Terraformを使って、Google Cloud Runへの自動デプロイを構築してみる
はじめに
最近、簡単なWebサービスやバックエンドサーバーのデプロイ先に、Google Cloud Runをよく使用しています。
Cloud Runはコンテナ環境をそのままGoogle Cloud上で動かせるサービスで、Webサービスも簡単に置くことができます。使用されていない間は自動でスケールダウンしてくれるのでコストがかかりずらく、個人開発向きだと思っています(以下、参考記事)。
さて、Cloud Runへデプロイする際は、Google CloudとGithub ActionsをOIDC連携して、自動デプロイのワークフローを組んでいました。その際の方法をまとめた記事がこちらです。
ただGoogle Cloud上での設定が結構多いです。この作業をなんとか自動化できないかと模索した結果、Terraformを使用した自動化が存外簡単に実現できました!
本記事では全体の流れを軽く記載しつつ、TerraformでのGoogle Cloud構築の仕方をメインで話します。
サンプルはこちらです。
※Terraformの仕組みについてはほとんど触れません。あらかじめご了承ください。
全体の流れ
- サービスを用意
- コンテナ環境を用意
- TerraformによるGoogle CloudとGithubのWIF連携
- Github Actionsのworkflow設定
1と2の用意はしてもらった上で、3を自動化できる、という内容です。
Terraformを実行することでGoogle CloudとGithubが連携できるので、あとは4でGithub Actionsによる自動デプロイを設定します。
3のイメージ
CI/CD実行時のイメージ
本記事で紹介する方法は、Workload Identity 連携(Workload Identity Federation, 通称WIF)を用いて、Github Actions内でサービスアカウントを一時的に呼び出し、そのアカウントを使ってデプロイを実行していく流れとなります。このWorkload Identityを経由する方法によりサービスアカウントのキー管理が必要なくなり、かわりにGitHubとGoogle Cloudの間でOpenID Connect(OIDC)認証を使用した安全な認証を行えます。
Workload Identity 連携をするために、次のような準備が必要になります。
- サービスアカウントの作成(ロール付与)
- Workload Identityプールとサービスアカウントとの紐づけ
- Workload IdentityプロバイダとGithubとのOIDC認証の設定
Workload Identity 連携の準備
先ほどの記事では、この3点の準備を手動で実施していきましたが、これをTerraformにより自動化させます。
前回の記事で実施していったgcloudコマンドの通りに、Terraformファイルにて設定を記載していった感じとなります。
例:サービスアカウントへのロール付与
CLIでのコマンド実施だと以下。
$ gcloud projects add-iam-policy-binding <PROJECT_ID> \
--member="serviceAccount:<SA_EMAIL>" \
--role="roles/iam.serviceAccountUser"
$ gcloud projects add-iam-policy-binding <PROJECT_ID> \
--member="serviceAccount:<SA_EMAIL>" \
--role="roles/artifactregistry.writer"
$ gcloud projects add-iam-policy-binding <PROJECT_ID> \
--member="serviceAccount:<SA_EMAIL>" \
--role="roles/run.admin"
Terraformでの書き方は以下のようになります。
resource "google_project_iam_member" "binding" {
for_each = toset(var.roles)
project = var.project
role = each.key
member = "serviceAccount:${var.service_account_email}"
}
以下のドキュメントを参考にして作成しています。
手順
それでは、ここから実際にサービスをCloud Runへデプロイするまでの作業をしていきます。
先ほどの1〜4に従って進めていきます。
1. サービスを用意
デプロイするWebサービスを用意。サンプルではViteを使って構築しています。
2. コンテナ環境を用意
Webサーバーが立ち上がるようなコンテナを構築すべく、dockerfileを用意します。
サンプルではnginxを利用しています。
サンプルDockerfileとnginx
3. TerraformによるGoogle CloudとGithubの連携
ここでGoogle CloudとGithubをWIF連携させるためにTerraformを動かしますが、
少し事前準備が必要です。
Terraformインストールはこちらになります(Windowsだと環境変数の設定も必要です)
事前準備
Terraformで自動化できない部分を済ませます。主にプロジェクト作成と、課金設定になります。
# 端末内でGoogle Cloudにログイン
gcloud auth login
# プロジェクト作成
gcloud projects create new-project-id # (作成済であれば下のコマンドだけ)
gcloud config set project new-project-id
この後GUIの管理画面にて、プロジェクトの課金設定を行ってください。
Terraform用意
さて、メインの部分です。
このterraformフォルダ配下の通りに、ファイルを用意します。
また、各自で設定ファイルが必要になります。terraform.tfvars
を用意して、以下6項目を書き込んでください。
# 必須項目
project_id = "..." # プロジェクトID
github_repo = "user-name/repo-name" # GitHubのユーザー名/リポジトリ名
artifact_registry_repo_name = "..." # Artifact Registryのリポジトリ名
# Github ActionsとのWIF連携時に使用する設定
github_actions = {
service_account_name = "..." # 作成するサービスアカウント名
workload_identity_pool_name = "..." # 使用するWI Pool名
workload_identity_provider_name = "..." # 使用するWI Provider名
}
一旦はこの3項目で問題ないですが、以下項目も任意で指定できます(指定しなければデフォルト)
任意の項目
# 任意の項目
# リージョン(指定しなければ"asia-northeast1")
region = "asia-northeast1"
# Terraform用サービスアカウントの名前(指定しなければデフォルト)
terraform_sa_name = "terraform-sa"
# 追加するAPI、ロールがあれば(指定しなければデフォルト)
# プロジェクトに対して有効化するAPIのリスト
enabled_apis = [
"iam.googleapis.com",
"iamcredentials.googleapis.com",
"cloudresourcemanager.googleapis.com",
"run.googleapis.com",
"artifactregistry.googleapis.com"
]
# Terraform用サービスアカウントに付与するIAMロールのリスト
terraform_sa_roles = [
"roles/iam.serviceAccountAdmin",
"roles/iam.workloadIdentityPoolAdmin",
"roles/serviceusage.serviceUsageAdmin"
]
# GitHub Actions用サービスアカウントに付与するIAMロールのリスト
github_actions_roles = [
"roles/run.admin",
"roles/iam.serviceAccountUser",
"roles/artifactregistry.writer"
]
# Terraform
.terraform
*.tfvars
*.tfstate
*.tfstate.*
tfファイルと.terraform.lock.hclのみGitに共有します。
Terraform実施
以上を済ませたら、terraform/
にて以下を実行します。
terraform init
terraform plan
terraform apply
問題なく通れば完了です!
また、完了時にターミナルからの出力を確認します。
github_actions = {
"PROJECT_ID" = "..."
"SA_EMAIL" = "..."
"WIF_PROVIDER" = "..."
"ARTIFACT_REGISTRY_REPO_NAME" = "..."
}
4. Github Actionsのworkflow設定
先ほどの出力に基づいて、4つの変数をSecretsに設定します(参考記事)。
そして、以下のようにActionsのワークフローファイル(.yaml)を作成します。
あとはmainにpushすることで、自動デプロイが実施されれば完了です!
まとめ
WIFが少し面倒な印象だったので、ここが簡単に行えるようになって効率よくなりました!今後もCloud Runは使っていきたいです。色々サービスデプロイしていきたい。
Discussion