GitHub Actions から OIDC 認証で各クラウドを Terraform デプロイする – GCP 編

GCP
スポンサーリンク

今回は GitHub Actions から Terraform を実行し、GCP にリソースをデプロイします。OIDC 認証を用いることにより、GitHub Actions のワークフローや資格情報内にクレデンシャルを残す必要がないため、セキュリティを向上できます。必要に応じて適切な権限を付与できるので、最小権限を意識して不正なアクセスが発生した場合でも被害を抑えることができます。

公式ではこちらの手順が参考になります。

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_providerservice_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_filetrue にしていないとうまく認証が通りませんでした。

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"
}

コメント

タイトルとURLをコピーしました