Configura una Google Cloud Function con Terraform
Prerrequisitos
- Python 3.7+.
- Google Cloud SDK.
- Terraform.
Introducción
En esta guía crearemos una Cloud Function escrita en Python, usando Terraform. Puedes descargar el código fuente aquí.
Acerca de Google Cloud Functions
Google Cloud Functions es una plataforma de Funciones como Servicios (FaaS). Este tipo de plataformas permite crear funciones que son ejecutadas como respuestas a un evento, por ejemplo, un simple llamado HTTP podría invocar tu función. Uno de los beneficios más grandes es que no hay que hacer provisión de servidores, la plataforma se encarga de instanciar contenedores para ejecutar las funciones. De esta manera se puede reducir el costo ya que solo se cobra por los recursos asignados (CPU y memoria) durante el tiempo de ejecución.
Acerca de Terraform
Terraform es una herramienta que nos permite tener infraestructura como código. Al definir los recursos en archivos de texto, tenemos la facilidad de agregarlos a un sistema de versionamiento, compartirlos y reutilizarlos. Terraform crea un plan de ejecución al aplicar cada cambio y nos muestra en detalle qué modificaciones serán aplicadas y en qué orden.
Crea una cuenta de servicio
Selecciona Create Service Account.
Ingresa “terraform” en Service account name (puede ser cualquier nombre) y da click en Create.
En la siguiente pantalla puedes asignar los permisos para la cuenta. Por motivos de simplicidad, en esta guía utilizaremos los roles “Project → Editor” y “Cloud Functions Admin”. Para producción, asegúrate de solamente asignar los permisos necesarios. Da click en continuar.
Por último, haz click en Done.
Crea una clave de cuenta de servicio
Esta clave permite a Terraform autenticarse en Google Cloud. Guarda esta clave en un lugar seguro y elimínala cuando ya no la necesites.
En la pantalla de Cuenta de Servicio Selecciona Create Key.
En key type, selecciona JSON y da click en Create. Guarda la clave en una ubicación que puedas recordar.
Escribe el código fuente de la función
Crea un directorio de trabajo con el nombre que elijas y agrega un archivo de texto main.py con el siguiente código de ejemplo:
def handler(request):
return 'Hola mundo!'
Crea un archivo zip con el código fuente
Almacenaremos el código fuente en un bucket en Cloud Storage. Para esto deberás crear un archivo zip (source.zip) que incluya main.py. Sin el directorio padre.
| - main.py
En Mac OS puedes ejecutar el siguiente comando en una terminal ubicado en el directorio del proyecto:
$ zip source.zip main.py
Agrega la configuración de Terraform
# Proveedor
provider "google" {
version = "3.5.0"
# Archivo JSON descargado desde la consola
credentials = file("<NAME>.json")
# ID del proyecto en GCP
project = "<PROJECT_ID>" region = "us-central1"
zone = "us-central1-c"
}
# Bucket para almacenar el código fuente
resource "google_storage_bucket" "source_bucket" {
name = "hello-world-source"
location = "us-central1"
}
# Almacenar source.zip al bucket
resource "google_storage_bucket_object" "archive" {
name = "source.zip"
bucket = google_storage_bucket.source_bucket.name
source = "./source.zip"
}
# Cloud Function
resource "google_cloudfunctions_function" "function" {
name = "function-test"
description = "Hola Mundo"
runtime = "python37"
available_memory_mb = 128
source_archive_bucket = google_storage_bucket.source_bucket.name
source_archive_object = google_storage_bucket_object.archive.name
trigger_http = true
entry_point = "handler"
}
# Permiso para invocar la función
resource "google_cloudfunctions_function_iam_member" "invoker" {
project = google_cloudfunctions_function.function.project
region = google_cloudfunctions_function.function.region
cloud_function = google_cloudfunctions_function.function.name
role = "roles/cloudfunctions.invoker"
member = "allUsers"
}
En la línea 6 reemplaza <NAME>
por la ruta del archivo de la clave que descargaste en el paso anterior.
En la línea 9 reemplaza <PROJECT_ID>
por el ID de tu proyecto de Google Cloud. Puedes encontrar esta información en la consola.
Inicializa Terraform
Antes de crear los recursos, Terraform necesita inicializarse. Este proceso creará una carpeta “.terraform” en el directorio actual con los archivos necesarios. Verás en tu consola un mensaje como muestra la imagen.
$ terraform init
Aplica los cambios
En este punto ya podemos indicarle a Terraform que cree los recursos. Para esto ejecuta el siguiente comando, Terraform te mostrará la lista de recursos a crear y te pedirá que confirmes los cambios.
$ terraform apply
Prueba tu función
Ya puedes probar tu función!. Ingresa a la consola de Google Cloud, selecciona tu función y en el tab “Trigger”, verás una URL. Utiliza esta URL para llamar tu función.
Deberías ver algo como esto:
Opcional: Desplegar un cambio en el código de la función
Ya que Terraform solo detecta cambios de infraestructura pero no de código fuente es necesario desplegar los cambios como un paso adicional después de crear los recursos.
- Modifica el código de la función
def handler(request):
return 'Hola América Latina!'
-
Crea el archivo zip y súbelo al bucket
En Mac OS puedes ejecutar para crear el zip:
$ zip source.zip main.py
Para subirlo, simplemente ejecuta:
$ terraform apply
-
Despliega la función
Utilizando el Google Cloud SDK:
$ gcloud functions deploy function-test --entry-point handler --source gs://hello-world-source/source.zip
Destruye los recursos creados
Cuando ya no necesites los recursos Terraform te permite eliminarlos en un solo paso ejecutando:
$ terraform destroy