今回は GitHub Actions から Terraform を実行し、GCP にリソースをデプロイします。公式ではこちらの手順が参考になります。
Configuring OpenID Connect in Google Cloud Platform – GitHub Docs
GCP でのプロバイダーとサービス アカウントの作成
GCP で OIDC 認証を受け付けるプロバイダーと、GitHub Actions で利用する権限を割り当てたサービス アカウントを準備します。
API の有効化
準備に必要な API を有効化します。なお、こちらで移行の手順を実施するためには以下の権限が必要となります。
- roles/iam.workloadIdentityUser
- roles/iam.serviceAccountTokenCreator
PROJECT_ID="プロジェクト ID を指定します"
gcloud services enable iam.googleapis.com --project $PROJECT_ID
gcloud services enable cloudresourcemanager.googleapis.com --project $PROJECT_ID
gcloud services enable iamcredentials.googleapis.com --project $PROJECT_ID
gcloud services enable sts.googleapis.com --project $PROJECT_ID
Workload Identity の作成
認証要求を受け付け、外部 ID を識別するための Workload Identity を構成します。
# Workload Identity のプール名とプロバイダー名を指定します
POOL_NAME="github-actions-oidc"
PROVIDER_NAME="gha-oidc-provider"
#プールの作成
gcloud iam workload-identity-pools create $POOL_NAME \
--project="${PROJECT_ID}" --location="global" \
--display-name="Auth for GitHub Actions"
export WORKLOAD_IDENTITY_POOL_ID=$( \
gcloud iam workload-identity-pools describe "${POOL_NAME}" \
--project="${PROJECT_ID}" --location="global" \
--format="value(name)" \
)
# プロバイダーの作成
gcloud iam workload-identity-pools providers create-oidc "${PROVIDER_NAME}" \
--project="${PROJECT_ID}" --location="global" \
--workload-identity-pool="${POOL_NAME}" \
--display-name="Auth for GitHub Actions provider" \
--attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository,attribute.actor=assertion.actor,attribute.aud=assertion.aud" \
--issuer-uri="https://token.actions.githubusercontent.com"
サービス アカウントの作成
外部から認証したときに利用するサービス アカウントを作成します。適宜必要なロールを付与しておきます。principalSet
でアクセス元のリポジトリーを制限しています。
SERVICE_ACCOUNT_NAME="サービス アカウント名を指定"
GITHUB_REPO="アカウント名/リポジトリ名"
# サービス アカウント作成
gcloud iam service-accounts create "${SERVICE_ACCOUNT_NAME}" \
--project "${PROJECT_ID}"
--display-name="GitHub Actions OIDC"
# サービス アカウントにロールを付与 (適宜必要なものを指定)
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
--role="roles/owner" \
--member="serviceAccount:${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"
# Workload Identity からサービス アカウントを利用できるようにする
gcloud iam service-accounts add-iam-policy-binding "${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
--project="${PROJECT_ID}" \
--role="roles/iam.workloadIdentityUser" \
--member="principalSet://iam.googleapis.com/${WORKLOAD_IDENTITY_POOL_ID}/attribute.repository/${GITHUB_REPO}"
GitHub Actions ワークフロー
GCP に OIDC 認証するための手順を GitHub Actions ワークフローに組み込みます。
シークレットの作成
ワークフロー内で使う情報のため、次のシークレットを作成しておきます。
- GCP_PROVIDER: Workload Identity プロバイダーの ID (例:
projects/PROJECT_ID/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID
) - GCP_SERVICE_ACCOUNT: 作成したサービス アカウントのメールアドレス (例:
xxxx@project.iam.gserviceaccount.com
)
権限設定の追記
ワークフローから OIDC トークンのリクエストを行えるように権限の設定を追加します。次のような内容をワークフローに追記します。
permissions:
id-token: write
GCP アクセス トークンのリクエスト
GCP にアクセス トークンをリクエストするステップを追加します。workload_identity_provider
と service_account
で作成したシークレットを指定しています。
- id: 'auth'
name: Authenticate to GCP
uses: google-github-actions/auth@v0.4.0
with:
create_credentials_file: true
workload_identity_provider: ${{ secrets.GCP_PROVIDER }}
service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }}
ワークフロー ファイルの例
上述の内容を踏まえ、次のような内容になります。create_credentials_file
を true
にしていないとうまく認証が通りませんでした。
name: 'Terraform'
on:
push:
branches:
- main
pull_request:
jobs:
terraform:
name: 'Terraform'
runs-on: ubuntu-latest
environment: production
# 権限設定の追記
permissions:
id-token: write
defaults:
run:
shell: bash
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
with:
cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}
# GCP での認証を行うステップ
- id: 'auth'
name: Authenticate to GCP
uses: google-github-actions/auth@v0.4.0
with:
create_credentials_file: true
workload_identity_provider: ${{ secrets.GCP_PROVIDER }}
service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }}
- name: Terraform Init
run: terraform init
- name: Terraform Format
run: terraform fmt -check
- name: Terraform Plan
run: terraform plan
- name: Terraform Apply
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
run: terraform apply -auto-approve
Terraform プロバイダーの指定
あとは Terraform ファイルを用意して GCP リソースを作成します。作成するリソースに応じてロールに必要な権限は調整してください。プロバイダーの指定は次のようになります。
provider "google" {
project = "${var.gcp_project_id}"
region = "us-west1"
zone = "us-west1-a"
}
コメント