CircleCI から Google Cloud への OIDC を用いた認証
概要
今日紹介するのは、先日発表された CircleCI の OIDC 対応を用いた Google Cloud への認証方法に関する手法の調査についてです。
Goal
Google Cloud の Service Account ( 以下、 GSA ) へ Impersonate 出来る CircleCI の Project を制限しつつ、 GSA を利用した Google Cloud への認証を行うことを目的としています。
How to
早速、必要なリソースを作成していきます。
Workload Identity Pool / Provider を作成します
まずは、 Google Cloud に対して OIDC 経由での認証を行うためのサービスである Workload Identity Federation を利用するために Pool と Provider を作成します。
作成にあたって、 CircleCI の Organization ID を local.circleci_org
に設定します。
locals {
circleci_org = "****"
}
resource "google_iam_workload_identity_pool" "circleci" {
provider = google-beta
workload_identity_pool_id = "circleci"
display_name = "circleci"
}
resource "google_iam_workload_identity_pool_provider" "circleci" {
provider = google-beta
workload_identity_pool_id = google_iam_workload_identity_pool.circleci.workload_identity_pool_id
workload_identity_pool_provider_id = "circleci"
display_name = "circleci"
attribute_mapping = {
"attribute.project_id" = "assertion['oidc.circleci.com/project-id']" # CircleCI の Project を制限するためにマッピングを行います。
"google.subject" = "assertion.sub"
}
oidc {
issuer_uri = "https://oidc.circleci.com/org/${local.circleci_org}" # Issuer URL は CircleCI Organization ごとに発行されます。
allowed_audiences = [local.circleci_org]
}
}
GSA を作成します
GSA を作成し、 Impersonate 出来る member に先ほど作成した Workload Identity Pool と、マッピングした CircleCI Project ID を指定しています。
attribute.project_id/***
の部分で CircleCI Project を制限しています。
そして、 google_project_iam_member
で該当の GSA に対して必要な権限を付与します。
locals {
gsa_name = "***"
}
resource "google_service_account" "default" {
account_id = local.gsa_name
display_name = local.gsa_name
}
resource "google_service_account_iam_member" "default" {
for_each = toset([
"principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.circleci.name}/attribute.project_id/<CircleCI Project ID>",
])
service_account_id = google_service_account.default.id
role = "roles/iam.workloadIdentityUser"
member = each.value
}
resource "google_project_iam_member" "default" {
for_each = toset([
"roles/editor", # 操作したい権限を付与します
])
project = var.project
role = each.value
member = "serviceAccount:${google_service_account.default.email}"
}
CircleCI Context を作成する
CircleCI の Organization Settings → Contexts より Context を作成します。
CircleCI Config を編集する
CircleCI から GCP に OIDC 認証を行うステップをまとめた CircleCI Orb を作成していますので、そちらを利用していきます。
CircleCI の設定ファイル ( .circleci/config.yaml
) の orbs
に上記の Orb を設定します。また、 jobs.*.steps
に以下のステップを追加します。
step
の中で Orb の initialize
コマンドを呼び出し、 OIDC 認証に必要なパラメータを渡します。 initialize
コマンド内で gcloud CLI のインストールと GOOGLE_APPLICATION_CREDENTIALS
の設定を行なっています。そのため、 step
を実行後は gcloud コマンドを実行するだけで対象の GCP Project に対する操作を行うことが可能になります。
最後に、 .circleci/config.yaml
の workflows
において OIDC を利用したい job に Context を指定することで全ての設定が完了します。 Context を指定することで OIDC 認証に必要な CIRCLECI_TOKEN
環境変数が CI 上で利用出来るようになります。
At last
CircleCI の OIDC トークンを利用して Google Cloud への認証を行うためにのドキュメントや記事がまだなく、試行錯誤していたので少しでも同じ境遇の人の助けになればと思います。
また、この方法はベストプラクティスではないと思われるため、もっと簡単に出来るよ!などありましたらお気軽にコメントや Twitter でもご連絡お待ちしています。
個人的には Orbs を使ってよしなに認証したかったのですが、正常に動作させることが出来ず…
Others
本日紹介した CircleCI の OIDC 対応ですが、 AWS に対する利用方法は Classmethod さんで詳しい記事が紹介されているので是非ご覧ください。
Discussion