Zum Inhalt

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>.username und .helper), oder
  • eine .netrc-Datei mit machine, login und password (Berechtigungen 600), 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.