El despliegue de aplicaciones serverless se ha vuelto cada vez m谩s popular debido a su escalabilidad, eficiencia en costos y facilidad de gesti贸n. Amazon Web Services (AWS) Lambda proporciona una poderosa plataforma de computaci贸n sin servidor, mientras que Go (Golang) ofrece un lenguaje de programaci贸n de alto rendimiento y tipado est谩tico.
En este art铆culo, exploraremos c贸mo desplegar aplicaciones basadas en Go en AWS Lambda integrando GitHub Actions y Terraform. Al combinar estas herramientas, los desarrolladores pueden automatizar el proceso de despliegue, simplificar el control de versiones y asegurar pr谩cticas consistentes de infraestructura como c贸digo para sus proyectos sin servidor.
Prerrequisitos
Antes de comenzar, necesitar谩s lo siguiente:
Una cuenta de AWS
Una cuenta de GitHub
AWS CLI instalado y configurado con tus credenciales de AWS (consulta la documentaci贸n de AWS para obtener instrucciones)
// main.go
packagemainimport (
"github.com/aws/aws-lambda-go/events""github.com/aws/aws-lambda-go/lambda")
funchello() (events.APIGatewayProxyResponse, error) {
returnevents.APIGatewayProxyResponse{
Body: "Hello World!",
StatusCode: 200,
}, nil}
funcmain() {
// Hacer que el controlador est茅 disponible para llamadas a procedimientos remotos por AWS Lambda
lambda.Start(hello)
}
Este archivo contiene el c贸digo m铆nimo necesario para crear una aplicaci贸n Go que se pueda desplegar en AWS Lambda. Importa los paquetes events y lambda de la biblioteca aws-lambda-go y define una funci贸n hello que devuelve una respuesta que nuestra API Gateway retornar谩 al cliente. La funci贸n main es el punto de entrada para nuestra aplicaci贸n y llama a la funci贸n hello. La funci贸n lambda.Start inicia el controlador de AWS Lambda1.
Paso 4: Instalar dependencias
Luego, instala las dependencias para tu aplicaci贸n Go:
go get github.com/aws/aws-lambda-go/events
go get github.com/aws/aws-lambda-go/lambda
Esto instalar谩 aws-lambda-go/events, que contiene la estructura APIGatewayProxyResponse, y aws-lambda-go/lambda, que contiene la funci贸n lambda.Start.
Paso 5: Crear el backend remoto
Usaremos S3 como nuestro backend remoto para Terraform. Esto es necesario porque estaremos usando GitHub Actions para desplegar nuestro c贸digo y necesitamos almacenar el estado de Terraform en una ubicaci贸n remota.
NOTA No estaremos creando una tabla DynamoDB para el bloqueo de estado para mantener las cosas simples, pero deber铆as considerar hacer esto si est谩s desplegando a producci贸n. Puedes leer m谩s sobre esto en la documentaci贸n de Terraform.
Para crear el bucket S3 para nuestro backend remoto, usaremos el siguiente comando:
Alternativamente, puedes crear el bucket utilizando la Consola de AWS siguiendo las instrucciones en la documentaci贸n de AWS.
Paso 6: Crear la configuraci贸n de Terraform
Ahora que hemos creado nuestra aplicaci贸n Go y hemos instalado las dependencias, podemos crear la configuraci贸n de Terraform. Usaremos la siguiente configuraci贸n de Terraform para desplegar nuestra aplicaci贸n Go en AWS Lambda:
# backend.tf
terraform {
backend"s3" { # 隆Reemplaza esto con el nombre de tu bucket!
bucket ="<TU_NOMBRE_DE_BUCKET>" key ="go-lambda-test.tfstate" region ="us-east-1" }
}
# main.tf
resource"aws_lambda_function" "go_function" {
filename ="lambda-handler.zip" function_name ="go-lambda-test" handler ="bootstrap" role =aws_iam_role.iam_for_lambda.arn source_code_hash =filebase64sha256("lambda-handler.zip")
runtime ="go1.x"}
data"aws_iam_policy_document" "assume_role" {
statement {
effect ="Allow"principals {
type ="Service" identifiers = ["lambda.amazonaws.com"]
}
actions = ["sts:AssumeRole"]
}
}
resource"aws_iam_role" "iam_for_lambda" {
name ="iam_for_lambda" assume_role_policy =data.aws_iam_policy_document.assume_role.json}# API Gateway
resource"aws_api_gateway_rest_api" "go_api" {
name ="go_api" description ="Esta es mi API para fines de demostraci贸n"}
resource"aws_api_gateway_resource" "go_api_resource" {
rest_api_id =aws_api_gateway_rest_api.go_api.id parent_id =aws_api_gateway_rest_api.go_api.root_resource_id path_part ="test"}
resource"aws_api_gateway_method" "go_api_method" {
rest_api_id =aws_api_gateway_rest_api.go_api.id resource_id =aws_api_gateway_resource.go_api_resource.id http_method ="GET" authorization ="NONE"}
resource"aws_api_gateway_integration" "go_api_integration" {
rest_api_id =aws_api_gateway_rest_api.go_api.id resource_id =aws_api_gateway_resource.go_api_resource.id http_method =aws_api_gateway_method.go_api_method.http_method integration_http_method ="POST" type ="AWS_PROXY" uri =aws_lambda_function.go_function.invoke_arn}
resource"aws_api_gateway_method" "proxy_root" {
rest_api_id =aws_api_gateway_rest_api.go_api.id resource_id =aws_api_gateway_rest_api.go_api.root_resource_id http_method ="ANY" authorization ="NONE"}
resource"aws_api_gateway_integration" "proxy_root_integration" {
rest_api_id =aws_api_gateway_rest_api.go_api.id resource_id =aws_api_gateway_rest_api.go_api.root_resource_id http_method =aws_api_gateway_method.proxy_root.http_method integration_http_method ="POST" type ="AWS_PROXY" uri =aws_lambda_function.go_function.invoke_arn}
resource"aws_api_gateway_deployment" "go_api_deployment" {
depends_on = [
aws_api_gateway_integration.go_api_integration,
aws_api_gateway_integration.proxy_root_integration,
]
rest_api_id =aws_api_gateway_rest_api.go_api.id stage_name ="test"}
resource"aws_lambda_permission" "apigw" {
statement_id ="AllowAPIGatewayInvoke" action ="lambda:InvokeFunction" function_name =aws_lambda_function.go_function.function_name principal ="apigateway.amazonaws.com" source_arn ="${aws_api_gateway_rest_api.go_api.execution_arn}/*/*"}
Paso 7: Configurar credenciales de AWS para GitHub Actions
Para configurar credenciales de AWS para GitHub Actions, usaremos federaci贸n OIDC. Esta es una forma segura de autenticarse con AWS sin tener que almacenar tus credenciales de AWS en tu repositorio de GitHub.
Necesitaremos seguir los siguientes pasos para configurar credenciales de AWS para GitHub Actions:
Luego, necesitaremos crear un rol IAM para GitHub Actions. Necesitaremos seguir los siguientes pasos para crear un rol IAM para GitHub Actions:
Haz clic en el proveedor que acabas de crear. Deber铆a llamarse “token.actions.githubusercontent.com”.
Haz clic en “Assign role”.
Selecciona “Create a new role” y haz clic en “Next”.
Para “Identity provider”, selecciona “token.actions.githubusercontent.com”.
Para Audience, ingresa sts.amazonaws.com.
Haz clic en “Next: Permissions”.
Selecciona “AmazonS3FullAccess”, “AWSLambdaFullAccess”, “IAMFullAccess”, y “AmazonAPIGatewayAdministrator” y haz clic en “Next: Tags”.
Haz clic en “Next: Review”.
Para “Role name”, ingresa github-actions y haz clic en “Create role”.
Busca el rol que acabas de crear y haz clic en 茅l.
Copia el “ARN” (Deber铆a parecer algo como arn:aws:iam::000000000000:role/github-actions). Lo necesitar谩s en el siguiente paso.
NOTA: Considera usar una pol铆tica IAM m谩s restrictiva para tu rol IAM de GitHub Actions.
Paso 8: Crear el flujo de trabajo de GitHub Actions
Luego, crearemos el flujo de trabajo de GitHub Actions. Usaremos el siguiente flujo de trabajo para desplegar nuestra aplicaci贸n Go en AWS Lambda:
No olvides reemplazar <ROL_IAM> con el ARN del rol IAM que has creado en el paso anterior.
# .github/workflows/deploy.ymlname: 'Deploy'on:
push:
branches: [ "main" ]
pull_request:
workflow_dispatch:
permissions:
id-token: writecontents: readjobs:
terraform:
name: 'Terraform'runs-on: ubuntu-latestenvironment: producci贸ndefaults:
run:
shell: bashsteps:
# Checkout de repositorio al runner de GitHub Actions - name: Checkoutuses: actions/checkout@v3# Configurar credenciales de AWS# Necesitar谩s reemplazar <ROL_IAM> con el ARN del rol IAM que creaste en el paso anterior - name: Configure AWS Credentialsuses: aws-actions/configure-aws-credentials@v2with:
role-to-assume: <ROL_IAM>aws-region: us-east-1 - name: Setup Terraformuses: hashicorp/setup-terraform@v1 - name: Configurar entorno Gouses: actions/setup-go@v4.0.1# Este paso construye la aplicaci贸n Go y crea un archivo zip que contiene el binario# Es importante notar que el binario debe llamarse "bootstrap" - name: Construir aplicaci贸n Gorun: | GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o bootstrap main.go
zip lambda-handler.zip bootstrap# Inicializar un directorio de trabajo de Terraform nuevo o existente creando archivos iniciales, cargando cualquier estado remoto, descargando m贸dulos, etc. - name: Terraform Initrun: terraform init - name: Terraform Formatrun: terraform fmt -check - name: Terraform Planrun: terraform plan -input=false - name: Output ref y event_namerun: | echo ${{github.ref}}
echo ${{github.event_name}}# Al hacer push a "main", construir o cambiar la infraestructura seg煤n los archivos de configuraci贸n de Terraform - name: Terraform Applyif: github.ref == 'refs/heads/main' && github.event_name == 'push'run: terraform apply -auto-approve -input=false - name: Output URL de invocaci贸n de API Gatewayif: github.ref == 'refs/heads/main' && github.event_name == 'push'run: | terraform output api_endpoint
Paso 9: Desplegar la aplicaci贸n Go en AWS Lambda
Ahora que hemos creado el flujo de trabajo de GitHub Actions, podemos subir nuestro c贸digo a GitHub y dejar que GitHub Actions despliegue nuestra aplicaci贸n Go en AWS.
git add .
git commit -m "Desplegar aplicaci贸n Go en AWS Lambda"git push --set-upstream origin main
Puedes ver el flujo de trabajo de GitHub Actions yendo a la pesta帽a “Actions” en tu repositorio de GitHub.
Paso 10: Probar la API
Ahora que hemos desplegado nuestra aplicaci贸n Go en AWS Lambda, podemos obtener la URL de invocaci贸n de API Gateway yendo a la pesta帽a “Actions” en tu repositorio de GitHub y haciendo clic en la 煤ltima ejecuci贸n del flujo de trabajo. Luego, viendo la salida del paso “Output API Gateway invocation URL”.
Si hacemos una solicitud a la URL de invocaci贸n de API Gateway, deber铆amos ver la siguiente respuesta:
Conclusi贸n
En este art铆culo, exploramos c贸mo desplegar aplicaciones basadas en Go en AWS Lambda usando GitHub Actions y Terraform. Al combinar estas herramientas, los desarrolladores pueden automatizar el proceso de despliegue, simplificar el control de versiones y asegurar pr谩cticas consistentes de infraestructura como c贸digo para sus proyectos sin servidor.