Terraform を使って Google Cloud のリソースを管理することはじめ(gloud authを利用)
Google Cloud のリソースを管理するツールのひとつに、Terraformがあります。よくタッグが組まれますが、私が最初何もわからない状態から触ろうとしたとき、リソースをデプロイするまで苦労しました。ので、振り返りも兼ねて記録を残します。
- gcloud コマンドをインストールしてGoogle Cloudのクレデンシャルを作成できるようにする
- Terraform 状態管理のための Cloud Storage バケットを作成する
- Terraform を初期化してリソースをデプロイする
この流れで進めます。
gcloud コマンドのインストール
gloud コマンドをローカルへインストールします。このコマンドは、ローカルマシンと Google Cloud のプロジェクトをつなぎ、クレデンシャルを生成するために使います。また、Terraformの状態を管理するための Cloud Storage バケットを作成するのに使います。
筆者の環境はmacOSです。こちらのドキュメントを参考に環境と相談してインストールしてください。
Google Cloud プロジェクトを作成、クレデンシャル生成
まだ Google Cloud のプロジェクトがなければ、作成してください。
Google Cloudのプロジェクトを作成したら、クレデンシャルを作成する準備を進めます。クレデンシャルはローカルマシンから Google Cloud に接続するため必要なのですが、大きく分けて2種類の取得方法があります。
- Google Cloud でサービスアカウントを作り、そのクレデンシャルをダウンロードする
- Google Cloud のプロジェクトを作成したユーザーアカウント(@gmail.com)を使ってクレデンシャルを作る
ここでは2番目の方法で進めます。
まず、gcloudのコンフィグを設定します。次のコマンドを実行してください。
gcloud config configurations create <任意ですが、作成したプロジェクト名が無難>
# 例
gcloud config configurations create graphql-training
Created [graphql-training].
Activated [graphql-training].
次に、作成したプロファイルにアカウント名とプロジェクト名を設定します。
gcloud config set core/account <Google Cloud のログインに使ったメアド>
gcloud config set core/project <Google Cloud のプロジェクト名>
# 例
gcloud config set core/account test@example.com
gcloud config set core/project graphql-training
この操作により、gcloud コマンドの状態がアップデートされ、コンフィグとしてプロジェクト名とアカウント名がセットされました。ここから、「ログイン」操作を行うことにより、ローカルマシンにクレデンシャル情報が作成されます。次のコマンドを入力してください。
gcloud auth login
するとブラウザが開き、認証を求められます。対応する Google Cloud のアカウントを選んだ上で、連携を許可してください。これで、ローカルマシンにクレデンシャルが生成されます。場所は~/.config/gcloud/credentials.db
です。このクレデンシャルはローカルマシンで次のようなコマンドライン実行時に使われます。
- gcloud
- bq # BigQuery のCLI
- gsutil # Cloud Storage のCLI
さらにもうひとつ認証処理を行ってください。
gcloud auth application-default login
こちらもやはりブラウザが開き、認証を求められます。連携を許可すると、ローカルマシンに別のクレデンシャルが生成されます。場所は~/.config/gcloud/application_default_credentials.json.db
です。このクレデンシャルは Google Cloud のSDKを使ったプログラムを実行する際の認証に利用します。Terraformもこのファイルを使います。
これでローカルマシンから作成した Google Project に対していろいろ操作する準備ができました。
Terraform 状態管理のためのバケット作成
Terraform は Google Cloud 上に作成したリソースの状態を tfstate
というファイルで管理して差分を検出しています。もちろんtfstate
をローカルで持っておくこともできるのですが、複数人の開発ではこのファイルをクラウドストレージで管理することで競合を防げます。Google Cloud の場合は共有ストレージとして Cloud Storage が使えますので、ここで状態管理するようにしましょう。というわけで早速バケットを作ります。gsutil
コマンドを使いますのでこちらもインストールしてください。
その後、状態管理のためのバケットを作成します。
gsutil mb gs://<任意のバケット名>
# 例:
gsutil mb gs://graphql-training-artifacts
mb
は make bucket ですね(多分)。準備OKです。
Terraform 初期化
ここまでできたら Terraform が使えます。Terraform は、もちろんインストールして使ってもいいのですが、Dockerコンテナも提供されているのでそれを使えばインストールいらずです。次のようなbashファイルを作ってください。
#!/bin/bash
command=${@:1}
docker run -it --rm \
-v $PWD:/work \
-v $HOME/.config/gcloud:/.config/gcloud \
-w /work \
-e GOOGLE_APPLICATION_CREDENTIALS=/.config/gcloud/application_default_credentials.json \
--entrypoint "/bin/sh" \
hashicorp/terraform:latest \
-c "terraform $command"
hashicorp/terraform
というコンテナを使って terraform
コマンドを実行しています。先ほどローカルマシンで作ったクレデンシャルもわたしていますね。ではTerraformのリソースを定義します。次のファイルを作ります。
terraform {
required_version = "~> 1.0.0"
backend "gcs" {
prefix = "tfstate/v1"
}
}
## project ##
provider "google" {
project = var.gcp_project_id
region = var.primary_region
}
このファイルはまだリソースを作成しませんが、一度動作確認しましょう。
chmod +x tf.sh
./tf.sh init -backend-config="bucket=<gsutilで作ったバケット>"
# 例:
./tf.sh init -backend-config="bucket=graphql-training-artifacts"
---
Initializing the backend...
Successfully configured the backend "gcs"! Terraform will automatically
use this backend unless the backend configuration changes.
Initializing provider plugins...
- Finding latest version of hashicorp/google-beta...
- Finding latest version of hashicorp/google...
- Installing hashicorp/google-beta v4.6.0...
このように表示されれば成功です。ブラウザで Google Cloud Storage の graphql-training-artifacts/tfstate/v1
を覗いてみてください。状態管理ファイルである default.tfstate
が作成されているはずです。
Artifact Repository のリポジトリを作ってみる
ここまでできればあとはリソース作りたい放題です。最初につくるリソースはなんでもいいのですが、Artifact Registry のリポジトリを作ってみましょう。modules/artifact-registry.tf
ファイルを作ります。
tree
.
├── README.md
├── main.tf
├── modules
│ └── artifact-registry
│ └── artifact-registry.tf
└── tf.sh
variable "gcp_project_id" {}
variable "artifact_registry_location" {
type = string
# https://cloud.google.com/storage/docs/locations
description = "Artifact Registry のロケーションをどこにするか"
}
# バックエンドアプリケーション用の Artifact Registry リポジトリ
resource "google_artifact_registry_repository" "backend" {
provider = google-beta
project = var.gcp_project_id
location = var.artifact_registry_location
repository_id = "backend"
description = "バックエンドアプリケーション"
format = "DOCKER"
}
main.tf
も修正します。
# Cloud Run のデプロイで利用するArtifact Registry のリポジトリ
+module "artifact-registry" {
+ source = "./modules/artifact-registry"
+ gcp_project_id = var.gcp_project_id
+ artifact_registry_location = var.primary_region
+}
さきほどから、var.xxxx
みたいなやつが登場してますね。Terraformで扱える変数です。この仕組みを上手く使うことで、公開したくない情報、外部から注入したい情報をリソース構成に組み込めます。値を注入するために、variable.tf
ファイルを新しく作ってください。
variable "gcp_project_id" {}
variable "primary_region" {}
このファイルを定義することで var.gcp_project_id
のようにリソース定義のなかで呼び出せます。では、実際の値はどのように注入するのでしょうか。いくつか方法があるようですが、ここでは「terraform.tfvars
ファイルをつくり、このファイルはバージョン管理しない」方針をとります。
gcp_project_id = "gql-training"
primary_region = "us-central1"
このくらいであれば別にバージョン管理しても良いのでは?と思うかもしれませんが、開発をすすめるうちに外部APIキーだったり、パスワードだったりを管理することもでてきます。秘匿情報は、たとえばですが Google Cloud の Secret Manager や 1Password で管理しておき、開発メンバーにterraform.tfvars
を共有することで事故を防げます。
さて、注入する変数の値もセットしたところで、init
とplan
を実行してみましょう。これらコマンドではまだリソースは作成されません。
./tf.sh init
Initializing modules...
- artifact-registry in modules/artifact-registry
moduleを新しく定義した場合、改めてinit
が必要になります。
./tf.sh 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:
# module.artifact-registry.google_artifact_registry_repository.backend will be created
+ resource "google_artifact_registry_repository" "backend" {
+ create_time = (known after apply)
+ description = "バックエンドアプリケーション"
+ format = "DOCKER"
+ id = (known after apply)
+ location = "us-central1"
+ name = (known after apply)
+ project = "xxxxxxx"
+ repository_id = "backend"
+ update_time = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
このように表示されるはずです。意図したとおりの作成プランになっているようでしたら、実際に適用するコマンドを打ちます。
./tf.sh apply
もしかするとここで「APIを有効にしてね」というエラーが出るかもしれません。Google Cloud は、リソースを作成したり更新できる管理用 API を用意してくれているのですが、デフォルトでは無効になっているものもあります。Terraform はそんなAPIを使ってリソースを管理しているため、モノによってはAPIを有効にしないと作れないものもあります。ガイドに従い、ブラウザからAPIを有効にしてあげればOKです。その後、再度実行してください。
./tf.sh apply
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
このようなメッセージがでればOKです。最後にArtifact Registryをブラウザで表示して、リソースが作成されていることを確認してください。
まとめ
お疲れさまでした。Terraform をつかって Google Cloud のリソースを作成してみました。Google Cloud の認証作法や Terraform の状態管理で準備する箇所がありますが、そこさえクリアしてしまえば快適にリソースを管理できます。ぜひおためしください。
ソースコード
この記事で紹介したソースコードは以下のリポジトリで公開しています。
Discussion