Google CloudのサービスアカウントをTerraformで作る方法について
今回は、Google CloudのサービスアカウントをTerraformから作成する方法について調べてみました。最近K8sに加えてTerraformの学習もどんどん進めており、その勉強として今回はサービスアカウントを取り扱ってみます。
Google CloudでTerraformを試してみた系は以下のスクラップにまとめていますので合わせてご覧ください!
早速やってみる!
変数の作成
まずはGoogle CloudのプロジェクトIDやリージョンを設定するためにvariables.tf
を以下のように作成しました。
variable "project_id" {
description = "The Google Cloud project ID"
type = string
}
variable "region" {
description = "The Google Cloud region"
type = string
default = "us-central1"
}
variable "service_account_id" {
description = "Service account's id"
type = string
default = "my-service-account"
}
project_id
にはプロジェクトIDが保存され、実行時に指定するようにします。region
はとりあえず設定してますが、サービスアカウントの作成には不要です。service_account_id
にはサービスアカウントのIDを指定します。作成されるサービスアカウントのプリンシパルは<service_account_id>@<project_id>.iam.gserviceaccount.com
のような形式になります。
ストレージ管理者ロールを与える
まずはサービスアカウントにCloud Storageの管理者ロールを与えるためのファイルをmain.tf
に書いてみます。
provider "google" {
project = var.project_id
region = var.region
}
resource "google_service_account" "my_sa" {
account_id = var.service_account_id
display_name = "My Service Account"
}
resource "google_project_iam_member" "my_sa_roles" {
project = var.project_id
role = "roles/storage.admin"
member = "serviceAccount:${google_service_account.my_sa.email}"
}
まずgoogle_service_account
リソースによりサービスアカウントを作ります。リソース名はmy_sa
とし、アカウントIDはvar.service_account_id
を通してvariables.tf
で指定した内容を参照しています。
次にgoogle_project_iam_member
リソースによりサービスアカウントにロールを付与します。この例ではroles/storage.admin
を指定して、ストレージ管理者を付与しています。
それではこの設定でterraform plan
を実行してみましょう。実行結果は以下のようになります。ない硫黄的にはサービスアカウントとそれに対するロールの付与について記載されていますね。問題なさそうです。
`terraform plan`実行結果
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
create
Terraform will perform the following actions:
# google_project_iam_member.my_sa_roles will be created
+ resource "google_project_iam_member" "my_sa_roles" {
+ etag = (known after apply)
+ id = (known after apply)
+ member = "serviceAccount:my-service-account@project-id.iam.gserviceaccount.com"
+ project = "project-id"
+ role = "roles/storage.admin"
}
# google_service_account.my_sa[0m will be created
+ resource "google_service_account" "my_sa" {
+ account_id = "my-service-account"
+ disabled = false
+ display_name = "My Service Account"
+ email = "my-service-account@project-id.iam.gserviceaccount.com"
+ id = (known after apply)
+ member = "serviceAccount:my-service-account@project-id.iam.gserviceaccount.com"
+ name = (known after apply)
+ project = "project-id"
+ unique_id = (known after apply)
}
Plan: 2 to add, 0 to change, 0 to destroy.
─────────────────────────────────────────────────────────────────────────────[0m
Note: You didn't use the -out option to save this plan, so Terraform can't
guarantee to take exactly these actions if you run "terraform apply" now.
それでは実際にterraform apply
してみましょう。applyした結果、Google Cloudコンソール上で指定した名前でサービスアカウントが作成され、ストレージ管理者のロールが付与されていることを確認できました。
複数ロールの付与
例えばさきほどのストレージ管理者に加えてPubSubのパブリッシャーロール(roles/pubsub.publisher
)も加えてみましょう。この場合、二つのgoogle_project_iam_member
リソースを作ってもできますが、variables.tf
でリストとしてロールを持っておき、それをfor_eachで回す形で一つのリソース定義ないで対応してみようと思います。
まずはvariables.tf
に以下を追加します。この設定では、roles
という変数はデフォルトでroles/storage.admin
とroles/pubsub.publisher
の二つのロールの情報をリストとして持つことになります。
variable "roles" {
type = list(string)
default = ["roles/storage.admin", "roles/pubsub.publisher"]
}
次にmain.tf
のgoogle_project_iam_member
リソースを以下のように変更します。for_eact
でvar.roles
を指定し、role
にeach.value
を指定することで、var.roles
が保持しているリストの値それぞれをrole
に設定した場合のリソースを作成することができます。
resource "google_project_iam_member" "my_sa_roles" {
project = var.project_id
for_each = toset(var.roles)
role = each.value
member = "serviceAccount:${google_service_account.my_sa.email}"
}
それではこの変更に対してterraform plan
を実行してみます。結果を見ると、先ほど作成されたロールは一度削除され、新たに二つのロールをもったサービスアカウントとして作られるようです。
`terraform plan`実行結果
google_service_account.my_sa: Refreshing state... [id=projects/project_id/serviceAccounts/my-service-account@project_id.iam.gserviceaccount.com]
google_project_iam_member.my_sa_roles: Refreshing state... [id=project_id/roles/storage.admin/serviceAccount:my-service-account@project_id.iam.gserviceaccount.com][0m
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
create
destroy
Terraform will perform the following actions:
# google_project_iam_member.my_sa_roleswill be destroyed
# (because resource uses count or for_each)
- resource "google_project_iam_member" "my_sa_roles" {
- etag = "BwY+/wlu044=" -> null
- id = "project_id/roles/storage.admin/serviceAccount:my-service-account@project_id.iam.gserviceaccount.com" -> null
- member = "serviceAccount:my-service-account@project_id.iam.gserviceaccount.com" -> null
- project = "project_id" -> null
- role = "roles/storage.admin" -> null
}
# google_project_iam_member.my_sa_roles["roles/pubsub.publisher"] will be created
+ resource "google_project_iam_member" "my_sa_roles" {
+ etag = (known after apply)
+ id = (known after apply)
+ member = "serviceAccount:my-service-account@project_id.iam.gserviceaccount.com"
+ project = "project_id"
+ role = "roles/pubsub.publisher"
}
# google_project_iam_member.my_sa_roles["roles/storage.admin"] will be created
+ resource "google_project_iam_member" "my_sa_roles" {
+ etag = (known after apply)
+ id = (known after apply)
+ member = "serviceAccount:my-service-account@project_id.iam.gserviceaccount.com"
+ project = "project_id"
+ role = "roles/storage.admin"
}
Plan: 2 to add, 0 to change, 1 to destroy.
─────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't
guarantee to take exactly these actions if you run "terraform apply" now.
それでは実行してみます。terraform apply
を実行すると、以下のように追加したロールも付与されていることが確認できました。
最後にterraform destroy
でリソースは削除しておきます。
まとめ
今回はTerraformを利用してGoogle Cloud上でサービスアカウントを作成し、ロールを付与するところを試してみました。サービスアカウント期限などの設定もできるようなので、今後利用するときはより詳細まで確認できたらと思います。
Discussion