Storage Event Function App es un directorio de imágenes y un creador de miniaturas. Se compone de los siguientes elementos:
- Una aplicación cliente en la que los usuarios pueden subir imágenes.
- API alojada en contenedor y sitio estático - Golang - Cloud Run
- Almacenamiento - Almacenamiento de archivos - Cloud Storage
- Un procesador de imágenes que crea miniaturas de las imágenes.
- Funciones como servicio (FaaS) - Go - Cloud Functions
- Un flujo de procesamiento de despliegue.
- Despliegue - Cloud Build
Empezar
Haz clic en el siguiente enlace para acceder a una copia del código fuente en Cloud Shell. Una vez allí, con un solo comando se creará una copia de trabajo de la aplicación en tu proyecto.
Ver el código fuente en GitHub
Componentes de la aplicación de funciones de eventos de almacenamiento
La arquitectura de la aplicación de funciones de eventos de almacenamiento utiliza varios productos. A continuación, se enumeran los componentes y se incluye más información sobre ellos, como enlaces a vídeos relacionados, documentación del producto y tutoriales interactivos.Secuencias de comandos
La secuencia de comandos de instalación usa un ejecutable escrito en go
y las herramientas de la CLI de Terraform para tomar un proyecto vacío e instalar la aplicación en él. El resultado debe ser una aplicación que funcione y una URL para la dirección IP de balanceo de carga.
./main.tf
Activación de servicios
Los servicios de Google Cloud están inhabilitados en un proyecto de forma predeterminada. Para usar cualquiera de las soluciones que se indican a continuación, debemos activar lo siguiente:
- Cloud Build: crea imágenes de contenedor y las despliega en Cloud Run
- Cloud Storage: aloja archivos estáticos.
- Cloud Functions: plataforma de funciones como servicio
- Cloud Run: la herramienta sin servidor que alojará el contenedor y proporcionará URLs desde las que acceder a la aplicación.
- Artifact Registry: almacena las imágenes de Docker para usarlas 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
}
Definir permisos
Define los roles y permisos de gestión de identidades y accesos que permiten a Cloud Build desplegar todos los servicios.
- Habilitar la cuenta de servicio de Cloud Build para desplegar en Cloud Run
- Habilitar la cuenta de servicio de Cloud Build para realizar actividades de cuentas de servicio
- Habilitar la cuenta de servicio de Cloud Build para publicar en Cloud Run
- Habilitar la cuenta de servicio de Cloud Build para almacenar contenedores en 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]
}
Crear segmentos de Storage
Crea la ubicación de almacenamiento de las imágenes y miniaturas subidas, y proporciona una ubicación de almacenamiento temporal para la subida 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
}
Crear un repositorio de Artifact Registry
En el siguiente código se describen los parámetros del repositorio de Artifact Registry en el que se almacenan los contenedores.
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]
}
Compilar un contenedor para una aplicación de Cloud Run
Con el siguiente comando se compila una imagen y se sube a Artifact Registry para usarla 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
]
}
Desplegar en Cloud Run
En el siguiente ejemplo se usa Cloud Build para desplegar la aplicación web cliente en 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
}
Desplegar código de función en Cloud Functions
Enviar directamente a las funciones y activarlas.
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
Crear un contenedor de APIs
A continuación, se crea una imagen Docker para la aplicación web.
- name: "gcr.io/cloud-builders/docker"
args: [ "build", "-t", "$_REGION-docker.pkg.dev/$PROJECT_ID/$_BASENAME-app/prod", ".", ]
Enviar el contenedor de la API a Artifact Registry
Al enviar el contenedor a Artifact Registry, Cloud Run puede obtener la imagen y servirla.
- name: "gcr.io/cloud-builders/docker"
args: ["push", "$_REGION-docker.pkg.dev/$PROJECT_ID/$_BASENAME-app/prod"]
Sustituciones
Crea una variable con un valor predeterminado para que estos valores se puedan cambiar en el momento de la implementación.
substitutions:
_REGION: us-central1
_BASENAME: scaler
Conclusión
Ahora tienes una solución para crear miniaturas que se ejecuta en tu proyecto y usa Cloud Functions para responder a los cambios en un segmento de Storage. También tienes todo el código para modificar o ampliar esta solución.