TerraformでサービスアカウントになりすましてGoogleグループを操作する

2023/12/15に公開

この記事は、AEON Advent Calendar 2023の15日目です。

イオンネクストのIT部 ReliabilityグループでSREをやっております@arairyusです。
11月に入社したばかりで、以前はフリーランスをやってました。
すっかりアドベントカレンダーのこと忘れていたため、今GCPのガバナンス整備をしているので、そこでどハマリした内容書きます。

実現したかったこと

  • GCPに関連するすべてをIaCで管理する

Googleアカウント・グループとは

上図はあくまで私の理解です。イオンネクストではCloud Identityを使っています。IdPはEntra ID(Azure AD)を使っています。

AWS GCP
ヒト IAMユーザー Googleアカウント
グループ IAMグループ Googleグループ

このように他クラウドと同様にユーザー・グループの概念があるのですが、GCPではGCP内のリソースではありません。Cloud IdentityやGoogle Workspace上のリソースです。
Googleアカウント・グループに対して、GCP内でIAMロールを付与します。

とりあえず、Googleアカウント・グループはGCP外で管理されているリソースです。

サービスアカウントとは

https://cloud.google.com/iam/docs/service-account-overview?hl=ja

ユーザーではない、リソースなどにアタッチするIAMリソースです(超ざっくり)。
AWSでいうIAMロール、Azureでいうサービスプリンシパル、マネージドIDのようなものと認識してます。

サービスアカウントになりすますってどういうこと?

ユーザー(Googleアカウント)がサービスアカウントから権限を借用して、サービスアカウントとしてリソースの操作をすることです。
AWSのAssumeRoleと同じようなこととイメージいただければと思います。

Terraformでサービスアカウントになりすまして実行する方法

  • Terraform用サービスアカウントへのアクセストークン作成権限がGoogleアカウントに紐づいていること
locals {
  admin_project_id            = "Terraform実行プロジェクトID"
  impersonate_service_account = "Terraform用サービスアカウント"
}

# このプロバイダーはGoogleアカウントを使用
provider "google" {
  alias = "impersonation"
  scopes = [
    "https://www.googleapis.com/auth/cloud-platform",
    "https://www.googleapis.com/auth/userinfo.email",
  ]
}

# サービスアカウントのアクセストークンを取得する
data "google_service_account_access_token" "default" {
  provider               = google.impersonation
  target_service_account = local.impersonate_service_account
  scopes                 = ["userinfo-email", "cloud-platform"]
  lifetime               = "1200s"
}

# サービスアカウントになりすまして実行するプロバイダー
provider "google" {
  project         = local.admin_project_id
  region          = "asia-northeast1"
  access_token    = data.google_service_account_access_token.default.access_token
  request_timeout = "60s"
}

# サービスアカウントになりすまして実行するプロバイダー
provider "google-beta" {
  project         = local.admin_project_id
  region          = "asia-northeast1"
  access_token    = data.google_service_account_access_token.default.access_token
  request_timeout = "60s"
}
terraform {
  required_version = ">=1.6.5"

  required_providers {
    google = {
      source  = "hashicorp/google"
      version = ">= x.y.z"
    }
    google-beta = {
      source  = "hashicorp/google-beta"
      version = ">= x.y.z"
    }
  }

  backend "gcs" {
    bucket                      = "Terraform State用GCS"
    prefix                      = "example"
    impersonate_service_account = "Terraform用サービスアカウント" # gcsにアクセスするときに使うなりすますサービスアカウント
  }
}

なりすますサービスアカウントの定義は環境変数でもOKです。

export GOOGLE_IMPERSONATE_SERVICE_ACCOUNT=サービスアカウント

サービスアカウントになりすましてGoogleグループを編集する方法

  • サービスアカウントはGCPのIAMリソース
  • GoogleグループはGCPの外に存在するリソース

デフォルトではサービスアカウントを使って、Googleグループ・アカウントの操作をすることができません(私調べ)

どうすればよいか

Googleグループを変更できるいいかんじの管理者ロールを作成して、サービスアカウントへ割当をして、サービスアカウントでGoogleグループを変更できるようにします。

admin.google.comにアクセスして[アカウント]-[管理者ロール]をクリックして、

試した感じ、ここらへんの権限あればいけました。

Terraformのコードはこんな感じです。
※私は積極的にterraform registryのmodule使ったほうがいいと思う派です。

module "group" {
  source  = "terraform-google-modules/group/google"
  version = "~> 0.6"

  id           = "example-group@${var.corp_domain}"
  display_name = "example-group"
  customer_id  = data.google_organization.org.directory_customer_id
  description  = "Example group"
  managers     = [google_service_account.example.email]
  types = [
    "default",
    "security",
  ]
}
module.group.google_cloud_identity_group.group: Modifying... [id=groups/xxxxxx]
module.group.google_cloud_identity_group.group: Modifications complete after 9s [id=groups/xxxxxx]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

無事、サービスアカウントになりすましてGoogleグループを操作できました。
これでIaCでサクッとGCPフォルダごとにGoogleグループ払い出して、権限付与して後はセルフサービスでどうぞと渡せる下準備ができました!

宣伝: イオンネクストについて

https://greenbeans.com/

英国Ocado社のソリューションなど最新技術を活用したイオンのオンラインマーケット「Green Beans」を運営しています。

image
配送エリアにお住まいの方はこの配送車を見かけたことあるかもしれませんね。

採用募集中です!!

https://hrmos.co/pages/aeonnexthr

エンジニア的に気になるところでいうと

  • PC: 貸与PCはWindows(開発用にMac使っている方も多いです)
  • コミュニケーションツール: Teams/Slack
  • ドキュメントツール: Notion
  • チケット管理: Jira
  • コード管理: GitHub
  • CICD: GitHub Actions
  • クラウド: AWS/Azure/GCP
  • IaC: Terraform
  • 言語: C#/PHP/Go

出社回数は?
(現時点では)IT部では、週2で出社推奨日を設けています。水曜: 幕張、金曜: 八丁堀
推奨日なので出社しなくてもどうこう言われません(?)。ちなみに私は今のところ週1出社してます。

参考サイト

AEON TECH HUB

Discussion