Zugriff auf Modulquellen bei GitHub Enterprise¶
Manches Terraform, das die Plattform ausführt (zum Beispiel die Spoke-Erweiterungen für GitHub), lädt seine Module aus Git-Repositories
auf einem GitHub-Enterprise-Host. Terraform muss sich an diesem Host authentifizieren, wenn es terraform init ausführt. Diese
Seite zeigt die Optionen, welche du verwenden solltest und wie du herausfindest, warum der Zugriff fehlschlägt.
Warum das nötig ist¶
Terraform erlaubt keine Variablen in der source eines Moduls. Die URL steht daher fest im Code, und die Zugangsdaten
müssen von außen kommen, aus Git. Eine Modulquelle sieht so aus (Platzhalter):
source = "git::https://<github host>/<organization>/<module repository>.git//src?ref=<version>"
Terraform ruft Git auf, um sie zu klonen. Hat Git keine Zugangsdaten für den Host, schlägt terraform init mit einem Authentifizierungsfehler oder
dem Fehler „repository not found“ fehl.
Eine Methode wählen¶
| Methode | Verwenden, wenn | Hinweise |
|---|---|---|
| HTTPS mit einem Git-Credential (empfohlen) | pipelines und Agents | Ein kurzlebiges Installations-Token der GitHub App in einem Git-Credential. Die Abschnitte unten zeigen, wie. |
| SSH | Du verwaltest bereits SSH-Keys auf den Agents | Ändere die Modulquelle auf die Form git::ssh://. Braucht einen Key, der die Repositories lesen darf und als Secret zum Agent hinzugefügt wird. |
| Lokaler Modulpfad | Die Module sind in dein eigenes Repository kopiert | Verwende in source einen relativen Pfad. Du bist dann dafür verantwortlich, die Kopie zu aktualisieren. |
| Eine andere Registry | Deine Organisation hat eine Modul-Registry | Die Quelle ändert sich entsprechend. |
Verwende für pipelines HTTPS mit einem Token. Tokens können kurzlebig und eng gefasst sein, und auf dem Agent muss nichts installiert werden.
HTTPS mit Git-Credentials¶
Das Token¶
Die Plattform-Workflows verwenden ein Installations-Token der GitHub App. Es wird im Workflow aus App-ID und Private Key erstellt (Spoke-Integrationen vorbereiten). Es läuft von selbst ab, ein geleaktes Token ist also nur begrenzt nützlich.
- Speichere die App-ID als Organisationsvariable und den Private Key als Organisations-Secret.
- Beschränke den Zugriff nur auf die Konfigurations-Repositories.
- Die App muss in der Organisation installiert sein, die die Module enthält, und diese Repositories lesen dürfen. Die Berechtigungen stehen unter Spoke-Integrationen vorbereiten.
GitHub Actions¶
Erstelle das Token und gib Git das Credential vor terraform init. Ein gekürzter Workflow:
- name: Create GitHub App token
id: app_token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ vars.cloud_platform_gh_app_id }}
private-key: ${{ secrets.cloud_platform_gh_app_private_key }}
owner: ${{ github.repository_owner }}
- name: Configure Git credentials
run: |
git config --global credential.helper store
echo "https://${{ steps.app_token.outputs.token }}@<github host>" > ~/.git-credentials
- name: Terraform init
run: terraform init
env:
TF_VAR_github_token: ${{ steps.app_token.outputs.token }}
Azure DevOps¶
Halte das Token in einer Variable Group oder einem pipeline-Secret und schreibe das Credential in einem Skript-Schritt vor
terraform init:
steps:
- script: |
git config --global credential.helper store
echo "https://$(GITHUB_TOKEN)@<github host>" > ~/.git-credentials
displayName: Configure Git credentials
- script: terraform init
displayName: Terraform init
env:
TF_VAR_github_token: $(GITHUB_TOKEN)
Lass keine Tokens auf gemeinsam genutzten Agents liegen
Die Datei ~/.git-credentials enthält das Token im Klartext. Entferne die Datei auf selbst gehosteten Agents, die wiederverwendet werden,
am Ende des Jobs, oder verwende einen ephemeren Agent. Ein Token, das länger als der Job auf einem Agent gespeichert bleibt, ist ein
Leak, der nur darauf wartet, zu passieren.
Andere Wege, Git ein Credential zu geben¶
Für eine Person, die auf einer Workstation testet, lässt sich dasselbe Ergebnis mit Git-Konfiguration erreichen:
- ein Credential Helper, der für den Host konfiguriert ist (
credential.<url>.usernameund.helper), oder - eine
.netrc-Datei mitmachine,loginundpassword(Berechtigungen600), oder - Umgebungsvariablen, die dein eigenes Credential-Skript liest.
Verwende diese nicht auf gemeinsam genutzten Build-Agents.
SSH¶
Ändere die Quelle auf die SSH-Form:
source = "git::ssh://git@<github host>/<organization>/<module repository>.git//src?ref=<version>"
Erstelle ein Schlüsselpaar, füge den Public Key zu einem Account (oder als Deploy Key) hinzu, der die Repositories lesen kann, und füge den Private Key der pipeline als Secret hinzu. Sorge dafür, dass der Agent dem Host vertraut. In GitHub Actions kann eine SSH-Agent-Action den Key laden.
Lokale Kopien¶
Kopiere die Module in das Repository und verweise per relativem Pfad auf sie:
source = "../../../modules/<module name>/src"
Nutze das, wenn der Host gar nicht erreichbar ist. Nimm die Aktualisierung der Kopie in dein Upgrade-Verfahren auf (Neue Version).
Testen und Fehler beheben¶
Teste zuerst mit Git, dann mit Terraform:
git ls-remote https://<github host>/<organization>/<module repository>.git
terraform init -backend=false
| Symptom | Prüfen |
|---|---|
| Authentifizierung fehlgeschlagen | Die App ist in der Organisation installiert und hat die richtigen Berechtigungen. Das Token ist nicht abgelaufen. Das Credential ist für den richtigen Hostnamen geschrieben. |
| Repository nicht gefunden | Das Repository existiert auf dem Enterprise-Host. Die App darf es lesen. Eine fehlende Berechtigung kann als „not found“ erscheinen. |
| Netzwerkfehler oder Timeout | Der Agent kann den Host erreichen (Firewallregeln, Proxy). Siehe Netzwerkzugriff der Agents. |
init funktioniert lokal, aber nicht in der pipeline |
Der Credential-Schritt läuft vor terraform init, im selben Job und Benutzerkontext. |