Application de fonction d'événement de stockage

Architecture

L'application Storage Event Function est un répertoire d'images et un outil de création de vignettes. Il se compose des éléments suivants:

  • Une application cliente dans laquelle les utilisateurs peuvent importer des images.
    • API hébergée pour les conteneurs et site statique – Golang – Cloud Run
    • Stockage – Stockage de fichiers – Cloud Storage
  • Processeur d'images qui crée des vignettes des images.
    • Functions as a Service – Golang – Cloud Functions
  • Un pipeline de déploiement
    • Déploiement : Cloud Build

Commencer

Cliquez sur le lien suivant pour copier le code source dans Cloud Shell. Une seule commande permet alors de lancer une copie de travail de l'application dans votre projet.

Ouvrir dans Cloud Shell

Afficher le code source sur GitHub


Composants de l'application Storage Event Functions

L'architecture de l'application Storage Event Functions utilise plusieurs produits. Vous trouverez ci-dessous la liste des composants, ainsi que des informations supplémentaires et des liens vers des vidéos associées, de la documentation produit et des tutoriels interactifs.
Vidéo Docs Tutoriels
Cloud Run Cloud Run vous permet d'exécuter des applications dans un conteneur, mais de manière sans serveur, sans avoir à configurer le nombre d'instances, de processeurs ni la mémoire. Importez un conteneur et obtenez une URL.
Cloud Storage Cloud Storage permet le stockage de fichiers et la diffusion publique d'images via HTTP(s).
Cloud Functions Cloud Functions est une plate-forme de services et de fonctions qui vous permet d'écouter les importations de fichiers Cloud Storage et d'exécuter du code pour créer des vignettes de ces fichiers.
Cloud Build Cloud Build est l'outil qui empaquette les conteneurs et les déploie pour qu'ils soient disponibles en tant que services Cloud Run.

Scripts

Le script d'installation utilise un exécutable écrit dans go et les outils de la CLI Terraform pour prendre un projet vide et y installer l'application. Le résultat doit correspondre à une application fonctionnelle et à une URL pour l'adresse IP de l'équilibrage de charge.

./main.tf

Activer les services

Les services Google Cloud sont désactivés par défaut dans les projets. Pour utiliser l'une de ces solutions, nous devons activer les éléments suivants:

  • Cloud Build : crée des images de conteneurs et les déploie sur Cloud Run.
  • Cloud Storage : héberge les fichiers statiques.
  • Cloud Functions : plate-forme Functions as a Service
  • Cloud Run : outil sans serveur qui héberge le conteneur et fournit des URL permettant d'accéder à l'application.
  • Artifact Registry : stocke les images Docker pour les utiliser avec 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
}

Définir des autorisations

Définit les rôles et autorisations IAM permettant à Cloud Build de déployer tous les services.

  • Activer le compte de service Cloud Build pour le déploiement sur Cloud Run
  • Activer le compte de service Cloud Build pour effectuer des activités de compte de service
  • Activer le compte de service Cloud Build pour publier sur Cloud Run
  • Activez le compte de service Cloud Build pour stocker des conteneurs dans 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]
}

Créer des buckets Storage

Il crée l'emplacement de stockage pour les images et les vignettes importées, et fournit un emplacement de stockage temporaire pour l'importation de 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
}

Créer un dépôt Artifact Registry

Le code suivant décrit les paramètres du dépôt Artifact Registry dans lequel les conteneurs sont stockés.

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

Créer un conteneur pour l'application Cloud Run

La commande suivante crée une image et l'importe dans Artifact Registry pour une utilisation avec 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
    ]
}

Déployer une application sur Cloud Run

La commande suivante utilise Cloud Build pour déployer l'application Web cliente sur 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
}

Déployer le code de la fonction dans Cloud Functions

Appuyez directement sur les fonctions et activez-les.

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

Créer un conteneur d'API

La commande suivante crée une image Docker pour l'application Web.

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

Transférer le conteneur d'API vers Artifact Registry

Le transfert du conteneur vers Artifact Registry permet à Cloud Run d'obtenir l'image et de la diffuser.

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

Substitutions

Créez une variable par défaut afin que ces valeurs puissent être modifiées au moment du déploiement.

substitutions:
  _REGION: us-central1
  _BASENAME: scaler

Conclusion

Vous disposez maintenant d'une solution de création de vignettes s'exécutant dans votre projet et utilisant Cloud Functions pour répondre aux modifications dans un bucket de stockage. Vous disposez également de tout le code pour modifier ou étendre cette solution.