Despliegue de Hugo con AWS CodeBuild en Lambda Compute
Introducción
En esta receta, revisaremos cómo desplegar un sitio estático de Hugo utilizando AWS CodeBuild en AWS Lambda compute. AWS Lambda compute ofrece tiempos de inicio optimizados y escalado automático para compilaciones más rápidas. Sin embargo, hay algunas limitaciones a tener en cuenta.
Utilizaremos AWS CodeBuild para compilar el sitio de Hugo, desplegarlo en un bucket de S3 e invalidar la caché de CloudFront. GitHub se utilizará como repositorio fuente para el sitio de Hugo.
Pre-requisitos
Antes de comenzar, asegúrate de tener lo siguiente:
- El código fuente de tu sitio Hugo en GitHub.
- Tu sitio Hugo ya está alojado en AWS S3 y CloudFront. Si no es así, sigue la receta Hospedando Hugo en AWS S3 y CloudFront para configurarlo.
Paso 1: Crear un nuevo rol IAM para el proyecto CodeBuild
Necesitamos crear un nuevo rol IAM que será utilizado por el proyecto CodeBuild para “sincronizar” el bucket de S3 e “invalidar” la distribución de CloudFront.
Crear una nueva política
- Ve a la consola de AWS IAM: Políticas.
- Haz clic en el botón
Create policy
(Crear política). - Haz clic en la pestaña
JSON
y pega el siguiente documento de política:
YOUR_BUCKET_NAME
, YOUR_ACCOUNT_ID
, y YOUR_DISTRIBUTION_ID
con tus valores.{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:GetBucketAcl",
"s3:GetBucketLocation",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::YOUR_BUCKET_NAME",
"arn:aws:s3:::YOUR_BUCKET_NAME/*"
]
},
{
"Effect": "Allow",
"Action": [
"cloudfront:CreateInvalidation"
],
"Resource": [
"arn:aws:cloudfront::YOUR_ACCOUNT_ID:distribution/YOUR_DISTRIBUTION_ID"
]
}
]
}
- Haz clic en el botón
Next
(Siguiente). - Ingresa el nombre y la descripción de la política.
- Haz clic en el botón
Create policy
(Crear política).
Crear un nuevo rol
- Regresa a la consola de AWS IAM: Roles.
- Haz clic en el botón
Create Role
(Crear rol). - Selecciona
AWS service
como la entidad de confianza. - Elige
CodeBuild
como el servicio que utilizará este rol. - Haz clic en el botón
Next: Add Permissions
(Siguiente: Agregar permisos). - Busca y marca la casilla junto a la política que creaste anteriormente.
- Haz clic en el botón
Next: Name, review and create
(Siguiente: Nombre, revisión y creación). - Ingresa el nombre y la descripción del rol.
- Haz clic en el botón
Create role
(Crear rol).
Ahora tienes un nuevo rol IAM que puede ser utilizado por el proyecto de CodeBuild.
Paso 2: Crear un nuevo proyecto de CodeBuild
Vamos a crear un nuevo proyecto de CodeBuild que construirá e implementará nuestro sitio en cada envío al repositorio de GitHub.
Ve a la consola de AWS CodeBuild y haz clic en el botón Create build project
(Crear proyecto de compilación).
Configuración del proyecto
- Ingresa el nombre y la descripción del proyecto.
- Restringe el número de compilaciones concurrentes que este proyecto puede iniciar a
1
.
Origen
- Selecciona
GitHub
como proveedor de origen. - Haz clic en el botón
Connect to GitHub
y autoriza a AWS para acceder a tus repositorios de GitHub. - Selecciona tu repositorio y la rama.
Entorno
- Selecciona
Managed Image
como la imagen de entorno. - Elige
Lambda
como tipo de cómputo. - Sistema operativo:
Amazon Linux
(no tienes otras opciones aquí). - Runtime:
Golang
. - Imagen:
aws/codebuild/amazonlinux-aarch64-lambda-standard:go1.21
o la más reciente disponible. - Versión de imagen:
Always use the latest image for this runtime version
. - Rol de servicio:
Existing service role
. - ARN del rol: elige el rol que creaste en el paso anterior.
- Marca la casilla
Allow AWS CodeBuild to modify this service role so it can be used with this build project
(Permitir a AWS CodeBuild modificar este rol de servicio para que pueda ser utilizado con este proyecto de compilación).
Buildspec
Elige Insert build commands
y pega el siguiente buildspec:
yum
o rpm
debido a que requieren acceso de root. Por lo tanto, necesitamos descargar y extraer manualmente Hugo. Para más información, consulta las Limitaciones del cómputo Lambda de AWS.YOUR_BUCKET_NAME
, YOUR_REGION
, y YOUR_DISTRIBUTION_ID
con tus valores.version: 0.2
phases:
install:
commands:
# Download and extract Hugo
- curl -Ls https://github.com/gohugoio/hugo/releases/download/v0.127.0/hugo_extended_0.127.0_linux-arm64.tar.gz -o /tmp/hugo.tar.gz
- mkdir /tmp/hugo_0.127.0
- tar xf /tmp/hugo.tar.gz -C /tmp/hugo_0.127.0
- /tmp/hugo_0.127.0/hugo version
build:
commands:
# Build the site using Hugo
- /tmp/hugo_0.127.0/hugo --minify --gc
post_build:
commands:
# Sync the Hugo build public folder with S3 bucket
- aws s3 sync public/ s3://YOUR_BUCKET_NAME --region YOUR_REGION --delete
# Invalidate CloudFront cache
- aws cloudfront create-invalidation --distribution-id YOUR_DISTRIBUTION_ID --paths '/*'
Artefactos
Selecciona No artifacts
como tipo de artefacto de salida, ya que estamos desplegando el sitio a S3 dentro del buildspec.
Registros
Opcionalmente, puedes configurar registros de CloudWatch para el proyecto de compilación. Esto te ayudará a depurar el proceso de compilación.
Paso 3: Activar la compilación
Ahora puedes activar la compilación al hacer un nuevo envío (commit) al repositorio de GitHub. El proyecto de CodeBuild iniciará automáticamente el proceso de compilación y desplegará el sitio en el bucket de S3. Alternativamente, puedes iniciar manualmente la compilación presionando el botón Start build
en la consola de CodeBuild.
¡Eso es todo! Has desplegado exitosamente tu sitio Hugo utilizando AWS CodeBuild en un entorno Lambda.
Despliegue con CloudFormation
Si prefieres desplegar el proyecto de CodeBuild usando CloudFormation, puedes utilizar la plantilla siguiente. Está parametrizada con los valores requeridos.
AWSTemplateFormatVersion: '2010-09-09'
Description: CodeBuild project for Hugo site deployment
Parameters:
ProjectName:
Type: String
Description: CodeBuild project name
Default: HugoSiteBuild
SiteBucketName:
Type: String
Description: Site S3 bucket name
DistributionId:
Type: String
Description: CloudFront distribution ID
Region:
Type: String
Description: AWS region
HugoVersion:
Type: String
Description: Hugo version
Default: 0.127.0
GitHubRepo:
Type: String
Description: GitHub repository URL
Resources:
ServiceRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: codebuild.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: CodeBuildServiceRolePolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- !Sub arn:aws:logs:${Region}:${AWS::AccountId}:log-group:/aws/codebuild/${ProjectName}
- !Sub arn:aws:logs:${Region}:${AWS::AccountId}:log-group:/aws/codebuild/${ProjectName}:*
- PolicyName: DeploySiteCodeBuildPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- s3:PutObject
- s3:GetObject
- s3:DeleteObject
- s3:GetBucketAcl
- s3:GetBucketLocation
- s3:ListBucket
Resource:
- !Sub arn:aws:s3:::${SiteBucketName}
- !Sub arn:aws:s3:::${SiteBucketName}/*
- Effect: Allow
Action:
- cloudfront:CreateInvalidation
Resource:
- !Sub arn:aws:cloudfront::${AWS::AccountId}:distribution/${DistributionId}
CodeBuildProject:
Type: AWS::CodeBuild::Project
Properties:
Name: !Ref ProjectName
Description: Build and deploy Hugo site
ConcurrentBuildLimit: 1
Environment:
Type: ARM_LAMBDA_CONTAINER
ComputeType: BUILD_LAMBDA_1GB
Image: aws/codebuild/amazonlinux-aarch64-lambda-standard:go1.21
ServiceRole: !GetAtt ServiceRole.Arn
Source:
Type: GITHUB
BuildSpec: !Sub |
version: 0.2
phases:
install:
commands:
- curl -Ls https://github.com/gohugoio/hugo/releases/download/v${HugoVersion}/hugo_extended_${HugoVersion}_linux-arm64.tar.gz -o /tmp/hugo.tar.gz
- mkdir /tmp/hugo_${HugoVersion}
- tar xf /tmp/hugo.tar.gz -C /tmp/hugo_${HugoVersion}
- /tmp/hugo_${HugoVersion}/hugo version
build:
commands:
- /tmp/hugo_${HugoVersion}/hugo --minify --gc
post_build:
commands:
- aws s3 sync public/ s3://${SiteBucketName} --region us-east-1 --delete
- aws cloudfront create-invalidation --distribution-id ${DistributionId} --paths '/*'
Location: !Ref GitHubRepo
Artifacts:
Type: NO_ARTIFACTS
Triggers:
Webhook: true
BuildType: BUILD
FilterGroups:
- - Type: EVENT
Pattern: PUSH
LogsConfig:
CloudWatchLogs:
Status: ENABLED
GroupName: !Sub /aws/codebuild/${ProjectName}
Conclusión
En esta receta, aprendimos cómo desplegar un sitio estático de Hugo utilizando AWS CodeBuild en un entorno Lambda, que es una forma más económica, fácil y rápida en comparación con el entorno tradicional de EC2. También escribimos todos los pasos en una plantilla de CloudFormation para facilitar el despliegue y la gestión.