👍

Github ActionsからGCPにterraform applyしたいと思ったときに最初に実行するスクリプトを作った

2024/03/01に公開

これは何?

趣味で作っているプロジェクトで、Github ActionsからTerraform applyしたくなりました。
一度準備してしまえばいろんなリソースをTerraformで管理できて楽になるのですが、それまでにGCP上に作っておかないといけないリソースが色々あります。

  • Github ActionsからGCPリソースを操作するためのWorkload Identity
  • Workload Identityに紐づけるサービスアカウント
  • tfstateをおいておくためのGCSバケット

などなど...

これらは手作業で作ってもいいのですが、ボンッと一発で作ってしまうスクリプトがあれば、別環境や別プロジェクトの構築の手間が省けるかなぁと思って作ってみました。

想定読者

  • Github ActionsからGCPterraform applyしたい人
  • ↑のための準備を手作業でやるのは面倒くさいと思っている人

作ってみる

#!/bin/sh

source .env

# サービスアカウント作成
gcloud iam service-accounts create $SERVICE_ACCOUNT_NAME

# サービスアカウントに権限を付与
# ロールは適切なものに修正してください
gcloud projects add-iam-policy-binding $PROJECT_ID \
	--member="serviceAccount:${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
	--role='roles/owner'

# Workload Identity Poolを作成
gcloud iam workload-identity-pools create $IDENTITY_POOL_NAME \
    --location="${IDENTITY_POOL_LOCATION}"

# Workload Identity Providerを作成
gcloud iam workload-identity-pools providers create-oidc $IDENTITY_PROVIDER_NAME \
    --location="${IDENTITY_POOL_LOCATION}" \
    --workload-identity-pool="${IDENTITY_POOL_NAME}" \
    --attribute-mapping="attribute.repository=assertion.repository,google.subject=assertion.sub" \
    # 指定したリポジトリからのみアクセスできる設定
    --attribute-condition="'${GITHUB_REPOSITORY}' == attribute.repository" \
    --issuer-uri="https://token.actions.githubusercontent.com"

# Workload Identity Providerにサービスアカウントを接続
gcloud iam service-accounts add-iam-policy-binding "${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
	--member="principalSet://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/${IDENTITY_POOL_LOCATION}/workloadIdentityPools/${IDENTITY_POOL_NAME}/*" \
	--role='roles/iam.workloadIdentityUser'

# Terraform用のGCSバケットを作成
gcloud alpha storage buckets create \
	--location="${GCS_LOCATION}" \
	--public-access-prevention \
	gs://${GCS_BUCKET_NAME}

echo "workload identity provider: projects/$PROJECT_NUMBER/locations/$IDENTITY_POOL_LOCATION/workloadIdentityPools/$IDENTITY_POOL_NAME/$IDENTITY_PROVIDER_NAME"
echo "service account:${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"
echo "gcs bucket name:$GCS_BUCKET_NAME"

使ってみる

事前にgcloud CLIのセットアップを済ませます。
認証は各種リソースの作成に必要なロールを持ったアカウントで行ってください。(私は管理者権限を持ったアカウントで行いました)

その後、こんな.envファイルをスクリプトファイルと同階層に用意します。

# GCPプロジェクトID
PROJECT_ID=<あなたのGCPプロジェクトのID>
# GCPプロジェクト番号
PROJECT_NUMBER=<あなたのGCPプロジェクトの番号>
# worklaod identity poolを配置するロケーション(例: global)
IDENTITY_POOL_LOCATION=<あなたがworkload identity poolを配置したいロケーション>
# workload identity pool名
IDENTITY_POOL_NAME=<好きな値>
# workload identity provider名
IDENTITY_PROVIDER_NAME=<好きな値>
# workload identity poolに接続するサービスアカウント名
SERVICE_ACCOUNT_NAME=<好きな値>
# terraformファイルを配置するGithubリポジトリ名
GITHUB_REPOSITORY=<あなたのGithubリポジトリ名>
# 環境のtfstateを置くバケットのロケーション(例: asia-northeast1)
GCS_LOCATION=<あなたがGCSバケットを配置したいロケーション>
# tfstateを置くバケット名
GCS_BUCKET_NAME=<好きな値>

この状態でスクリプトを実行すると、下記のリソースがGCPにボンッと生まれます。

  • Github ActionsからGCPリソースを操作するためのWorkload Identity
  • Workload Identityに紐づけるサービスアカウント
  • tfstateをおいておくためのGCSバケット

スクリプトの実行ログの末尾に表示されるこの子たちは、Github Actions用のsecretsに設定しましょう。

...
workload identity provider: ***
service account: ***
gcs bucket name:***

Github Actionsでこんな感じでGCPに認証すると、ジョブからGCPのリソースを参照・操作できるようになります。

    - name: Authenticate to Google Cloud
      uses: "google-github-actions/auth@v0"
      with:
        workload_identity_provider: ${{ secrets.<workload identity providerのsecret名> }}
        service_account: ${{secrets.<service accountのsecret名> }}

まとめ

Github ActionsからGCPterraform applyしたいときに最初に実行するスクリプトを作りました。

今回のスクリプトの実行によって、

  • Github ActionsからGCPリソースを操作するためのWorkload Identity
  • Workload Identityに紐づけるサービスアカウント
  • GCSバケット

が一気に作られ、すぐに開発を始められるようになります。

なお、実行は内容をよく確認の上、自己責任にてお願い致します。

Discussion