サービスアカウントキーを利用せずに Terraform を実行する方法
Google Cloud のリソース構築に Terraform を利用していますが、セキュリティの観点からサービスアカウントキーを発行したくないという方も多いのではないでしょうか。今回は有効期限の短いアクセストークンを利用してサービスアカウントの権限を借用することで、サービスアカウントキーを利用せずに Terraform を実行する方法を解説します。
今回の記事は下記の Google Cloud ブログを参考にしています。ブログ投稿だと行間が分かりにくい部分があるので、行間を補足するイメージ記載しています。
また、この方法はローカル環境から Terraform を実行することを想定しています。CI/CD で Terraform を実行するような場合には、Workload Identity 連携の利用を推奨します。Workload Identity 連携を利用した方法もいずれまとめたいと思います。
概要
サービスアカウントキーを利用しないとはどんな方法か?端的に説明すると有効期限の短いアクセストークンを発行し、サービスアカウントの権限借用を行う方法です。と言われてもパッとイメージするのは難しいと思いますので、Terraform で BigQuery のデータセットを作成するケースを例にポンチ絵にするとこんな感じです。
詳細は各手順の中で解説するので、ここでは大まかなイメージを掴んでください。
- Google アカウントの認証情報をリクエスト
- Google アカウントの認証情報を取得、アプリケーションのデフォルト認証情報(ADC)として設定
- ADC を利用してサービスアカウントの有効期限の短いアクセストークンをリクエスト
- 有効期限の短いアクセストークンを取得
- 有効期限の短いアクセストークンを利用してサービスアカウントの権限で BigQuery データセットを作成
設定の流れ
Terraform を実行できるようになるまでの流れは以下の通りです。
- サービスアカウントを作成
- Google アカウントに必要な権限を付与
- サービスアカウントに必要な権限を付与
- アプリケーションのデフォルト認証情報 (ADC) に Google アカウントの認証情報を設定
- Terraform コードの作成
前半の 1 ~ 3 は Google Cloud プロジェクト上での作業、4 ~ 5 はローカル環境側の作業です。
また、以下は完了している前提としています。
- Google Cloud プロジェクトの作成
- Google アカウントへ 1 ~ 3 の操作を行うための権限付与
- ローカル環境で gcloud コマンドが実行できる状態
- ローカル環境で Terraform が実行できる状態
1. サービスアカウントを作成
まずは Terraform を実行するためのサービスアカウントを作成します。
名前は任意ですが、Terraform の実行用途と分かりやすい名前が良いかもしれません。
gcloud iam service-accounts create terraform --display-name="Terraform service account"
2. Google アカウントに必要な権限を付与
自身の Google アカウントに必要な権限を付与します。
アクセストークンを発行し、サービスアカウントの権限借用を行うために必要最小限のロールは Service Account Token Creator (roles/iam.serviceAccountTokenCreator) です。今回は簡易的に gcloud iam service-accounts add-iam-policy-binding
コマンドを利用してロールを付与しますが、IAM を Terraform で管理しているケースも多いかと思いますので、権限付与の方法は適宜変更して下さい。
terraform@[myprojectid].iam.gserviceaccount.com
部分は前の手順で作成したサービスアカウントの情報に、user:[mygoogleaccount]
部分は自身の Google アカウントのアドレス、もしくは Google グループのアドレスに読み替えてください。
gcloud iam service-accounts add-iam-policy-binding terraform@[myprojectid].iam.gserviceaccount.com --member='user:[mygoogleaccount]' --role='roles/iam.serviceAccountTokenCreator'
プロジェクトレベルで Google アカウントに Service Account Token Creator ロールを付与することも可能ですが、他のサービスアカウントに対してもトークン作成の権限が付与されることになり、過剰な権限付与となってしまう可能性があるため、サービスアカウント単位で個別に権限付与することを推奨します。
3. サービスアカウントに必要な権限を付与
サービスアカウントに Terraform でリソース構築するために必要な権限を付与します。
今回は BigQuery のデータセットを作成するので、BigQuery Data Editor (roles/bigquery.dataEditor) ロールを付与します。今回は簡易的に gcloud projects add-iam-policy-binding
コマンドを利用してロールを付与しますが、IAM を Terraform で管理しているケースも多いかと思いますので、権限付与の方法は適宜変更して下さい。
gcloud projects add-iam-policy-binding [myprojectid] --member='serviceAccount:terraform@[myprojectid].iam.gserviceaccount.com' --role='roles/bigquery.dataEditor'
4. アプリケーションのデフォルト認証情報 (ADC) に Google アカウントの認証情報を設定
アプリケーションのデフォルト認証情報(ADC)は、Cloud クライアントライブラリ等が Google Cloud APIs の認証に利用する認証情報のことであり、Terraform の実行においても ADC を利用した認証が推奨されています。
今回のケースでは ADC をサービスアカウントのアクセストークンを取得するために利用しますので、以下のコマンドで Google アカウントの認証情報を ADC としてローカルに保存します。
gcloud auth application-default login
コマンドを実行すると Web ブラウザが自動起動し、Google アカウントのログイン画面が表示されます。画面に従いアクセスリクエストを許可することでアクセストークンが取得されます。
これで Terraform の実行に必要な準備はすべて完了です。次の手順では具体的な Terraform のコードの中身を見ていきます。
5. Terraform コードの作成
Terraform のコードを作成していきます。
まずは provider.tf ファイルです。ここではプロバイダ情報を2つ指定します。1つ目はサービスアカウントのアクセストークンを取得するために使用するプロバイダ、 2つ目はリソースを構築するために使用するプロバイダです。またアクセストークンを取得するためのデータブロックもあわせて記載します。
# リソースを構築するためのプロバイダ
provider "google" {
project = "nridev"
access_token = data.google_service_account_access_token.default.access_token
}
# 有効期限の短いトークンを取得するためのプロバイダ
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 = var.terraform_service_account
scopes = ["userinfo-email", "cloud-platform"]
lifetime = "300s"
}
lifetime
はトークンの有効期限です。Terraform の実行に必要な時間だけ使えれば良いので、今回は5分 (300s) にしています。
次にサービスアカウントの情報を変数で定義します。今回は変数で値を渡していますが、Google Cloud ブログでは local 変数を利用しているようです。ここはお好みの方法を利用いただければ問題ありません。
variable "terraform_service_account" {}
terraform_service_account = "terraform@[myprojectid].iam.gserviceaccount.com"
最後に BigQuery のデータセットを定義します。
resource "google_bigquery_dataset" "dataset" {
dataset_id = "test"
friendly_name = "test"
description = "This is a test dataset"
location = "asia-northeast1"
}
あとは Terraform を実行するだけです。
サービスアカウントキーを利用せずに Terraform を実行する方法について解説しました。
認証・認可まわりは少し地味ではありますが Google Cloud に限らずクラウドを利用するためには非常に重要なポイントです。Google Cloud では Workload Identity 連携や Workforce Identity 連携など新しい機能が登場していますので、今後も安全かつスマートな方法を追求していきたいと思います。
Discussion