Storage イベント関数アプリ

アーキテクチャ

ストレージ イベント関数アプリは、画像ディレクトリとサムネイル メーカーです。これは次のコンポーネントで構成されています。

  • ユーザーが画像をアップロードできるクライアント アプリケーション。
    • コンテナでホストされる API と静的サイト - Golang - Cloud Run
    • ストレージ - ファイル ストレージ - Cloud Storage
  • 画像のサムネイルを作成する画像プロセッサ。
    • Functions as a Service - Golang - Cloud Functions
  • デプロイ パイプライン。
    • デプロイ - Cloud Build

スタートガイド

Cloud Shell でソースコードのコピーへの次のリンクをクリックします。その後、1 つのコマンドでプロジェクト内のアプリケーションの作業コピーがスピンアップされます。

Cloud Shell で開く

GitHub でソースコードを見る


ストレージ イベント関数アプリのコンポーネント

ストレージ イベント関数のアプリ アーキテクチャでは、いくつかのプロダクトが使用されています。 以下に、関連動画、プロダクト ドキュメント、インタラクティブ チュートリアルへのリンクを含めた、コンポーネントの詳細を示します。
動画 ドキュメント チュートリアル
Cloud Run Cloud Run を使用すると、コンテナ内でアプリケーションを実行できますが、サーバーレスで、インスタンス、プロセッサ、メモリの数を構成する必要はありません。コンテナをアップロードし、URL を取得します。
Cloud Storage Cloud Storage は、http(s) を介してファイル ストレージと画像の一般公開を提供します。
Cloud Functions Cloud Functions は関数であり、Cloud Storage ファイルのアップロードをリッスンし、コードを実行してそれらのサムネイルを作成することができるサービス プラットフォームです。
Cloud Build Cloud Build は、コンテナをパッケージ化し、Cloud Run サービスとして利用できるようにデプロイするツールです。

スクリプト

インストール スクリプトでは、go と Terraform CLI ツールで記述された実行ファイルを使用して、空のプロジェクトを作成し、そこにアプリケーションをインストールします。出力は、機能するアプリケーションとロード バランシング IP アドレスの URL になります。

./main.tf

サービスを有効化する

Google Cloud サービスは、デフォルトではプロジェクトで無効になっています。ここに記載されているいずれかのソリューションを使用するには、以下の対象を有効にする必要があります。

  • Cloud Build - コンテナ イメージを作成して Cloud Run にデプロイします。
  • Cloud Storage - 静的ファイルをホストします
  • Cloud Functions - Functions as a Service プラットフォーム。
  • Cloud Run - コンテナをホストするサーバーレス ツールであり、アプリケーションにアクセスするための URL を提供します。
  • 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
}

権限を設定

Cloud Build がすべてのサービスをデプロイできるようにする IAM ロールと権限を設定します。

  • Cloud Build サービス アカウントを有効にして Cloud Run にデプロイする
  • Cloud Build サービス アカウントを有効にしてサービス アカウント アクティビティを実行する
  • Cloud Build サービス アカウントを有効にして Cloud Run に公開する
  • Cloud Build サービス アカウントを有効にsite 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 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 アプリケーション用のコンテナをビルドする

以下では、Cloud Build で使用するためにイメージをビルドして Artifact Registry にアップロードしています。

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 にデプロイする

関数に直接 push して有効にします。

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 に push する

コンテナを Artifact Registry に push すると、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 を使用して Storage バケットの変更に応答できるプロジェクト内で実行されるサムネイル作成ソリューションを用意できました。このソリューションを変更または拡張するためのコードもすべて用意されています。