DEV Community

olcortesb for AWS Español

Posted on

🚀 Golang + ⚡ Lambda + 🏗️Terraform

Source: https://olcortesb.hashnode.dev/golang-lambda-terraform

Como siempre por estos caminos estoy hablando de Serverless y sus derivados, en esta ocasión contaré un poco sobre como es desplegar funciones AWS Lambda en Go con Terraform no es complejo, pero tenemos que tener consideraciones.

En este artículo te muestro cómo crear una función Lambda básica en Golang usando el runtime provided.al2023 y por qué es la mejor opción actualmente.

Estructura del proyecto

Aquí Link dejaré el repositorio con el código completo.

00_GST_lambda/ ├── src/  ├── go.mod # Módulo Go  ├── main.go # Código fuente  └── bootstrap # Binario compilado (generado) ├── main.tf # Recursos Terraform ├── variables.tf # Variables configurables ├── outputs.tf # Outputs del módulo ├── providers.tf # Configuración de providers ├── backend.tf # Backend de Terraform └── README.md # Documentación 
Enter fullscreen mode Exit fullscreen mode

El código Go

Primero creamos una función Lambda básica en Go. Lo importante aquí es usar la librería oficial aws-lambda-go:

// main.go package main import ( "github.com/aws/aws-lambda-go/lambda" ) func hello() (string, error) { return "Hello λ!", nil } func main() { // Make the handler available for Remote Procedure Call by AWS Lambda lambda.Start(hello) } 
Enter fullscreen mode Exit fullscreen mode

Y nuestro go.mod debe tener un nombre diferente al de la dependencia:

module lambda-function go 1.23 require github.com/aws/aws-lambda-go v1.49.0 
Enter fullscreen mode Exit fullscreen mode

Importante: El nombre del módulo no puede ser github.com/aws/aws-lambda-go porque entraría en conflicto con la dependencia.

La infraestructura Terraform

Compilación automática

El truco está en usar un data source external que compile automáticamente nuestro código Go:

# Crear archivo ZIP con el código compilado data "external" "build_lambda" { program = ["bash", "-c", "cd src && env GOOS=linux GOARCH=arm64 go build -o bootstrap main.go && echo '{\"filename\":\"bootstrap\"}'"] } data "archive_file" "lambda_zip" { type = "zip" source_file = "${path.module}/src/bootstrap" output_path = "${path.module}/lambda_function.zip" depends_on = [data.external.build_lambda] } 
Enter fullscreen mode Exit fullscreen mode

Clave: El ejecutable debe llamarse bootstrap, no main. El runtime provided.al2023 busca específicamente este nombre.

GST_1

Rol IAM y función Lambda

# Rol IAM para Lambda resource "aws_iam_role" "lambda_role" { name = var.role_name assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = "sts:AssumeRole" Effect = "Allow" Principal = { Service = "lambda.amazonaws.com" } } ] }) } # Función Lambda resource "aws_lambda_function" "go_lambda" { filename = data.archive_file.lambda_zip.output_path function_name = "go-hello-serverless-lambda" role = aws_iam_role.lambda_role.arn handler = "main" runtime = "provided.al2023" architectures = ["arm64"] source_code_hash = data.archive_file.lambda_zip.output_base64sha256 depends_on = [ aws_iam_role_policy_attachment.lambda_basic, data.archive_file.lambda_zip ] } 
Enter fullscreen mode Exit fullscreen mode

🤔 ¿ Por qué usar provided.al2023 en lugar de go1.x?

Si has trabajado con Lambda en Go anteriormente, probablemente usaste el runtime go1.x. Sin embargo, AWS deprecó todos los runtimes nativos de Go en diciembre de 2023.

The Go 1.x managed runtime for Lambda is deprecated If you have functions that use the Go 1.x runtime, you must migrate your functions to provided.al 2023 or provided.al 2. The provided.al 2023 and provided.al 2 runtimes offer several advantages over go1.x, including support for the arm64 architecture (AWS Graviton2 processors), smaller binaries, and slightly faster invoke times.

https://docs.aws.amazon.com/lambda/latest/dg/lambda-golang.html?utm_source=chatgpt.com

Como se ve la recomendación oficial es usar provided.al2023 por estas razones:

  • Soporte ARM64: Arquitectura Graviton2 que es 50% más barata que x86_64

  • Control total: Siempre usas la última versión de Go que necesites

  • Mejor rendimiento: Binario nativo sin overhead del runtime

  • Sin deprecación: AWS no puede deprecar tu versión de Go

Despliegue

# Inicializar Terraform terraform init # Ver plan de despliegue terraform plan # Aplicar cambios terraform apply 
Enter fullscreen mode Exit fullscreen mode

Verificamos el despliegue

En nuestra consola de AWS verificamos que la función se desplegó correctamente:

Podemos ver que:

  • Runtime: provided.al2023

  • Arquitectura: arm64

  • Handler: bootstrap

GST_02

Probando nuestra función Lambda

Para probar la función podemos usar la consola de AWS o el CLI:

aws lambda invoke --function-name go-hello-serverless-lambda response.json cat response.json 
Enter fullscreen mode Exit fullscreen mode

El resultado debería ser:

more response.json # "Hello λ!" 
Enter fullscreen mode Exit fullscreen mode

GST_03

Errores conocidos:

Si ves este error … :

{ "errorType": "Runtime.InvalidEntrypoint", "errorMessage": "Couldn't find valid bootstrap(s): [/var/task/bootstrap /opt/bootstrap]" } 
Enter fullscreen mode Exit fullscreen mode

Es porque el ejecutable no se llama bootstrap. Asegúrate de compilar con:

env GOOS=linux GOARCH=arm64 go build -o bootstrap main.go 
Enter fullscreen mode Exit fullscreen mode

Conclusiones

  • Usar provided.al2023 para funciones Lambda en Go nos da:

  • El proceso de despliegue con Terraform es directo una vez que entiendes los detalles del runtime y la compilación automática.

¡Gracias por leer, saludos!

Referencias

Top comments (0)