App funzioni eventi Storage

Architettura

L'app Storage Event Function è una directory di immagini e la creazione di miniature. È composto dai seguenti componenti:

  • Un'applicazione client in cui gli utenti possono caricare immagini.
    • Sito statico e API in hosting in container - Golang - Cloud Run
    • Archiviazione - Archiviazione di file - Cloud Storage
  • Un processore di immagini che crea le miniature delle immagini.
    • Functions as a Service - Golang - Cloud Functions
  • Una pipeline di deployment.
    • Deployment - Cloud Build

Inizia

Fai clic sul link seguente a una copia del codice sorgente in Cloud Shell. Da lì, un singolo comando avvierà una copia funzionante dell'applicazione nel tuo progetto.

Apri in Cloud Shell

Visualizza il codice sorgente su GitHub


Componenti app delle funzioni eventi di archiviazione

L'architettura dell'app Storage Event Function utilizza diversi prodotti. Di seguito sono elencati i componenti, insieme a ulteriori informazioni sui componenti, tra cui link a video correlati, documentazione del prodotto e procedure dettagliate interattive.
Video Documenti Procedure dettagliate
Cloud Run Cloud Run ti consente di eseguire applicazioni in un container, ma in modo serverless, senza dover configurare il numero di istanze, processori o memoria. Carica un contenitore, recupera un URL.
Cloud Storage Cloud Storage offre archiviazione di file e pubblicazione pubblica di immagini su http.
Cloud Functions Cloud Functions è una piattaforma di servizi che consente di ascoltare i caricamenti di file di Cloud Storage ed eseguire il codice per crearne le miniature.
Cloud Build Cloud Build è lo strumento che pacchettizza i container e ne esegue il deployment in modo che siano disponibili come servizi Cloud Run.

Script

Lo script di installazione utilizza un eseguibile scritto in go e negli strumenti dell'interfaccia a riga di comando di Terraform per acquisire un progetto vuoto e installare l'applicazione al suo interno. L'output deve essere un'applicazione funzionante e un URL per l'indirizzo IP di bilanciamento del carico.

./main.tf

Abilitazione dei servizi

I servizi Google Cloud sono disabilitati in un progetto per impostazione predefinita. Per utilizzare una qualsiasi delle soluzioni qui riportate, dobbiamo attivare quanto segue:

  • Cloud Build: crea immagini container ed esegue il deployment in Cloud Run
  • Cloud Storage: ospita file statici
  • Cloud Functions - Piattaforma Functions as a Service
  • Cloud Run: lo strumento serverless che ospita il container e fornisce gli URL da cui accedere all'applicazione.
  • Artifact Registry: archivia le immagini Docker da utilizzare con 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
}

Imposta autorizzazioni

Imposta i ruoli e le autorizzazioni IAM che consentono a Cloud Build di eseguire il deployment di tutti i servizi.

  • Abilita l'account di servizio Cloud Build per eseguire il deployment in Cloud Run
  • Abilita l'account di servizio Cloud Build per eseguire attività dell'account di servizio
  • Abilita l'account di servizio Cloud Build per pubblicare in Cloud Run
  • Abilita l'account di servizio Cloud Build per archiviare i container in 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]
}

Creazione di bucket di archiviazione

Crea il percorso di archiviazione per le immagini e le miniature caricate e fornisce una posizione di archiviazione temporanea per il caricamento di 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
}

Crea repository Artifact Registry

Il codice seguente descrive i parametri per il repository Artifact Registry in cui sono archiviati i container.

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]
}

Crea container per l'applicazione Cloud Run

Quanto segue crea un'immagine e la carica in Artifact Registry per l'utilizzo con 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
    ]
}

esegui il deployment in Cloud Run

Quanto segue utilizza Cloud Build per eseguire il deployment dell'app web client in 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
}

Esegui il deployment del codice della funzione in Cloud Functions

Esegui il push direttamente alle funzioni e attivale.

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

Container API di build

Di seguito viene creata un'immagine Docker per l'app web.

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

Esegui il push del container API in Artifact Registry

Il push del container ad Artifact Registry consente a Cloud Run di ottenere l'immagine e gestirla.

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

Sostituzioni

Crea una variabile con un valore predefinito in modo che questi valori possano essere modificati al momento del deployment.

substitutions:
  _REGION: us-central1
  _BASENAME: scaler

Conclusione

Ora hai una soluzione per la creazione di miniature in esecuzione nel tuo progetto utilizzando Cloud Functions per rispondere alle modifiche in un bucket di archiviazione. Hai anche tutto il codice per modificare o estendere questa soluzione