Terraform Cloud で Google Cloud プロジェクトを作成する
はじめに
社内で Google Cloud プロジェクトを新規で用意する場合、現在はプロジェクト作成権限を持ったユーザが手動で行っています。
今回は Terraform Cloud を使ってプロジェクト作成を自動でできるようにしました。
構築手順
Terraform Cloud 環境設定
Terraform Cloud のセットアップをします。
terraform Cloud の Organization はすでに用意されていたものを使うことになっていたので、Workspace の作成から始めます。
今回は CLI-driven workflow を選びます。
Workspace 名と紐づくプロジェクトを指定し、「Create workspace」より Workspace を作成します。
Terraform CLI のセットアップ
ローカルマシンに Terraform CLI をインストールし、Terraform Cloud に接続できるようにします。
以下URLから CLI 用の Zip ファイルをダウンロードし、任意の場所に展開します。
展開したパス上でコマンドプロンプトを開き、terraform login
コマンドを実行します。
yes
を入力すると自動的に Terraform Cloud の Token ページが開きます。初めて接続する場合はトークンを新規作成し、トークン文字列をコマンドプロンプトに入力します。
terraform workspace
コマンドで接続する Workspace を指定できますが、後述のテンプレートの中で記述するためこのコマンドは不要かもしれません。
テンプレートを保存するフォルダを作成し、そのフォルダ上でコマンドプロンプトを開き、terraform init
を実行します。
Google Cloud サービスアカウントの準備
Terraform で Google Cloud のリソースを作成するには、リソース作成に必要な権限をもつサービスアカウントのキーが必要になります。
サービスアカウントはプロジェクトごとに作成できます。組織に直接紐づくサービスアカウントは作成できません。
下記記事を参考に、任意のプロジェクトでサービスアカウント作成後、gcloud organizations add-iam-policy-binding
コマンドで2つのロール roles/resourcemanager.projectCreator
と roles/billing.user
を付与しました。
ロールを付与したサービスアカウントのキーを新規発行します。
今回はキー連携を行っていますが、画像の通り Workload Identity 連携のほうがより安全とのことです。
また、サービスアカウントを作成したプロジェクトで Cloud Billing API が有効化されていない場合は有効化します。
プロジェクト作成のプロバイダーに請求先アカウントIDを指定する場合、Cloud Billing API が無効化状態だと以下のエラーが発生します。
Error: failed pre-requisites: failed to check permissions on billing account "billingAccounts/<Billing ID>": googleapi: Error 403: Cloud Billing API has not been used in project <Project ID> before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/cloudbilling.googleapis.com/overview?project=<Project ID> then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry. Details: [ { "@type": "type.googleapis.com/google.rpc.Help", "links": [ { "description": "Google developers console API activation", "url": "https://console.developers.google.com/apis/api/cloudbilling.googleapis.com/overview?project=<Project ID>" } ] }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "googleapis.com", "metadata": { "consumer": "projects/<Project ID>", "service": "cloudbilling.googleapis.com" }, "reason": "SERVICE_DISABLED" } ] , accessNotConfigured
with google_project.new_project
テンプレートの作成
プロジェクトを作成するテンプレートを作成します。
まず接続先の Workspace と使用するプロバイダーを指定します。
terraform {
cloud {
organization = "<Organaization Name>"
workspaces {
name = "google-cloud"
}
}
required_providers {
google = {
source = "hashicorp/google"
version = "4.51.0"
}
}
}
続いて、プロジェクト作成プロバイダーに関するテンプレートを追加します。
認証に必要な先述でダウンロードしたサービスアカウントのキー文字列とプロジェクト作成プロバイダーの引数となる新規作成するプロジェクトID、プロジェクト名、紐づける組織ID、紐づける請求先アカウント(任意)を追加します。
このうち、サービスアカウントのキー文字列・紐づける組織ID・紐づける請求先アカウントは不変であり、特にキー文字列は平文で持ちたくありません。
なのでこの3つを Terraform Cloud の環境変数として登録しました。
Workspace の Variables より、Terraform variables として作成します。意図せぬところで値が見えないように、Sensitive で作成します。
テンプレートでは、variable "<変数名>" {}
で変数宣言し、変数を使う場合は ${var.<変数名>}
を指定します。
variable "GOOGLE_CREDENTIALS" {}
variable "ORGNIZATION_ID" {}
variable "BILLING_ACCOUNT" {}
provider "google" {
credentials = "${var.GOOGLE_CREDENTIALS}"
}
resource "google_project" "new_project" {
name = "<Project Name>"
project_id = "<Project ID>"
org_id = "${var.ORGNIZATION_ID}"
billing_account = "${var.BILLING_ACCOUNT}"
}
テンプレート作成は以上です。
わたしはプロバイダー指定部分とリソース作成部分でテンプレートを分けたかったので別ファイルにしましたが、1ファイルに合わせて記述しても問題ないと思います。
実行
テンプレートを実行しプロジェクト作成ができるか確認します。
terraform init
を実行したコマンドプロンプトに戻り、terraform validate
でテンプレートの構文チェック、terraform apply
でテンプレートを実行します。
terraform plan
で作成されるリソースを確認する(いわゆる dry run)こともできます。
参考
以上です。どなたかの参考になれば幸いです。