LoginSignup
3
0

More than 1 year has passed since last update.

terraform でCloudRun のPR駆動CloudBuildトリガーを作成する

Posted at

概要

CloudRun のコンソール”継続的デプロイ”から選択して作成できるGitHub のソースコードトリガーを terraform にてIaCしてみた話

背景

CloudRun は2021年10月頃に Go や Python のような特定の言語において Dockerfile を必要とせずソースコードから直接デプロイができるようになりました。

しかもCloudRun のコンソールからCDトリガーを作成でき、ソースコードからデプロイの設定もできて便利だったので、ついでにこれをIaCして使いまわそうと思ったのがきっかけです

「継続的なデプロイの設定」
image.png

image.png

ソースコードについて

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
}
3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0