Hey team, I'm trying to set up CI/CD using GitHub...
# getting-started
q
Hey team, I'm trying to set up CI/CD using GitHub Actions. But I wanted to use google's best practices with OIDC by having my workload identity pool and provider on one project, and my service account which uses them in the project I want my stack to get deployed to. Now I know I've got OIDC set up right for my "Admin GCP Project" because my release workflow works fine and can display values I have in my ESC environment:
Copy code
- name: Fetch short lived Pulumi access token
        id: auth
        uses: pulumi/auth-actions@v1
        with:
          organization: ${{ inputs.organisation }}
          requested-token-type: urn:pulumi:token-type:access_token:organization

      - uses: pulumi/esc-action@v1
        with:
          environment: ${{ inputs.project }}/${{ inputs.stack }}
But when I try with:
Copy code
- name: Fetch short‑lived Pulumi access token
      uses: pulumi/auth-actions@v1
      with:
        organization: ${{ inputs.organisation }}
        requested-token-type: urn:pulumi:token-type:access_token:organization

    - name: Install and inject ESC environment variables
      uses: pulumi/esc-action@v1
      with:
        environment: ${{ inputs.project }}/${{ inputs.stack }}

    - name: pulumi preview
      uses: pulumi/actions@v6
      with:
        command: preview
        stack-name: ${{ inputs.organisation }}/${{ inputs.project }}/${{ inputs.stack }}
        upsert: true
        refresh: true
        work-dir: infra
💀 I'm getting the following error:
Copy code
error: getting stack configuration: opening environment: [0] 
  Diags: impersonating service account: could not authenticate with GCP.
  
  Please ensure that your trust relationship is correct.
  Subject: "pulumi:environments:org:myPulumiOrg:env:<yaml>"
  Audience: "gcp:myPulumiOrg"
  
  If this environment has been cloned from one in the "default" project the trust relationship has changed from
  Subject: "pulumi:environments:org:myPulumiOrg:env:<yaml>"
  Audience: "myPulumiOrg"
  
  generating impersonation token: status code 403: {
    "error": {
      "code": 403,
      "message": "Permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist).",
      "status": "PERMISSION_DENIED",
      "details": [
        {
          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
          "reason": "IAM_PERMISSION_DENIED",
          "domain": "iam.googleapis.com",
          "metadata": {
            "permission": "iam.serviceAccounts.getAccessToken"
          }
        }
      ]
    }
  }
For my esc env the key part is:
Copy code
gcp:
    login:
      fn::open::gcp-login:
        project: 123456789101
        oidc:
          workloadPoolId: pulumi-esc-pool
          providerId: pulumi-esc-provider
          serviceAccount: pulumi-esc-sa@admin.iam.gserviceaccount.com
The reason the esc github action works is because I've got a service account in my gcp admin project which has the right principle to connect by OIDC:
Copy code
{
  "bindings": [
    {
      "members": [
        "<principal://iam.googleapis.com/projects/123456789101/locations/global/workloadIdentityPools/pulumi-esc-pool/subject/pulumi:environments:org:myPulumiOrg:env:targetPulumiProject/dev>",
        "serviceAccount:pulumi-esc-sa@targetGCPProject.iam.gserviceaccount.com"
      ],
      "role": "roles/iam.serviceAccountTokenCreator"
    },
    {
      "members": [
        "<principal://iam.googleapis.com/projects/123456789101/locations/global/workloadIdentityPools/pulumi-esc-pool/subject/pulumi:environments:org:myPulumiOrg:env:targetPulumiProject/dev>"
      ],
      "role": "roles/iam.workloadIdentityUser"
    }
  ],
  "etag": "BwY1PwAeEAZ=",
  "version": 1
}
(This line was my naive attempt to get project access token permissions for the desired GCP project but it hasn't worked):
Copy code
"serviceAccount:pulumi-esc-sa@targetGCPProject.iam.gserviceaccount.com"
But what am I missing to get the access-token/GOOGLE_APPLICATION_CREDENTIALS or relevant "get access token" permissions into my pulumi action step? 🤔
And I know, you're going to probably say just use this in the step before the pulumi action:
Copy code
- name: Authenticate with Google 🔑
        uses: google-github-actions/setup-gcloud@v0
        with:
          service_account_key: ${{ secrets.GCP_KEY }}
          project_id: ${{ env.PROJECT_ID }}
          export_default_credentials: true
Which is my fallback, but I wondered if there was a more elegant approach given the ESC step before? Does the ESC action not pass in a short lived access token to subsequent steps that I just need to set the right permissions on for it to work?
think I figured it out, using principleSet for my gcloud iam workloadIdentityUser and serviceAccountTokenCreator member fields caused issues, should have set it to just principle like so:
Copy code
PULUMI_MEMBER="<principal://iam.googleapis.com/projects/${ADMIN_PROJECT_NUMBER}/locations/global/workloadIdentityPools/${POOL_ID}/subject/${PULUMI_SUBJECT}>"
Weird little oversight 🤷‍♂️