diff --git a/.github/workflows/deployment.yaml b/.github/workflows/deployment.yaml index 623e75c..049612d 100644 --- a/.github/workflows/deployment.yaml +++ b/.github/workflows/deployment.yaml @@ -97,6 +97,18 @@ on: BUCKET_NAME: required: false + # secrets for shared image push + GCP_SERVICE_ACCOUNT_SHARED: + required: false + description: 'GCP service account email to impersonate via WIF (e.g. tf-deploy@my-project.iam.gserviceaccount.com).' + GCP_WORKLOAD_IDENTITY_PROVIDER_SHARED: + required: false + description: 'Full WIF provider resource name (e.g. projects/123/locations/global/workloadIdentityPools/github-actions-pool/providers/github-provider).' + GCP_PROJECT_SHARED: + required: false + GCP_REGISTRY_SHARED: + required: false + jobs: deploy: name: Build, Publish, and Deploy @@ -123,20 +135,29 @@ jobs: - name: Checkout code uses: actions/checkout@v3 - - name: Authenticate with GCP + # --- GCR push to shared account --- + + # NOTE: we push to the shared account first so that steps following + # this build/push (e.g. GKE deploy) use the normal gcloud credentials. + # all steps related to the shared account are allowed to fail so + # that existing workflows are not impacted. + - name: Authenticate with GCP Shared Account uses: google-github-actions/auth@v2 + continue-on-error: true with: - workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }} - service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }} + workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER_SHARED }} + service_account: ${{ secrets.GCP_SERVICE_ACCOUNT_SHARED }} - - name: Set up gcloud + - name: Set up gcloud for GCP Shared Account uses: google-github-actions/setup-gcloud@v2 + continue-on-error: true with: - project_id: ${{ secrets.GCP_PROJECT }} + project_id: ${{ secrets.GCP_PROJECT_SHARED }} - - name: Configure Docker to use the gcloud command-line tool as a credential helper + - name: Configure Docker to use the gcloud command-line tool as a credential helper for GCP Shared Registry + continue-on-error: true if: ${{ inputs.deploy_type != 'release-only' }} - run: gcloud auth configure-docker ${{ secrets.GCP_REGISTRY }} + run: gcloud auth configure-docker ${{ secrets.GCP_REGISTRY_SHARED }} # The env-file artifact (repo .env + GitHub secrets appended by the caller's # prepare-env job) is no longer baked into the image. It is downloaded to a @@ -165,6 +186,19 @@ jobs: build-args: | GH_ACCESS_TOKEN=${{ secrets.GH_ACCESS_TOKEN }} + # Retag the already-built standard image for the shared registry. + # A separate step (rather than an additional tag in the build step) keeps + # continue-on-error scoped to this step alone. + - name: Tag Docker image for GCP Shared Account + if: ${{ inputs.deploy_type != 'release-only' }} + continue-on-error: true + id: tag_shared + run: | + docker tag \ + ${{ secrets.GCP_REGISTRY }}/${{ secrets.GCP_PROJECT }}/${{ inputs.image_path }}:latest \ + ${{ secrets.GCP_REGISTRY_SHARED }}/${{ secrets.GCP_PROJECT_SHARED }}/${{ inputs.image_path }}:latest + + # only a single scan is required since both images are identical with different tags - name: Run Trivy vulnerability scanner on image if: ${{ inputs.deploy_type != 'release-only' }} uses: aquasecurity/trivy-action@0.35.0 @@ -176,6 +210,27 @@ jobs: severity: 'CRITICAL,HIGH' exit-code: '1' + - name: Push Docker image to GCP Shared Account + continue-on-error: true + if: ${{ inputs.deploy_type != 'release-only' }} + run: docker push ${{ secrets.GCP_REGISTRY_SHARED }}/${{ secrets.GCP_PROJECT_SHARED }}/${{ inputs.image_path }}:latest + + # --- GCR push to standard account --- + - name: Authenticate with GCP + uses: google-github-actions/auth@v2 + with: + workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }} + service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }} + + - name: Set up gcloud + uses: google-github-actions/setup-gcloud@v2 + with: + project_id: ${{ secrets.GCP_PROJECT }} + + - name: Configure Docker to use the gcloud command-line tool as a credential helper + if: ${{ inputs.deploy_type != 'release-only' }} + run: gcloud auth configure-docker ${{ secrets.GCP_REGISTRY }} + - name: Push Docker image if: ${{ inputs.deploy_type != 'release-only' }} run: docker push ${{ secrets.GCP_REGISTRY }}/${{ secrets.GCP_PROJECT }}/${{ inputs.image_path }}:latest