Closed5

Github Actions から特定のサービスアカウントを用いて Artifact Registry にイメージを push しようとしてもできなかった際の対応

yuyake0084yuyake0084

原因

https://zenn.dev/link/comments/7ffa9a5b52533a

Github Actions の 流れ

- name: Set up Cloud SDK
   uses: google-github-actions/setup-gcloud@v0

- name: Authenticate to Google Cloud
   id: "auth"
   uses: "google-github-actions/auth@v1"
   with:
     workload_identity_provider: "${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER_NAME }}"
     service_account: "${{ secrets.GCP_SERVICE_ACCOUNT_ID }}@${{ secrets.GCP_PROJECT_ID }}.iam.gserviceaccount.com"

- name: Authorize Docker push
  run: gcloud auth configure-docker ${{ secrets.GCP_REGION }}-docker.pkg.dev

- name: Set IMAGE_REPOSITORY
  run: |
    echo "IMAGE_REPOSITORY=${{ secrets.GCP_REGION }}-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/${{ secrets.GCP_CLOUD_RUN_SERVICE_NAME }}/result" >> $GITHUB_ENV
      
- name: Build Image
  run: |-
    docker build \
      -t ${{ env.IMAGE_REPOSITORY }}:${{ github.sha }} \
      -t ${{ env.IMAGE_REPOSITORY }}:latest \
      --build-arg NODE_ENV=${{ env.NODE_ENV }} \
    ./

エラー

要約すると サービスアカウントに iam.serviceAccounts.getAccessToken の権限が付与されてないから動かせないよと言う内容

ERROR: (gcloud.auth.docker-helper) There was a problem refreshing your current auth tokens: ('Unable to acquire impersonated credentials', '{\n  "error": {\n    "code": 403,\n    "message": "Permission \'iam.serviceAccounts.getAccessToken\' denied on resource (or it may not exist).",\n    "status": "PERMISSION_DENIED",\n    "details": [\n      {\n        "@type": "type.googleapis.com/google.rpc.ErrorInfo",\n        "reason": "IAM_PERMISSION_DENIED",\n        "domain": "iam.googleapis.com",\n        "metadata": {\n          "permission": "iam.serviceAccounts.getAccessToken"\n        }\n      }\n    ]\n  }\n}\n')

Please run:

  $ gcloud auth login

to obtain new credentials.

If you have already logged in with a different account, run:

  $ gcloud config set account ACCOUNT

前提

  • 別リポジトリの Github Actions では全く同じ流れで push までできている
  • サービスアカウントには以下の権限は付与済み
    • roles/run.admin
    • roles/artifactregistry.writer
yuyake0084yuyake0084

仮説1. ローカルで当該サービスアカウントをアクティベートして、Actions と同じことをやった時に push できるか?

事前にGCPのコンソールから当該サービスアカウントのキーをJSONで作成し、ローカルに保存しておく。

$ gcloud auth activate-service-account ${ACCOUNT_ID}@${PROJECT_ID}.iam.gserviceaccount.com --key-file <JSONまでのパス>
$ gcloud auth configure-docker ${REGION}-docker.pkg.dev
$ docker build \
    -t ${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/result:latest \
    --build-arg NODE_ENV=development \
  ./
$ docker push ${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/result:latest

...できてしまった。

yuyake0084yuyake0084

仮説2. 環境変数に渡す値が間違えているのでは?

登録後再度 Action を回してもダメでした。

yuyake0084yuyake0084

仮説3. そもそも認証ができてないのでは?

Please run:

  $ gcloud auth login

エラーを見れば「それはそう」という話なのだが、認証が通ってない状態で push しようとしてもできないは極々当たり前だし、仮説1でローカルから push はできてるのでこの辺りを疑って見てみる。(もちろん自分自身では期待通りの値を渡せている認識だがそれが誤っているかもしれない)

- name: Authenticate to Google Cloud
   id: "auth"
   uses: "google-github-actions/auth@v1"
   with:
     workload_identity_provider: "${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER_NAME }}"
     service_account: "${{ secrets.GCP_SERVICE_ACCOUNT_ID }}@${{ secrets.GCP_PROJECT_ID }}.iam.gserviceaccount.com"
yuyake0084yuyake0084

解決

結論。
terraform 側で roles/iam.workloadIdentityUser の role を渡す member を間違えていた。。
module の呼び出しをコピペで実施していた為、 var.repo_name が別のリポジトリを向いていたのがよくなかった。
コピペしてきたら全てのパラメータをまっさらにして最初からちゃんと入力しましょう(自戒)

resource "google_service_account_iam_member" "github_actions" {
  service_account_id = google_service_account.github_actions.name
  role               = "roles/iam.workloadIdentityUser"
  member             = "principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.github_actions_pool.name}/attribute.repository/${var.repo_name}"
}
このスクラップは2023/07/17にクローズされました