[Terraform] CloudRunでアプリケーションを動かすチュートリアル
目次
Introduction
TerraformでCloudRunを構築することがあり、また構築する時に再度調べるのがめんどくさいので備忘録として残したいと思います。
今回は、Terraformを実行する環境構築は省きます。
作成するリソース
今回作成するGCPリソースとCICDの要件は以下になります。
- 今回はサンプルアプリケーションは省略
- CICD環境はGithubActionsを選択
- アプリケーションサーバーはマネージドなCloudRunを使用
- GCPリソースは、Terraformで構築
- tfファイルの記述量を減らすために公式のmoduleを使用
- ディレクトリ構成は記述してないので、参考にする場合は構成お任せします
作成するインフラ構成図は以下になります。

HandsOn
では、淡々と構築するためのコードを貼っていきます。
環境ごとのファイル構築
最初にプロジェクトごとの設定ファイルを作成します。
locals {
project-id = "development-project"
env = "development"
project = "tech-blog"
github-repo = "kita21/tech-blog-sample"
location = "asia-northeast1"
}
IAM
ではまず、各リソースを動かすためのServiceAccountを作成していきます。
# https://cloud.google.com/iam/docs/understanding-roles
# https://github.com/terraform-google-modules/terraform-google-service-accounts
module "cloudrun_service_account" {
source = "terraform-google-modules/service-accounts/google"
version = "~> 4.2.0"
display_name = "cloudrun-service-account"
description = "service-account for cloudrun"
project_id = local.project-id
prefix = "cloudrun"
names = ["sample"]
project_roles = [
"${local.project-id}=>roles/secretmanager.secretAccessor"
]
}
module "github_actions_service_account" {
source = "terraform-google-modules/service-accounts/google"
version = "~> 4.2.0"
display_name = "github-actions-service-account"
description = "service-account for github-actions. use cloud-run deploy"
project_id = local.project-id
prefix = "github-actions"
names = ["deploy"]
project_roles = [
"${local.project-id}=>roles/artifactregistry.writer",
"${local.project-id}=>roles/run.developer",
"${local.project-id}=>roles/iam.serviceAccountUser",
"${local.project-id}=>roles/secretmanager.secretAccessor"
]
}
resource "google_service_account_iam_binding" "iam_workload_identity_user_binding" {
service_account_id = "projects/${local.project-id}/serviceAccounts/${module.github_actions_service_account.email}"
role = "roles/iam.workloadIdentityUser"
members = [
"principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.github_actions_pool.name}/attribute.repository/${local.github-repo}"
]
}
次にGithubActionsと連携するためのWorkloadIdentityを作成
resource "google_iam_workload_identity_pool" "github_actions_pool" {
workload_identity_pool_id = "github-actions-pool"
display_name = "github-actions-pool"
description = "pool for access from github-actions"
disabled = false
}
resource "google_iam_workload_identity_pool_provider" "github_actions_provider" {
workload_identity_pool_id = google_iam_workload_identity_pool.github_actions_pool.workload_identity_pool_id
workload_identity_pool_provider_id = "github-actions-provider"
display_name = "github-actions-provider"
disabled = false
attribute_mapping = {
"google.subject" = "assertion.sub"
"attribute.actor" = "assertion.actor"
"attribute.repository" = "assertion.repository"
}
attribute_condition = "assertion.repository==\"${local.github-repo}\""
oidc {
issuer_uri = "https://token.actions.githubusercontent.com"
}
}
CloudRun
CloudRunはコンテナで動くため、イメージを保存するためのレジストリーを作成
resource "google_artifact_registry_repository" "gar" {
location = "asia-northeast1"
repository_id = local.project
description = "gcr for cloudrun"
format = "DOCKER"
}
resource "google_artifact_registry_repository_iam_binding" "gar_reader_binding" {
project = google_artifact_registry_repository.gar.project
location = google_artifact_registry_repository.gar.location
repository = google_artifact_registry_repository.gar.name
role = "roles/artifactregistry.reader"
members = [
"serviceAccount:${module.cloudrun_service_account.email}"
]
}
メインのCloudRunを構築していきます。
- ポートは3001
- インスタンス数は料金的を考えてminScaleは0
# https://github.com/GoogleCloudPlatform/terraform-google-cloud-run
module "cloudrun" {
source = "GoogleCloudPlatform/cloud-run/google"
version = "~> 0.8.0"
service_name = "${local.env}-${local.project}"
project_id = local.project-id
location = local.location
image = "${local.location}-docker.pkg.dev/${local.project-id}/${local.project}/${local.env}-${local.project}-cloudrun:latest"
template_annotations = {
"autoscaling.knative.dev/maxScale" = 1
"autoscaling.knative.dev/minScale" = 0
}
ports = {
name = "http1"
port = 3001
}
limits = {
cpu = "1000m"
memory = "256Mi"
}
members = ["allUsers"]
service_account_email = module.cloudrun_service_account.email
}
GitHubActions
GithubActionsを動かすためのworkflowsファイルを作成します。
developブランチにマージやコミットされたら実行されるような設定にします。
yamlファイルの流れは以下になります
- 必要な設定を環境変数に格納
- GCPの認証情報取得
- Artifact Registryから最新のイメージを取得後、Dockerfileをビルド
- ビルドされたイメージをArtifact RegistryにPush後、CloudRunを更新
Dockerfileはアプリケーションによるので今回は記述しないです。
name: Deploy to gcp cloudrun
on:
workflow_dispatch:
push:
branches:
- develop
permissions:
id-token: write
contents: read
env:
WORKLOAD_IDENTITY_PROVIDER: projects/xxxxxx/locations/global/workloadIdentityPools/github-actions-pool/providers/github-actions-provider
GAR_REPO: tech-blog
DEPLOY_REGION: asia-northeast1
jobs:
BuildAndDeploy:
timeout-minutes: 20
runs-on: ubuntu-22.04
steps:
# env
- name: Env Each. Env Setting
if: github.ref == 'refs/heads/develop'
run: |
echo NEXT_PUBLIC_SERVICE_ENV=development >> $GITHUB_ENV
echo GCP_PROJECT_ID=development-project >> $GITHUB_ENV
echo SERVICE_NAME=development-tech-blog >> $GITHUB_ENV
- name: Common. Env Setting
run: |
echo GCP_SERVICE_ACCOUNT=github-actions-deploy@${{ env.GCP_PROJECT_ID }}.iam.gserviceaccount.com >> $GITHUB_ENV
echo GAR_DOCKER_REPO=${{ env.DEPLOY_REGION }}-docker.pkg.dev/${{ env.GCP_PROJECT_ID }}/${{ env.GAR_REPO }}/${{ env.SERVICE_NAME }} >> $GITHUB_ENV
# setting
- name: Github Checkout
uses: actions/checkout@v3
- id: auth
name: Authenticate to Google Cloud
uses: google-github-actions/auth@v1
with:
workload_identity_provider: ${{ env.WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ env.GCP_SERVICE_ACCOUNT }}
- name: Setup Cloud SDK
uses: google-github-actions/setup-gcloud@v1
- name: Authorize Docker push
run: gcloud auth configure-docker ${{ env.DEPLOY_REGION }}-docker.pkg.dev
# build
- name: Pull Latest Image
run: docker pull ${{ env.GAR_DOCKER_REPO }}:latest || true
- name: Build Docker Image
run: |-
docker build -f Dockerfile . \
-t ${{ env.GAR_DOCKER_REPO }}:${{ github.sha }} \
-t ${{ env.GAR_DOCKER_REPO }}:latest \
--cache-from ${{ env.GAR_DOCKER_REPO }}:latest
- name: Push
run: docker push --all-tags ${{ env.GAR_DOCKER_REPO }}
# deploy
- name: Deploy to CloudRun
run: |-
gcloud run deploy $SERVICE_NAME \
--project=${{ env.GCP_PROJECT_ID }} \
--image=${{ env.GAR_DOCKER_REPO }}:${{ github.sha }} \
--region=${{ env.DEPLOY_REGION }} \
--service-account=${{ env.GCP_SERVICE_ACCOUNT }} \
--allow-unauthenticated \
--no-use-http2
終わりに
以上で、CloudRunのTerraform構築テンプレートになります。
自分のメモ代わりに特に説明なく淡々とtfファイルとgithub-actionsファイルを記載しました。
かなりざっくり書いたのでこれをみて構築しようとしている人は、しっかりTerraformのプロパティやmoduleの詳細を確認しながら構築してくださいね。