概要
CloudRun のコンソール”継続的デプロイ”から選択して作成できるGitHub のソースコードトリガーを terraform にてIaCしてみた話
背景
CloudRun は2021年10月頃に Go や Python のような特定の言語において Dockerfile を必要とせずソースコードから直接デプロイができるようになりました。
しかもCloudRun のコンソールからCDトリガーを作成でき、ソースコードからデプロイの設定もできて便利だったので、ついでにこれをIaCして使いまわそうと思ったのがきっかけです
ソースコードについて
terraform の概要については割愛します。
ディレクトリ構成
ディレクトリ構成は以下のような構成です。
実際には環境ごとに分けていたりするのです便宜上、簡易的に表現しました。
--modeles/cloudbuild
| |- main.tf
| |- variabels.tf
|- main.tf
|- variables.tf
modules にモジュールの詳細を書き、
環境によってはmainのvariablesを上書きして更新するような使い方です。
コード
cloudbuild-trigger.tf
resource "google_cloudbuild_trigger" "default" {
description = "Build and deploy to Cloud Run service ${var.project} on push to \"^${var.github_branch}$\""
name = "rmgpgab-${var.project}-api--${var.region}"
substitutions = {
"_DEPLOY_REGION" = "${var.region}"
"_GCR_HOSTNAME" = "us.gcr.io"
"_PLATFORM" = "managed"
"_SERVICE_NAME" = "${var.project}-api"
}
tags = [
"gcp-cloud-build-deploy-cloud-run",
"gcp-cloud-build-deploy-cloud-run-managed",
var.project,
]
build {
images = [
"$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA",
]
substitutions = {
"_DEPLOY_REGION" = "${var.region}"
"_GCR_HOSTNAME" = "us.gcr.io"
"_PLATFORM" = "managed"
"_SERVICE_NAME" = "${var.project}"
"_CLOUDRUN_MEMORY" = "${var.cloudrun_memory}"
"_CLOUDRUN_MIN_INSTANCES" = "${var.cloudrun_min_instances}"
"_CLOUDRUN_MAX_INSTANCES" = "${var.cloudrun_max_instances}"
"_CLOUDRUN_CPU" = "${var.cloudrun_cpu}"
"_CLOUDRUN_APP_PORT" = "${var.cloudrun_app_port}"
"_CLOUDRUN_APP_CLIENT_HOST" = "${var.cloudrun_app_client_host}"
"_CLOUDRUN_INSTANCE_CONNECTION_NAME" = "${var.cloudsql_instance}"
"_CLOUDSQL_PASSWORD" = "${var.cloudsql_password}"
"_CLOUDSQL_PORT" = "${var.cloudsql_port}"
"_CLOUDSQL_DB_NAME" = "${var.cloudsql_db_name}"
"_CLOUDSQL_INSTANCE" = "${var.cloudsql_instance}"
"_CLOUDSQL_USERNAME" = "${var.cloudsql_username}"
}
tags = [
"gcp-cloud-build-deploy-cloud-run",
"gcp-cloud-build-deploy-cloud-run-managed",
"${var.project}",
]
options {
disk_size_gb = 0
dynamic_substitutions = false
substitution_option = "ALLOW_LOOSE"
}
step {
args = [
"build",
"$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA",
"--builder=gcr.io/buildpacks/builder:v1",
"--path=api",
]
entrypoint = "pack"
id = "Buildpack"
name = "gcr.io/k8s-skaffold/pack"
}
step {
args = [
"push",
"$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA",
]
id = "Push"
name = "gcr.io/cloud-builders/docker"
}
# https://cloud.google.com/sdk/gcloud/reference/run/services/update
step {
args = [
"run",
"deploy", // cloud run のリソースは別で作っておいてupdateするのが適切かもしれない
"$_SERVICE_NAME",
"--allow-unauthenticated",
"--platform=managed",
"--region=$_DEPLOY_REGION",
"--image=$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA",
"--labels=managed-by=gcp-cloud-build-deploy-cloud-run,commit-sha=$COMMIT_SHA,gcb-build-id=$BUILD_ID,gcb-trigger-id=$_TRIGGER_ID,$_LABELS",
"--min-instances=$_CLOUDRUN_MIN_INSTANCES",
"--max-instances=$_CLOUDRUN_MAX_INSTANCES",
"--memory=$_CLOUDRUN_MEMORY",
"--cpu=$_CLOUDRUN_CPU",
"--add-cloudsql-instances=$_CLOUDSQL_INSTANCE",
"--set-env-vars=APP_PORT=$_CLOUDRUN_APP_PORT",
"--set-env-vars=INSTANCE_CONNECTION_NAME=$_CLOUDRUN_INSTANCE_CONNECTION_NAME",
"--set-env-vars=DB_PORT=$_CLOUDSQL_PORT",
"--set-env-vars=DB_USER=$_CLOUDSQL_USERNAME",
"--set-env-vars=DB_PASSWORD=$_CLOUDSQL_PASSWORD",
"--set-env-vars=DB_NAME=$_CLOUDSQL_DB_NAME",
"--set-env-vars=APP_CLIENT_HOST=$_CLOUDRUN_APP_CLIENT_HOST",
"--quiet",
]
entrypoint = "gcloud"
id = "Deploy"
name = "gcr.io/google.com/cloudsdktool/cloud-sdk:slim"
}
}
github {
name = var.github_repo
owner = var.github_owner
push {
branch = "^${var.github_branch}$"
invert_regex = false
}
}
}
※環境変数はシークレットも--set-env-varsで設定していますが、実際にはシークレットマネージャーを用いて設定する必要があります。そうしないとCloudRun の閲覧権限がある人からシークレットが見えてしまします。今後、修正する予定です。
main.tf
module "cloudbuild-trigger" {
source = "./modules/cloudbuild-trigger"
project = var.project
project_id = var.project_id
region = var.region
github_owner = var.github_owner
github_repo = var.github_repo
cloudrun_memory = var.cloudrun_memory
cloudrun_max_instances = var.cloudrun_max_instances
cloudrun_min_instances = var.cloudrun_min_instances
cloudrun_cpu = var.cloudrun_cpu
cloudrun_app_client_host = var.cloudrun_app_client_host
cloudsql_username = var.cloudsql_username
cloudsql_password = var.cloudsql_password
cloudsql_db_name = var.cloudsql_db_name
cloudsql_instance = var.cloudsql_instance
}