avatar Artículo

Cómo crear aplicaciones serverless con AWS SAM (Serverless Application Model)

SAM (Serverless Application Model) es un framework de código abierto que puedes usar para construir aplicaciones serverless en AWS y te mostraré cómo funciona.

AWS SAM

Guía completa de AWS Serverless Application Model (SAM) para construir, probar y desplegar aplicaciones serverless.

3 articles

In progress

Introducción

Lo primero que hay que entender es la relación entre las aplicaciones serverless y AWS SAM, seguido de una revisión de los conceptos básicos.

Qué es una aplicación serverless

Una aplicación serverless es más que solo una función Lambda. Es una combinación de funciones Lambda, fuentes de eventos, APIs, bases de datos y otros recursos que trabajan juntos para realizar tareas.

Qué es AWS SAM

El AWS Serverless Application Model (AWS SAM) es un framework de código abierto que puedes usar para construir aplicaciones serverless en AWS. SAM es una extensión de AWS CloudFormation pero SAM está optimizado y diseñado específicamente para recursos Serverless.

SAM es la solución IaC específica de AWS para definir y desplegar aplicaciones serverless.

Beneficios de SAM

  • Pruebas y depuración locales
    • Con el aws sam cli puedes ejecutar y probar tus aplicaciones serverless en tu entorno local (montando una imagen docker y ejecutando el código)
  • Extensión de AWS Cloud Formation
    • Obtienes confiabilidad en las capacidades de despliegue
    • Puedes usar la plantilla yaml de SAM con todos los recursos que están disponibles en CloudFormation
  • Configuración de despliegue única
    • Puedes gestionar fácilmente todos tus recursos necesarios en un solo lugar que pertenece al mismo stack
  • Mejores prácticas integradas
    • Puedes definir y desplegar tu Infraestructura como Configuración
      • puedes aplicar revisiones de código
      • puedes habilitar despliegues seguros a través de CodeDeploy
      • puedes habilitar el rastreo usando AWS X-Ray
  • Integración profunda con herramientas de desarrollo
    • AWS Serverless Application Repository: descubre nuevas aplicaciones
    • AWS Cloud9 IDE: Para autoría, pruebas y depuración. He escrito un post sobre Cloud9; puedes encontrarlo aquí
    • CodeBuild, CodeDeploy y CodePipeline: Para construir un pipeline de despliegue
    • AWS CodeStar: Para comenzar con una estructura de proyecto, repositorio de código y un pipeline CI/CD que está configurado automáticamente para ti

Conceptos básicos

Usaremos NodeJS como lenguaje de programación. Sin embargo, como dice AWS en las FAQs, puedes usar AWS SAM para construir aplicaciones serverless que usen cualquier runtime soportado por AWS Lambda.

Para entender la estructura de código de los proyectos SAM, cinco archivos son particularmente importantes:

  • Comunes a todos los lenguajes de programación:

    1. template.yaml: Este archivo contiene la plantilla AWS SAM que define los recursos AWS de tu aplicación.
    2. events/file.json: la carpeta events contiene los eventos de invocación que puedes usar para invocar la función.
  • Depende del lenguaje de programación (en este caso NodeJS), por lo que será diferente en cada caso (pero la idea es la misma):

    1. src/handlers/file.js: la carpeta src contiene el código para la función Lambda de la aplicación.
    2. __tests__/unit/handlers/file.test.js: la carpeta test contiene las pruebas unitarias para el código de la aplicación.
    3. package.json: Este archivo de NodeJS contiene las dependencias de la aplicación y se usa para el sam build. Si estás usando el lenguaje Python en lugar de NodeJS, el archivo será requirements.txt.

Anatomía de la plantilla AWS SAM

Esta es la estructura del template.yaml.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# El AWSTemplateFormatVersion identifica las capacidades de la plantilla
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/format-version-structure.html
AWSTemplateFormatVersion: '2010-09-09'
# Opcional: descripción
Description: >-
  Cualquier texto aquí.
  Multi-línea

# La sección Transform especifica una o más macros que AWS CloudFormation usa para procesar tu plantilla
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/transform-section-structure.html
Transform: AWS::Serverless-2016-10-31  

# Opcional: La sección Globals define propiedades que son comunes a todas tus funciones serverless y APIs
Globals:
  Function:
    Timeout: 3
    MemorySize: 128
    Tracing: Active
    Tags:
      iac: SAM

# Opcional: proporciona información adicional sobre la plantilla
Metadata:
  template metadata

# Opcional: Valores para pasar a tu plantilla en tiempo de ejecución (cuando creas o actualizas un stack).
Parameters:
  set of parameters

# Opcional: Un mapeo de claves y valores asociados que puedes usar para especificar valores de parámetros condicionales, similar a una tabla de búsqueda
Mappings:
  set of mappings

# Opcional: condiciones que controlan si ciertos recursos se crean o si ciertas propiedades de recursos se asignan un valor durante la creación o actualización del stack
Conditions:
  set of conditions

# Resources declara los recursos AWS que quieres incluir en el stack.
# La sección Resources puede contener una combinación de recursos AWS CloudFormation y recursos AWS SAM
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html
Resources:
  set of resources

# Opcional: Los valores que se devuelven cada vez que ves las propiedades de tu stack
Outputs:
  set of outputs

Más información aquí.

Requisitos previos

Construyendo aplicaciones SAM

Comencemos revisando un ejemplo de la aplicación SAM para mostrar algunas opciones sobre lo que podemos hacer aquí.

Te mostraré la parte del archivo template.yaml que afecta al servicio específico.

Es importante recordar que puedes incorporar recursos de CloudFormation en nuestra plantilla SAM. Sin embargo, AWS SAM ofrece recursos específicos que están especialmente diseñados para crear funciones Lambda, API Gateway, AppSync, DynamoDB, Step Functions, entre varios otros servicios. Toda la información relevante se puede encontrar aquí.

Ejemplo de función Lambda

El primer tipo especial, y más importante, es el AWS::Serverless::Function, que debes usar para crear funciones Lambda (más información aquí).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Resources:
  # Cada función Lambda se define por propiedades:
  # https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction

  # Esta es una configuración de función Lambda asociada con el código fuente: hello-from-lambda.js
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: src/handlers/hello-from-lambda.helloFromLambdaHandler
      Runtime: nodejs14.x
      Architectures:
        - x86_64
      MemorySize: 128
      Timeout: 100
      Description: A Lambda function that returns a static string.
      Policies:
        # Dar permiso de ejecución básica de Lambda al helloFromLambda
        - AWSLambdaBasicExecutionRole

Añadiendo un API Gateway

Para añadir el recurso API Gateway puedes usar el tipo específico de AWS::Serverless::Api (más información aquí).

1
2
3
4
5
6
7
8
Resources:
  ...
  BasicAWSApiGateway:
    Type: AWS::Serverless::Api
    Properties:
      Name: Basic Amazon API Gateway resource
      StageName: poc
      ...

También puedes añadir un trigger en la función Lambda actualizando la sección Events:

1
2
3
4
5
6
7
8
9
10
Resources:
  HelloWorldFunction:
    Properties:
      ...
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /
            Method: get

Y debes crear en la carpeta events la definición json del método:

1
2
3
{
    "httpMethod": "GET"
}

Añadiendo un evento programado a la función Lambda

Incluir un evento programado a la función Lambda es bastante similar a añadir una API.

1
2
3
4
5
6
7
8
9
Resources:
  HelloWorldFunction:
    Properties:
      ...
      Events:
        CloudWatchEvent:
          Type: Schedule
          Properties:
            Schedule: cron(0 * * * ? *)

Y debes crear en la carpeta events la definición json de la regla:

1
2
3
4
5
6
7
8
9
10
11
12
{
  "id": "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c",
  "detail-type": "Scheduled Event",
  "source": "aws.events",
  "account": "",
  "time": "1970-01-01T00:00:00Z",
  "region": "us-west-2",
  "resources": [
    "arn:aws:events:us-west-2:xxxxxxxxxxxx:rule/ExampleRule"
  ],
  "detail": {}
}

Añadiendo el recurso SNS topic

En este caso, incluiré la función Lambda como suscriptor de mi SNS topic.

1
2
3
4
5
6
7
8
9
10
11
Resources:
  ...
  SnsTopicAsTriggerOfLambdaFunction:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: !Sub '${ResourcesName}'
      DisplayName : Topic used for trigger the lambda function
      Subscription:
        - Protocol: lambda
          Endpoint: !GetAtt HelloWorldFunction.Arn
      TracingConfig: Active

Guardando una propiedad en el SSM Parameter Store

1
2
3
4
5
6
7
8
Resources:
  ...
  MySnsTopicArnParameter:
      Type: AWS::SSM::Parameter
      Properties:
        Name: /general/sns/topic-test
        Type: String
        Value: !Ref SnsTopicAsTriggerOfLambdaFunction

Más ejemplos

Como puedes ver, puedes añadir cualquier recurso usando el código de CloudFormation habitual dentro del archivo template.yaml.

Recomiendo que ejecutes aws sam init e intentes crear diferentes proyectos desde las plantillas.

Práctica: Creando una nueva aplicación SAM

Para mantenerlo simple, crearemos una aplicación SAM desde una plantilla de inicio rápido usando la función independiente. Sin embargo, podrías probar una plantilla diferente, los pasos a seguir deberían ser los mismos.

El ejemplo de código está disponible en el repositorio de GitHub aquí. Si quieres ver el paso a paso puedes verificar el historial de commits, donde puedes encontrar la evolución de la aplicación a través de los pasos explicados en las siguientes líneas.

Estos son todos los pasos que quiero mostrarte en este artículo:

  • Paso 1: Descargar una aplicación SAM de ejemplo
  • Paso 2 (Opcional): Probar tu aplicación localmente
  • Paso 3 (Opcional): Prueba unitaria
  • Paso 4: Construir tu aplicación
  • Paso 5: Desplegar manualmente tu aplicación con el CLI
  • Paso 6 (Opcional): AWS SAM Accelerate (Preview) - Sync

Paso 1: Descargar una aplicación SAM de ejemplo

El primer paso es crear nuestra aplicación a través de una plantilla de inicio rápido: Standalone function.

Para crear una nueva aplicación desde una plantilla ejecutamos el comando sam init.

1
sam init
Haz clic para ver la salida del comando
  Which template source would you like to use?
  1 - AWS Quick Start Templates
  2 - Custom Template Location
  Choice: > 1

  Choose an AWS Quick Start application template
    1 - Hello World Example
    2 - Data processing
    3 - Hello World Example with Powertools for AWS Lambda
    4 - Multi-step workflow
    5 - Scheduled task
    6 - Standalone function
    7 - Serverless API
    8 - Infrastructure event management
    9 - Lambda Response Streaming
    10 - Serverless Connector Hello World Example
    11 - Multi-step workflow with Connectors
    12 - GraphQLApi Hello World Example
    13 - Full Stack
    14 - Lambda EFS example
    15 - Hello World Example With Powertools for AWS Lambda
    16 - DynamoDB Example
    17 - Machine Learning
  Template: > 6

  Which runtime would you like to use?
    1 - dotnet6
    2 - nodejs20.x
    3 - nodejs18.x
    4 - nodejs16.x
  Runtime: > 2

  Based on your selections, the only Package type available is Zip.
  We will proceed to selecting the Package type as Zip.

Based on your selections, the only dependency manager available is npm.
We will proceed copying the template using npm.

  Project name [sam-app]: > sam-app

      -----------------------
      Generating application:
      -----------------------
      Name: sam-app
      Runtime: nodejs20.x
      Architectures: x86_64
      Dependency Manager: npm
      Application Template: quick-start-from-scratch
      Output Directory: .
      Configuration file: sam-app/samconfig.toml

      Next steps can be found in the README file at sam-app/README.md


  Commands you can use next
  =========================
  [*] Create pipeline: cd sam-app && sam pipeline init --bootstrap
  [*] Validate SAM template: cd sam-app && sam validate
  [*] Test Function in the Cloud: cd sam-app && sam sync --stack-name {stack-name} --watch
  

Al final de los mensajes de la línea de comandos aparece Commands you can use next, donde se sugieren otros comandos del CLI de SAM como los próximos pasos a ejecutar.

Esta es la aplicación básica que se ha creado (solo con una función lambda para facilitar la comprensión):

sam-code-basic

Ten en cuenta que tenemos 4 de los 5 archivos que revisamos antes:

  • src/handlers/hello-from-lambda.js
  • _test_/unit/handlers/hello-from-lambda.test.js
  • template.yaml
  • package.json

No tenemos la carpeta events porque solo creamos una función Lambda simple sin integraciones de eventos

Paso 2 (Opcional): Probar tu aplicación localmente

El CLI de AWS SAM proporciona el comando sam local para ejecutar tu aplicación usando contenedores Docker que simulan el entorno de ejecución de Lambda.

Invoca tu función Lambda ejecutando sam local invoke:

1
sam local invoke
Haz clic para ver la salida del comando
  Invoking src/handlers/hello-from-lambda.helloFromLambdaHandler (nodejs20.x)
  Local image was not found.
  Removing rapid images for repo public.ecr.aws/sam/emulation-nodejs20.x
  Building image.............................................................................................................................................................................................................................................................................
  Using local image: public.ecr.aws/lambda/nodejs:20-rapid-x86_64.

  Mounting /Users/alazaroc/Documents/MyProjects/github/aws/sam/sam-app as /var/task:ro,delegated, inside
  runtime container
  START RequestId: ba22ff8c-02f8-42a7-980d-0f0248ee63bf Version: $LATEST
  2024-01-22T22:11:35.245Z	ae4b9347-e347-4ec0-a7a1-f34a3533ec8b	INFO	Hello from Lambda!
  END RequestId: ae4b9347-e347-4ec0-a7a1-f34a3533ec8b
  REPORT RequestId: ae4b9347-e347-4ec0-a7a1-f34a3533ec8b	Init Duration: 0.06 ms	Duration: 181.07 ms	Billed Duration: 182 ms	Memory Size: 128 MB	Max Memory Used: 128 MB
  "Hello from Lambda!"
  

Recibimos la respuesta "Hello from Lambda!" y más información útil (Duration, Billed Duration, Memory Size o Max Memory Used).

Si tienes más de una función Lambda, debes añadir el nombre que aparece en el archivo template.yaml.

1
sam local invoke "helloFromLambdaFunction"
Haz clic para ver la salida del comando
  Invoking src/handlers/hello-from-lambda.helloFromLambdaHandler (nodejs20.x)
  Local image is up-to-date
  Using local image: public.ecr.aws/lambda/nodejs:20-rapid-x86_64.

  Mounting /Users/alazaroc/Documents/MyProjects/github/aws/sam/sam-app as /var/task:ro,delegated, inside
  runtime container
  START RequestId: 323bbea4-2d41-407d-97b6-8605cbe454c3 Version: $LATEST
  2024-01-22T22:20:25.541Z	9fadbf3c-0c9f-4728-b1a7-4ab96e715172	INFO	Hello from Lambda!
  END RequestId: 9fadbf3c-0c9f-4728-b1a7-4ab96e715172
  REPORT RequestId: 9fadbf3c-0c9f-4728-b1a7-4ab96e715172	Init Duration: 0.05 ms	Duration: 142.91 ms	Billed Duration: 143 ms	Memory Size: 128 MB	Max Memory Used: 128 MB
  "Hello from Lambda!"
  

También puedes probar una API localmente si tu proyecto SAM la incluye.

Debes ejecutar el comando sam local start-api, que inicia un endpoint local que replica tu endpoint de API REST.

Paso 3 (Opcional): Prueba unitaria

Las pruebas se definen en la carpeta __tests__ en este proyecto. Usa npm para instalar el framework de pruebas Jest y ejecutar pruebas unitarias.

1
2
3
npm install
...
npm run test
Haz clic para ver la salida del comando
  > replaced-by-user-input@0.0.1 test
  > node --experimental-vm-modules node_modules/jest/bin/jest.js

    console.info
      Hello from Lambda!

        at helloFromLambdaHandler (src/handlers/hello-from-lambda.mjs:9:13)

  (node:31412) ExperimentalWarning: VM Modules is an experimental feature and might change at any time
  (Use `node --trace-warnings ...` to show where the warning was created)
  PASS  __tests__/unit/handlers/hello-from-lambda.test.mjs
    Test for hello-from-lambda
       Verifies successful response (30 ms)

  Test Suites: 1 passed, 1 total
  Tests:       1 passed, 1 total
  Snapshots:   0 total
  Time:        0.553 s
  Ran all test suites.
  

Paso 4: Construir tu aplicación

El comando sam build construye cualquier dependencia que tenga tu aplicación, y copia el código fuente de tu aplicación a carpetas bajo .aws-sam/build para ser comprimido y subido a Lambda.

1
sam build
Haz clic para ver la salida del comando
  Starting Build use cache
  Manifest file is changed (new hash: 57574ed173cdc6a98b283bd7b00b44ca) or dependency folder
  (.aws-sam/deps/ee51225c-b9b8-433f-ab8b-3821871f820a) is missing for (helloFromLambdaFunction), downloading
  dependencies and copying/building source
  Building codeuri: /Users/alazaroc/Documents/MyProjects/github/aws/sam/sam-app runtime: nodejs20.x metadata:
  {} architecture: x86_64 functions: helloFromLambdaFunction
  Running NodejsNpmBuilder:NpmPack
  Running NodejsNpmBuilder:CopyNpmrcAndLockfile
  Running NodejsNpmBuilder:CopySource
  Running NodejsNpmBuilder:NpmInstall
  Running NodejsNpmBuilder:CleanUp
  Running NodejsNpmBuilder:CopyDependencies
  Running NodejsNpmBuilder:CleanUpNpmrc
  Running NodejsNpmBuilder:LockfileCleanUp
  Running NodejsNpmBuilder:LockfileCleanUp

  Build Succeeded

  Built Artifacts  : .aws-sam/build
  Built Template   : .aws-sam/build/template.yaml

  Commands you can use next
  =========================
  [*] Validate SAM template: sam validate
  [*] Invoke Function: sam local invoke
  [*] Test Function in the Cloud: sam sync --stack-name  --watch
  [*] Deploy: sam deploy --guided
  

Estos son los nuevos archivos de nuestro proyecto SAM:

sam-build-files

Paso 5: Desplegar manualmente tu aplicación con el CLI

Ahora queremos desplegar nuestra aplicación y lo haremos manualmente usando el CLI, aunque en este otro artículo explicaré cómo hacerlo con un pipeline (automáticamente).

Recuerda que AWS SAM usa AWS CloudFormation como el mecanismo de despliegue subyacente.

Como no tenemos un archivo de configuración que contenga todos los valores, vamos a crear uno. Ejecutamos el comando sam deploy --guided que buscará como primer paso si existe un archivo samconfig.toml y si no, el CLI de AWS SAM nos preguntará sobre la información necesaria para desplegar nuestra aplicación.

El comando sam deploy empaquetará y subirá los artefactos de la aplicación al bucket S3, y desplegará la aplicación usando AWS CloudFormation

1
sam deploy --guided
Haz clic para ver la salida del comando
  Configuring SAM deploy
  ======================

    Looking for config file [samconfig.toml] :  Found
    Reading default arguments  :  Success

    Setting default arguments for 'sam deploy'
    =========================================
    Stack Name [sam-app]:
    AWS Region [eu-west-1]:
    #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
    Confirm changes before deploy [Y/n]:
    #SAM needs permission to be able to create roles to connect to the resources in your template
    Allow SAM CLI IAM role creation [Y/n]:
    #Preserves the state of previously provisioned resources when an operation fails
    Disable rollback [y/N]:
    Save arguments to configuration file [Y/n]:
    SAM configuration file [samconfig.toml]:
    SAM configuration environment [default]:

    Looking for resources needed for deployment:

    Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-k2z3x0eqvuxq
    A different default S3 bucket can be set in samconfig.toml and auto resolution of buckets turned off by setting resolve_s3=False

          Parameter "stack_name=sam-app" in [default.deploy.parameters] is defined as a global parameter
  [default.global.parameters].
          This parameter will be only saved under [default.global.parameters] in
  /Users/alazaroc/Documents/MyProjects/github/aws/sam/sam-app/samconfig.toml.

    Saved arguments to config file
    Running 'sam deploy' for future deployments will use the parameters saved above.
    The above parameters can be changed by modifying samconfig.toml
    Learn more about samconfig.toml syntax at
    https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html

    Uploading to sam-app/c20f3d4923fb213486783dd25f269a52  38478 / 38478  (100.00%)

    Deploying with following values
    ===============================
    Stack name                   : sam-app
    Region                       : eu-west-1
    Confirm changeset            : True
    Disable rollback             : False
    Deployment s3 bucket         : aws-sam-cli-managed-default-samclisourcebucket-k2z3x0eqvuxq
    Capabilities                 : ["CAPABILITY_IAM"]
    Parameter overrides          : {}
    Signing Profiles             : {}

  Initiating deployment
  =====================

    Uploading to sam-app/3752a1ab023524618cd64cc55081484c.template  734 / 734  (100.00%)


  Waiting for changeset to be created..

  CloudFormation stack changeset
  -------------------------------------------------------------------------------------------------------------
  Operation                   LogicalResourceId           ResourceType                Replacement
  -------------------------------------------------------------------------------------------------------------
  + Add                       helloFromLambdaFunctionRo   AWS::IAM::Role              N/A
                              le
  + Add                       helloFromLambdaFunction     AWS::Lambda::Function       N/A
  -------------------------------------------------------------------------------------------------------------


  Changeset created successfully. arn:aws:cloudformation:eu-west-1:000000000000:changeSet/samcli-deploy1705962828/ee61a1a2-9083-4029-9ee1-126661b04541


  Previewing CloudFormation changeset before deployment
  ======================================================
  Deploy this changeset? [y/N]: y

  2024-01-22 23:34:17 - Waiting for stack create/update to complete

  CloudFormation events from stack operations (refresh every 5.0 seconds)
  -------------------------------------------------------------------------------------------------------------
  ResourceStatus              ResourceType                LogicalResourceId           ResourceStatusReason
  -------------------------------------------------------------------------------------------------------------
  CREATE_IN_PROGRESS          AWS::CloudFormation::Stac   sam-app                     User Initiated
                              k
  CREATE_IN_PROGRESS          AWS::IAM::Role              helloFromLambdaFunctionRo   -
                                                          le
  CREATE_IN_PROGRESS          AWS::IAM::Role              helloFromLambdaFunctionRo   Resource creation
                                                          le                          Initiated
  CREATE_COMPLETE             AWS::IAM::Role              helloFromLambdaFunctionRo   -
                                                          le
  CREATE_IN_PROGRESS          AWS::Lambda::Function       helloFromLambdaFunction     -
  CREATE_IN_PROGRESS          AWS::Lambda::Function       helloFromLambdaFunction     Resource creation
                                                                                      Initiated
  CREATE_COMPLETE             AWS::Lambda::Function       helloFromLambdaFunction     -
  CREATE_COMPLETE             AWS::CloudFormation::Stac   sam-app                     -
                              k
  -------------------------------------------------------------------------------------------------------------


  Successfully created/updated stack - sam-app in eu-west-1
  

Recuerda que el comando ejecutado creará el archivo samconfig.toml en nuestro proyecto para guardar la configuración de despliegue y poder repetirla sin configuración.

sam-deploy-guided-3

De ahora en adelante, para desplegar nuestro proyecto SAM solo necesitamos ejecutar el comando sam deploy, así que lo ejecutamos pero si no tenemos cambios, el despliegue fallará:

1
sam deploy
Haz clic para ver la salida del comando
      Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-k2z3x0eqvuxq
      A different default S3 bucket can be set in samconfig.toml
      Or by specifying --s3-bucket explicitly.
  File with same data already exists at sam-app/c20f3d4923fb213486783dd25f269a52, skipping upload

    Deploying with following values
    ===============================
    Stack name                   : sam-app
    Region                       : eu-west-1
    Confirm changeset            : True
    Disable rollback             : False
    Deployment s3 bucket         : aws-sam-cli-managed-default-samclisourcebucket-k2z3x0eqvuxq
    Capabilities                 : ["CAPABILITY_IAM"]
    Parameter overrides          : {}
    Signing Profiles             : {}

  Initiating deployment
  =====================

  File with same data already exists at sam-app/3752a1ab023524618cd64cc55081484c.template, skipping upload


  Waiting for changeset to be created..

  Error: No changes to deploy. Stack sam-app is up to date
  

Paso 6 (Opcional): AWS SAM Sync

Ya hemos desplegado nuestra aplicación en la nube y es posible que quieras sincronizar los cambios, es decir, desplegar los cambios en tiempo real cuando guardamos los cambios (sin ejecutar el comando deploy).

El comando sam sync sincroniza los cambios de tu aplicación local con la nube de AWS. Usa sync para construir, empaquetar y desplegar cambios en tu entorno de desarrollo mientras iteras en tu aplicación. Como mejor práctica, ejecuta sam sync después de terminar de iterar en tu aplicación para sincronizar cambios con tu stack de AWS CloudFormation.

Ten cuidado si usas esta funcionalidad.

Primero está en preview y también como verás en las siguientes líneas en la consola: “El CLI de SAM usará las APIs de AWS Lambda, Amazon API Gateway y AWS StepFunctions para subir tu código sin realizar un despliegue de CloudFormation. Esto causará drift en tu stack de CloudFormation.”

El comando sync solo debe usarse contra un stack de desarrollo.

1
sam sync --stack-name sam-app --watch
Haz clic para ver la salida del comando
  The SAM CLI will use the AWS Lambda, Amazon API Gateway, and AWS StepFunctions APIs to upload your code without
  performing a CloudFormation deployment. This will cause drift in your CloudFormation stack.
  **The sync command should only be used against a development stack**.

  Confirm that you are synchronizing a development stack.

  Enter Y to proceed with the command, or enter N to cancel:
  [Y/n]:
  Queued infra sync. Waiting for in progress code syncs to complete...
  Starting infra sync.
  Manifest is not changed for (helloFromLambdaFunction), running incremental build
  Building codeuri: /Users/alazaroc/Documents/MyProjects/github/aws/sam/sam-app runtime: nodejs20.x
  metadata: {} architecture: x86_64 functions: helloFromLambdaFunction
  Running NodejsNpmBuilder:NpmPack
  Running NodejsNpmBuilder:CopyNpmrcAndLockfile
  Running NodejsNpmBuilder:CopySource
  Running NodejsNpmBuilder:CleanUpNpmrc
  Running NodejsNpmBuilder:LockfileCleanUp
  Running NodejsNpmBuilder:LockfileCleanUp

  Build Succeeded

  Successfully packaged artifacts and wrote output template to file /var/folders/wq/bz6xngtx5h3f5gf8py3kf28c0000gn/T/tmppcg60qga.
  Execute the following command to deploy the packaged template
  sam deploy --template-file /var/folders/wq/bz6xngtx5h3f5gf8py3kf28c0000gn/T/tmppcg60qga --stack-name <YOUR STACK NAME>


    Deploying with following values
    ===============================
    Stack name                   : sam-app
    Region                       : eu-west-1
    Disable rollback             : False
    Deployment s3 bucket         : aws-sam-cli-managed-default-samclisourcebucket-k2z3x0eqvuxq
    Capabilities                 : ["CAPABILITY_NAMED_IAM", "CAPABILITY_AUTO_EXPAND"]
    Parameter overrides          : {}
    Signing Profiles             : null

  Initiating deployment
  =====================


  2024-01-22 23:43:31 - Waiting for stack create/update to complete

  CloudFormation events from stack operations (refresh every 0.5 seconds)
  ---------------------------------------------------------------------------------------------------------
  ResourceStatus             ResourceType               LogicalResourceId          ResourceStatusReason
  ---------------------------------------------------------------------------------------------------------
  UPDATE_IN_PROGRESS         AWS::CloudFormation::Sta   sam-app                    User Initiated
                            ck
  UPDATE_IN_PROGRESS         AWS::CloudFormation::Sta   sam-app                    Transformation succeeded
                            ck
  CREATE_IN_PROGRESS         AWS::CloudFormation::Sta   AwsSamAutoDependencyLaye   -
                            ck                         rNestedStack
  CREATE_IN_PROGRESS         AWS::CloudFormation::Sta   AwsSamAutoDependencyLaye   Resource creation
                            ck                         rNestedStack               Initiated
  CREATE_COMPLETE            AWS::CloudFormation::Sta   AwsSamAutoDependencyLaye   -
                            ck                         rNestedStack
  UPDATE_IN_PROGRESS         AWS::Lambda::Function      helloFromLambdaFunction    -
  UPDATE_COMPLETE            AWS::Lambda::Function      helloFromLambdaFunction    -
  UPDATE_COMPLETE_CLEANUP_   AWS::CloudFormation::Sta   sam-app                    -
  IN_PROGRESS                ck
  UPDATE_COMPLETE            AWS::CloudFormation::Sta   sam-app                    -
                            ck
  ---------------------------------------------------------------------------------------------------------


  Stack update succeeded. Sync infra completed.

  Infra sync completed.
  

La consola sigue escuchando cambios y si cambiamos nuestro código lambda y lo guardamos:

sam-sync-lambda

La consola se actualizará automáticamente de la siguiente manera:

1
2
3
4
5
6
7
8
9
10
11
Syncing Lambda Function helloFromLambdaFunction...
Manifest is not changed for (helloFromLambdaFunction), running incremental build
Building codeuri: /Users/alazaroc/Documents/MyProjects/github/aws/sam/sam-app runtime: nodejs20.x
metadata: {} architecture: x86_64 functions: helloFromLambdaFunction
 Running NodejsNpmBuilder:NpmPack
 Running NodejsNpmBuilder:CopyNpmrcAndLockfile
 Running NodejsNpmBuilder:CopySource
 Running NodejsNpmBuilder:CleanUpNpmrc
 Running NodejsNpmBuilder:LockfileCleanUp
 Running NodejsNpmBuilder:LockfileCleanUp
Finished syncing Lambda Function helloFromLambdaFunction.

Cuando lo detengas (control + C) en la consola aparecerá:

1
2
^CShutting down sync watch...
Sync watch stopped.

Cuando ejecutaste el comando sync, se creó un stack anidado asociado con tu stack principal (sam-app):

sam-nested-stack

Y cuando la consola deja de estar sincronizada, este stack anidado NO se elimina.

¿Cómo eliminar el stack anidado creado con el comando sync?

Tienes que ejecutar el comando sam deploy nuevamente y se eliminará:

1
sam deploy
Haz clic para ver la salida del comando
        Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-k2z3x0eqvuxq
        A different default S3 bucket can be set in samconfig.toml
        Or by specifying --s3-bucket explicitly.
    File with same data already exists at sam-app/c20f3d4923fb213486783dd25f269a52, skipping upload

      Deploying with following values
      ===============================
      Stack name                   : sam-app
      Region                       : eu-west-1
      Confirm changeset            : True
      Disable rollback             : False
      Deployment s3 bucket         : aws-sam-cli-managed-default-samclisourcebucket-k2z3x0eqvuxq
      Capabilities                 : ["CAPABILITY_IAM"]
      Parameter overrides          : {}
      Signing Profiles             : {}

    Initiating deployment
    =====================

    File with same data already exists at sam-app/3752a1ab023524618cd64cc55081484c.template, skipping upload


    Waiting for changeset to be created..

    CloudFormation stack changeset
    ---------------------------------------------------------------------------------------------------------
    Operation                  LogicalResourceId          ResourceType               Replacement
    ---------------------------------------------------------------------------------------------------------
    * Modify                   helloFromLambdaFunction    AWS::Lambda::Function      False
    - Delete                   AwsSamAutoDependencyLaye   AWS::CloudFormation::Sta   N/A
                              rNestedStack               ck
    ---------------------------------------------------------------------------------------------------------


    Changeset created successfully. arn:aws:cloudformation:eu-west-1:000000000000:changeSet/samcli-deploy1705963790/6b5464b9-0b8e-44c2-93c0-8e0f509c9110


    Previewing CloudFormation changeset before deployment
    ======================================================
    Deploy this changeset? [y/N]: y

    2024-01-22 23:50:02 - Waiting for stack create/update to complete

    CloudFormation events from stack operations (refresh every 5.0 seconds)
    ---------------------------------------------------------------------------------------------------------
    ResourceStatus             ResourceType               LogicalResourceId          ResourceStatusReason
    ---------------------------------------------------------------------------------------------------------
    UPDATE_IN_PROGRESS         AWS::CloudFormation::Sta   sam-app                    User Initiated
                              ck
    UPDATE_IN_PROGRESS         AWS::Lambda::Function      helloFromLambdaFunction    -
    UPDATE_COMPLETE            AWS::Lambda::Function      helloFromLambdaFunction    -
    UPDATE_COMPLETE_CLEANUP_   AWS::CloudFormation::Sta   sam-app                    -
    IN_PROGRESS                ck
    DELETE_IN_PROGRESS         AWS::CloudFormation::Sta   AwsSamAutoDependencyLaye   -
                              ck                         rNestedStack
    DELETE_COMPLETE            AWS::CloudFormation::Sta   AwsSamAutoDependencyLaye   -
                              ck                         rNestedStack
    UPDATE_COMPLETE            AWS::CloudFormation::Sta   sam-app                    -
                              ck
    ---------------------------------------------------------------------------------------------------------


    Successfully created/updated stack - sam-app in eu-west-1
  

Paso 7: Limpieza

Si seguiste este tutorial solo tendrás un stack en nuestra cuenta AWS, así que puedes ejecutar el comando sam delete (que elimina el stack principal: sam-app).

1
sam delete
Haz clic para ver la salida del comando
    Are you sure you want to delete the stack sam-app in the region eu-west-1 ? [y/N]: y
    Are you sure you want to delete the folder sam-app in S3 which contains the artifacts? [y/N]: y
          - Deleting S3 object with key sam-app/c20f3d4923fb213486783dd25f269a52
          - Deleting S3 object with key sam-app/3752a1ab023524618cd64cc55081484c.template
    - Deleting Cloudformation stack sam-app

  Deleted successfully
  

Próximos pasos

Lectura adicional:

Espero escuchar tus pensamientos y experiencias con AWS SAM. Siéntete libre de compartirlos en los comentarios a continuación. ¡Feliz codificación!

Este artículo está licenciado bajo CC BY 4.0 por el autor.