今天來跟大家介紹詳細解釋如何利用 terraform 實作具有 CICD 的 cloud run + cloud sql

從根目錄開始看, 可以得知整個專案很清楚的拆分成服務實體和 CICD 兩個元件, 按照順序建置
module "sql-instance" {
  source       = "./instances"
  service_name = module.global_var.service-name
  region       = module.global_var.region
  run-sa       = "77786086397-compute@developer.gserviceaccount.com"
  db-name      = "postgres"
}
module "cicd" {
  source     = "./cicd"
  depends_on = [module.sql-instance]
  git_token = "<your git token>"
  build_sa = "service-77786086397@gcp-sa-cloudbuild.iam.gserviceaccount.com"
  git_app_id = "36856157"
  builder_sa = "77786086397@cloudbuild.gserviceaccount.com"
  service_name = module.global_var.service-name
}
服務實體是按照順序建置 cloud sql, sql user, cloud run
此時有一個小細節, 因為真正的 image 可以靠 CD 推上來, 所以這裡可以直接引用一個你所需要的靜態頁面的圖像, 之後網站維護也直接用這個圖像即可, 很方便
resource "google_sql_database_instance" "instance" {
  name             = "${var.service_name}-sql"
  region           = var.region
  database_version = "POSTGRES_15"
  settings {
    tier      = "db-f1-micro"
    disk_type = "PD_HDD"
    disk_size = 10
    database_flags {
      name  = "cloudsql.iam_authentication"
      value = "on"
    }
  }
  deletion_protection = "false"
}
resource "time_sleep" "wait_seconds" {
  depends_on = [google_sql_database_instance.instance]
  create_duration = "60s"
}
resource "google_sql_user" "iam_service_account_user" {
  # Note: for Postgres only, GCP requires omitting the ".gserviceaccount.com" suffix
  # from the service account email due to length limits on database usernames.
  name = trimsuffix(var.run-sa, ".gserviceaccount.com")
  /* name     = var.run-sa */
  instance = google_sql_database_instance.instance.name
  type     = "CLOUD_IAM_SERVICE_ACCOUNT"
  depends_on = [time_sleep.wait_seconds]
}
resource "google_cloud_run_v2_service" "default" {
  name     = var.service_name
  location = var.region
  ingress  = "INGRESS_TRAFFIC_ALL"
  template {
    service_account = var.run-sa
    scaling {
      max_instance_count = 3
      min_instance_count = 0
    }
    volumes {
      name = "cloudsql"
      cloud_sql_instance {
        instances = [google_sql_database_instance.instance.connection_name]
      }
    }
    containers {
      image = "us-docker.pkg.dev/cloudrun/container/hello"
      env {
        name  = "DB_IAM_USER"
        value = google_sql_user.iam_service_account_user.name
      }
      env {
        name  = "DB_NAME"
        value = var.db-name
      }
      env {
        name  = "INSTANCE_CONNECTION_NAME"
        value = google_sql_database_instance.instance.connection_name
      }
      volume_mounts {
        name       = "cloudsql"
        mount_path = "/cloudsql"
      }
    }
  }
  traffic {
    type    = "TRAFFIC_TARGET_ALLOCATION_TYPE_LATEST"
    percent = 100
  }
  depends_on = [google_sql_user.iam_service_account_user]
}
CICD 組件相對複雜, 不過我們前面的文章都大概聊過了
依序執行
module "git-connection" {
  source     = "./github-connection"
  secret_id  = "github-token"
  name       = "github-connection"
  git_token  = var.git_token
  git_app_id = var.git_app_id
  build_sa   = var.build_sa
  region     = module.global_var.region
  git-url    = module.global_var.git-url
}
resource "google_artifact_registry_repository" "docker-images" {
  location      = module.global_var.region
  repository_id = var.service_name
  description   = "example docker repository"
  format        = "DOCKER"
  docker_config {
    immutable_tags = false
  }
}
resource "google_project_iam_member" "r1" {
  project = module.global_var.project_id
  role    = "roles/run.admin"
  member  = "serviceAccount:${var.builder_sa}"
}
resource "google_project_iam_member" "r2" {
  project    = module.global_var.project_id
  role       = "roles/iam.serviceAccountUser"
  member     = "serviceAccount:${var.builder_sa}"
  depends_on = [google_project_iam_member.r1]
}
module "build" {
  source    = "./cloud-build"
  name      = var.service_name
  file      = module.global_var.build-file-path
  region    = module.global_var.region
  repo-id   = module.git-connection.repo-id
  repo-name = google_artifact_registry_repository.docker-images.name
  depends_on = [module.git-connection, google_artifact_registry_repository.docker-images, google_project_iam_member.r2]
}