App funzione evento di archiviazione

Architettura

L'app di funzione di evento di archiviazione è una directory di immagini e un creator di miniature. È composto dai seguenti componenti:

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

Inizia

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

Apri in Cloud Shell

Visualizza il codice sorgente su GitHub


Componenti dell'app di funzione di evento di archiviazione

L'architettura dell'app di funzione di evento di archiviazione utilizza diversi prodotti. Di seguito sono elencati i componenti, insieme a ulteriori informazioni sul componenti, inclusi 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 contenitore, ma in modo serverless, senza dover configurare il numero di istanze, processori o memoria. Carica un container e ottieni un URL.
Cloud Storage Cloud Storage fornisce archiviazione di file e pubblicazione pubblica di immagini tramite http(s).
Cloud Functions Cloud Functions è una piattaforma Functions as a Service che ti consente di monitorare i caricamenti di file di Cloud Storage ed eseguire 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 usa un eseguibile scritto negli strumenti dell'interfaccia a riga di comando go e Terraform per installare l'applicazione al suo interno in un progetto vuoto. L'output deve essere un'applicazione funzionante e un URL per l'indirizzo IP del bilanciamento del carico.

./main.tf

Attiva i servizi

I servizi Google Cloud sono disabilitati in un progetto per impostazione predefinita. Per utilizzare una qualsiasi delle soluzioni riportate di seguito, 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 ospiterà il contenitore e fornirà gli URL da cui accedere all'applicazione.
  • Artifact Registry: memorizza 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
  • Consenti all'account di servizio Cloud Build di eseguire attività dell'account di servizio
  • Attivare l'account di servizio Cloud Build per la pubblicazione su Cloud Run
  • Abilita l'account di servizio Cloud Build per archiviare 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 la posizione 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 un repository Artifact Registry

Il seguente codice illustra i parametri per 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 un container per l'applicazione Cloud Run

Il seguente comando 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

Di seguito viene utilizzato 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

Crea contenitore API

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

L'invio del contenitore ad Artifact Registry consente a Cloud Run di recuperare l'immagine e di pubblicarla.

- 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 utilizzando Cloud Functions per rispondere ai cambiamenti in un bucket Storage. Hai anche tutto il codice per modificare o estendere questa soluzione