iT邦幫忙

2023 iThome 鐵人賽

DAY 25
0
IT管理

GCP 的 terraform 之旅系列 第 25

day25 Terraform GCP cloud run CICD(下)

  • 分享至 

  • xImage
  •  

簡介

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

https://ithelp.ithome.com.tw/upload/images/20231006/20131164k8RGlATHs1.png

code

正文

從根目錄開始看, 可以得知整個專案很清楚的拆分成服務實體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 組件相對複雜, 不過我們前面的文章都大概聊過了

依序執行

  1. 建立 git 和 cloud build 的連線
  2. 創建圖像倉庫
  3. 給予 cloud build 操作 cloud run 的權限 (才能發佈)
  4. 利用 cloud build 建構 git 內原始碼到 cloud run
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]
}

上一篇
day24 Terraform GCP cloud run CICD(上)
下一篇
day26 Terraform GCP loadBalancer
系列文
GCP 的 terraform 之旅31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言