儲存空間事件函式應用程式

架構

Storage Event Function App 是圖片目錄和縮圖製作工具。這項服務由下列元件組成:

  • 使用者可上傳圖片的用戶端應用程式。
    • 容器代管的 API 和靜態網站 - Golang - Cloud Run
    • 儲存空間 - 檔案儲存空間 - Cloud Storage
  • 影像處理器,可建立圖片的縮圖。
    • 函式即服務 - Golang - Cloud Functions
  • 部署管道。
    • 部署作業 - Cloud Build

開始使用

按一下下列連結,即可在 Cloud Shell 中複製原始碼。完成後,只要執行單一指令,即可在專案中啟動應用程式的工作副本。

在 Cloud Shell 開啟

在 GitHub 上查看原始碼


Storage Event Function App 元件

儲存空間事件函式應用程式架構會使用多項產品。 下表列出各項元件,並提供元件的相關資訊,包括相關影片、產品說明文件和互動式導覽的連結。
影片 文件 逐步操作說明
Cloud Run Cloud Run 可讓您在容器中執行應用程式,但採用無伺服器方式,不必設定執行個體、處理器或記憶體數量。上傳容器,取得網址。
Cloud Storage Cloud Storage 提供檔案儲存空間,並透過 http(s) 公開提供圖片。
Cloud Functions Cloud Functions 是函式服務平台,可讓您監聽 Cloud Storage 檔案上傳作業,並執行程式碼來建立縮圖。
Cloud Build Cloud Build 是封裝容器並部署容器的工具,可將容器以 Cloud Run 服務的形式提供。

指令碼

安裝指令碼會使用以 go 撰寫的可執行檔和 Terraform CLI 工具,在空白專案中安裝應用程式。輸出內容應為可運作的應用程式,以及負載平衡 IP 位址的網址。

./main.tf

啟用服務

專案預設會停用 Google Cloud 服務。如要使用這裡的任何解決方案,請啟用下列項目:

  • Cloud Build - 建立容器映像檔並部署至 Cloud Run
  • Cloud Storage - 存放靜態檔案
  • Cloud Functions - 函式即服務平台
  • Cloud Run - 無伺服器工具,用於代管容器並提供網址,方便存取應用程式。
  • Artifact Registry - 儲存 Docker 映像檔,供 Cloud Build 使用。
variable "gcp_service_list" {
    description = "The list of apis necessary for the project"
    type        = list(string)
    default = [
        "cloudbuild.googleapis.com",
        "storage.googleapis.com",
        "cloudfunctions.googleapis.com",
        "run.googleapis.com",
        "artifactregistry.googleapis.com",
    ]
}

resource "google_project_service" "all" {
    for_each                   = toset(var.gcp_service_list)
    project                    = var.project_number
    service                    = each.key
    disable_dependent_services = false
    disable_on_destroy         = false
}

設定權限

設定 IAM 角色和權限,允許 Cloud Build 部署所有服務。

  • 允許 Cloud Build 服務帳戶部署至 Cloud Run
  • 允許 Cloud Build 服務帳戶執行服務帳戶活動
  • 允許 Cloud Build 服務帳戶發布至 Cloud Run
  • 允許 Cloud Build 服務帳戶將容器儲存在 Artifact Registry 中
variable "build_roles_list" {
    description = "The list of roles that build needs for"
    type        = list(string)
    default = [
        "roles/run.developer",
        "roles/iam.serviceAccountUser",
        "roles/run.admin",
        "roles/cloudfunctions.admin",
        "roles/artifactregistry.admin",
    ]
}

resource "google_project_iam_member" "allbuild" {
    for_each   = toset(var.build_roles_list)
    project    = var.project_number
    role       = each.key
    member     = "serviceAccount:${local.sabuild}"
    depends_on = [google_project_service.all]
}

建立儲存空間 bucket

為上傳的圖片和縮圖建立儲存位置,並為 Cloud Functions 上傳作業提供暫時儲存位置。

resource "google_storage_bucket" "target_bucket" {
    name     = var.bucket
    project  = var.project_number
    location = var.location
}

resource "google_storage_bucket" "function_bucket" {
    name     = "${var.project_id}-function-deployer"
    project  = var.project_number
    location = var.location
}

建立 Artifact Registry 存放區

下列程式碼會列出 Artifact Registry 存放區的參數,容器會儲存在該存放區中。

resource "google_artifact_registry_repository" "app" {
    provider      = google-beta
    format        = "DOCKER"
    location      = var.region
    project       = var.project_id
    repository_id = "${var.basename}-app"
    depends_on    = [google_project_service.all]
}

為 Cloud Run 應用程式建構容器

下列指令會建構映像檔,並上傳至 Artifact Registry,以供 Cloud Build 使用。

resource "null_resource" "cloudbuild_app" {
    provisioner "local-exec" {
        working_dir = "${path.module}/code/app"
        command     = "gcloud builds submit . --substitutions=_REGION=${var.region},_BASENAME=${var.basename}"
    }

    depends_on = [
        google_artifact_registry_repository.app,
        google_project_service.all
    ]
}

部署至 Cloud Run

以下範例使用 Cloud Build 將用戶端網頁應用程式部署至 Cloud Run。

resource "google_cloud_run_service" "app" {
    name     = "${var.basename}-app"
    location = var.region
    project  = var.project_id

    template {
        spec {
            containers {
                image = "${var.region}-docker.pkg.dev/${var.project_id}/${var.basename}-app/prod"
                env {
                name  = "BUCKET"
                value = var.bucket
                }
            }
        }

        metadata {
            annotations = {
                "autoscaling.knative.dev/maxScale" = "1000"
                "run.googleapis.com/client-name"   = "terraform"
            }
        }
    }
    autogenerate_revision_name = true
    depends_on = [
        null_resource.cloudbuild_app,
    ]
}

data "google_iam_policy" "noauth" {
    binding {
        role = "roles/run.invoker"
        members = [
        "allUsers",
        ]
    }
}

resource "google_cloud_run_service_iam_policy" "noauth_app" {
    location    = google_cloud_run_service.app.location
    project     = google_cloud_run_service.app.project
    service     = google_cloud_run_service.app.name
    policy_data = data.google_iam_policy.noauth.policy_data
}

將函式程式碼部署至 Cloud Functions

直接推送到函式並啟用。

resource "google_storage_bucket_object" "archive" {
    name   = "index.zip"
    bucket = google_storage_bucket.function_bucket.name
    source = "index.zip"
    depends_on = [
        google_project_service.all,
        google_storage_bucket.function_bucket,
        null_resource.cloudbuild_function
    ]
}

resource "google_cloudfunctions_function" "function" {
    name    = var.basename
    project = var.project_id
    region  = var.region
    runtime = "go116"

    available_memory_mb   = 128
    source_archive_bucket = google_storage_bucket.function_bucket.name
    source_archive_object = google_storage_bucket_object.archive.name
    entry_point           = "OnFileUpload"
    event_trigger {
        event_type = "google.storage.object.finalize"
        resource   = google_storage_bucket.target_bucket.name
    }

    depends_on = [
        google_storage_bucket.function_bucket,
        google_storage_bucket.target_bucket,
        google_storage_bucket_object.archive,
        google_project_service.all
    ]
}

./code/app/cloudbuild.yaml

建構 API 容器

下列指令會為網頁應用程式建立 Docker 映像檔。

- name: "gcr.io/cloud-builders/docker"
  args: [ "build", "-t", "$_REGION-docker.pkg.dev/$PROJECT_ID/$_BASENAME-app/prod", ".", ]

將 API 容器推送至 Artifact Registry

將容器推送至 Artifact Registry 後,Cloud Run 就能取得並提供該映像檔。

- name: "gcr.io/cloud-builders/docker"
  args: ["push", "$_REGION-docker.pkg.dev/$PROJECT_ID/$_BASENAME-app/prod"]

替代字詞

建立含有預設值的變數,以便在部署時變更這些值。

substitutions:
  _REGION: us-central1
  _BASENAME: scaler

結論

您現在已在專案中執行縮圖建立解決方案,並使用 Cloud Functions 回應儲存空間值區的變更。您也可以修改或擴充這個解決方案的所有程式碼,