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

+

架構

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

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

開始使用

按一下以下連結,前往 Cloud Shell 中的原始碼副本。完成後,您只需執行單一指令,即可在專案中啟動應用程式的可用副本。

在 Cloud Shell 開啟

在 GitHub 上查看原始碼


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

儲存空間事件函式應用程式架構會使用多項產品。以下列出這些元件,並提供相關資訊,包括相關影片、產品說明文件和互動式操作說明的連結。
影片 文件 逐步操作說明
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:儲存可與 Cloud Build 搭配使用的 Docker 映像檔。
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]
}

建立儲存空間值區

為上傳的圖片和縮圖建立 Cloud Storage 位置,並提供 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 函式來回應儲存空間值區變更的縮圖建立解決方案。您也擁有所有用於修改或擴充此解決方案的程式碼