概要 #
権限をコンソールで手動付与していると、誰にどのRoleを与えたのか把握しづらくなります。付与漏れや、逆に権限を与えすぎたままでも、見た目だけでは気づくことができません。
Terraformで管理すれば、Service AccountとIAM RoleをコードとしてReviewでき、差分もそのまま履歴に残ります。ここではService Accountを作成し、Projectにroles/storage.objectViewerを付与します。長期CredentialになるService Account Key JSONは作成しません。
Terraformの基本操作は前提としています。IAMの基礎(Role、Member)は説明しません。
検証すること #
- Service Accountを作成する
google_project_iam_memberでRoleを加算的に付与する- Service AccountとIAM Policyを
gcloudで確認する - destroyで今回追加したMemberだけを削除する
前提環境 #
- Google Cloud CLIとApplication Default Credentials(ADC)
- Terraform 1.5以降
- IAMを変更できる検証用Google Cloud Project
- IAM Memberとして指定するGoogleアカウント
- 検証時のバージョン:Terraform 1.14.3、google 7.43.0
今回の構成 #
Service AccountとRoleの紐付けは、Project単位のIAM Policyとして保持されます。
flowchart TB
subgraph GCP["Google Cloud"]
subgraph Project["Project"]
SA["Service Account
tf-example-sa@...iam.gserviceaccount.com"]
subgraph Policy["Project の IAM Policy"]
Binding["member: 上記のSA
role: roles/storage.objectViewer"]
end
end
end
SA -.->|"memberとして参照"| Binding
google_project_iam_memberは、既存のPolicyへ1件だけ追加します。google_project_iam_policyはPolicy全体を置き換えるため、他の設定を消してしまいます。用途が違う点に注意が要ります。
使用するTerraformコード #
必要な権限 #
- Service Account Admin相当
- Project IAM Admin相当
- Service Usageを操作できる権限
IAM Policyの変更は影響が大きいため、検証用Projectで実施します。
今回重要なTerraformコード #
Service Accountを作成します。
resource "google_service_account" "example" {
account_id = var.service_account_id
display_name = var.service_account_display_name
description = "Sample service account for terraform-gcp-examples/05-iam."
depends_on = [google_project_service.iam]
}
作成したService AccountへProject Roleを付与します。
resource "google_project_iam_member" "example" {
project = var.project_id
role = var.project_iam_role
member = "serviceAccount:${google_service_account.example.email}"
}
デフォルトRoleはObjectの読み取りに使うroles/storage.objectViewerです。
google_project_iam_memberは、指定したRoleへ1つのMemberを追加する加算型Resourceです。同じRoleに設定済みの他Memberをまとめて管理・置換するgoogle_project_iam_bindingとは管理範囲が異なります。
既存IAMを意図せず削除しにくいため、1つのMemberだけを追加する今回のサンプルではmemberを使用します。
Service Account Keyを作らない理由 #
Service Account Key JSONはダウンロード後にGoogle Cloud外へ持ち出せる長期Credentialです。漏えいするとKeyを無効化するまで悪用される可能性があります。
Google Cloud上のWorkloadではService Accountの直接割り当て、外部CI/CDではWorkload Identity Federationなど、Keyを保存しない方式を優先します。
設定と実行 #
cd Basic-Examples/05-iam
cp terraform.tfvars.example terraform.tfvars
project_id = "your-project-id"
region = "asia-northeast1"
必要に応じてService Account IDやRoleを上書きします。
service_account_id = "tf-example-sa"
service_account_display_name = "TF Example Service Account"
project_iam_role = "roles/storage.objectViewer"
terraform init
terraform fmt -check
terraform validate
terraform plan
terraform apply
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
Outputs:
service_account_email = "tf-example-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com"
service_account_id = "projects/YOUR_PROJECT_ID/serviceAccounts/tf-example-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com"
GCP側で確認する #
gcloud iam service-accounts describe \
"$(terraform output -raw service_account_email)" \
--project=YOUR_PROJECT_ID
Roleを確認します。
gcloud projects get-iam-policy YOUR_PROJECT_ID \
--flatten="bindings[].members" \
--filter="bindings.members:$(terraform output -raw service_account_email)" \
--format="table(bindings.role)"
roles/storage.objectViewerが表示されれば完了です。
後片付けと注意点 #
terraform destroy
今回追加したIAM MemberとService Accountが削除されます。Service Accountを他のResourceから利用し始めた後に削除すると影響が出るため、依存関係を確認します。
Service AccountやIAM設定自体には通常追加料金は発生しません。権限は目的に必要な範囲へ限定し、OwnerやEditorなどの広いRoleを安易に付与しないことが重要です。
まとめ #
- Workload用Service AccountをTerraformで作成できる
google_project_iam_memberで1つのMemberを加算的に管理できる- 最小権限のRoleから始める
- Service Account Keyを作らない認証方式を優先する
参考資料 #
- Terraform: google_service_account
- Terraform: google_project_iam
- Google Cloud: Service Accountのベストプラクティス
次回 #
次はTerraformでCloud Run v2サービスをデプロイし、HTTP応答を確認します。