serverless-application-model Documentation

The AWS Serverless Application Model (AWS SAM) transform is a AWS CloudFormation macro that transforms SAM templates into CloudFormation templates.

RAW Doc

File: README.md

AWS SAM transform





The AWS Serverless Application Model (AWS SAM) transform is a AWS CloudFormation macro that transforms SAM templates into CloudFormation templates.

To use the SAM transform, add AWS::Serverless-2016-10-31 to the Transform section of your CloudFormation template.

Benefits of using the SAM transform include:

  • Built-in best practices and sane defaults.
  • Local testing and debugging with the AWS SAM CLI.
  • Extension of the CloudFormation template syntax.

Getting started

Save the following as template.yaml:

yaml
Transform: AWS::Serverless-2016-10-31
Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      Runtime: nodejs24.x
      Handler: index.handler
      InlineCode: |
        exports.handler = async (event) => {
          console.log(event);
        }

And deploy it with the SAM CLI:

bash
sam sync --stack-name sam-app

The AWS::Serverless::Function resource will create a AWS Lambda function that logs events it receives.

Under the hood, the template is transformed into the JSON equivalent of the following CloudFormation template:

yaml
Resources:
  MyFunction:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        ZipFile: |
          exports.handler = async (event) => {
            console.log(event);
          }
      Handler: index.handler
      Role: !GetAtt MyFunctionRole.Arn
      Runtime: nodejs24.x
      Tags:
        - Key: lambda:createdBy
          Value: SAM
  MyFunctionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Tags:
        - Key: lambda:createdBy
          Value: SAM

For a more thorough introduction, see the this tutorial in the Developer Guide.

Contributing

Setting up development environment

You'll need to have Python 3.8+ installed.

Create a virtual environment:

bash
python3 -m venv .venv
source .venv/bin/activate

Set up dependencies:

bash
make init

Run tests:

bash
make pr

See DEVELOPMENT_GUIDE.md for further development instructions, and CONTRIBUTING.md for the contributing guidelines.

Getting help

The best way to interact with the team is through GitHub. You can either create an issue or start a discussion.

You can also join the #samdev channel on Slack.

Learn more

Workshops and tutorials

Documentation


File: docs/internals/generated_resources.rst

CloudFormation Resources Generated By SAM

.. contents::
:local:
:backlinks: none

When you create a Serverless Function or a Serverless API, SAM will create additional AWS resources to wire everything up.
For example, when you create a AWS::Serverless::Function, SAM will create a Lambda Function resource
along with an IAM Role resource to give appropriate permissions for your function. This document describes all
such generated resources, how they are named, and how to refer to them in your SAM template.

AWS::Serverless::Function

Given a Function defined as follows:

.. code:: yaml

MyFunction:
Type: AWS::Serverless::Function
Properties:
...

Following resources will be generated:

================================== ================================
CloudFormation Resource Type Logical ID
================================== ================================
AWS::Lambda::Function MyFunction
AWS::IAM::Role MyFunction\ Role
================================== ================================

With AutoPublishAlias Property

text
Example:

.. code:: yaml

  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      ...
      AutoPublishAlias: live
      ...


Additional generated resources:

================================== ================================
CloudFormation Resource Type       Logical ID 
================================== ================================
AWS::Lambda::Version               MyFunction\ **Version**\ *SHA* (10 digits of SHA256 of CodeUri)
AWS::Lambda::Alias                 MyFunction\ **Alias**\ *live*
================================== ================================


With DeploymentPreference Property

Example:

.. code:: yaml

MyFunction:
Type: AWS::Serverless::Function
Properties:
...
AutoPublishAlias: live
DeploymentPreference:
Type: Linear10PercentEvery10Minutes
Role: "arn"
...

Additional generated resources:

================================== ================================
CloudFormation Resource Type Logical ID
================================== ================================
AWS::CodeDeploy::Application ServerlessDeploymentApplication (only one per stack)
AWS::CodeDeploy::DeploymentGroup MyFunction\ DeploymentGroup
AWS::IAM::Role CodeDeployServiceRole
================================== ================================

NOTE: AWS::IAM::Role resources are only generated if no Role parameter is supplied for DeploymentPreference

With Events

text
A common theme with all Events is SAM will generate a ``AWS::Lambda::Permission`` resource to give event source 
permission to invoke the function. Other generated resources depend on the specific event type.

API
^^^
This is called an "Implicit API". There can be many functions in the template that define these APIs. Behind the 
scenes, SAM will collect all implicit APIs from all Functions in the template, generate a Swagger, and create an 
implicit ``AWS::Serverless::Api`` using this Swagger. This API defaults to a StageName called "Prod" that cannot be
configured.

.. code:: yaml

  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      ...
      Events:
        ThumbnailApi:
          Type: Api
          Properties:
            Path: /thumbnail
            Method: GET
      ...

Additional generated resources:

================================== ================================
CloudFormation Resource Type       Logical ID 
================================== ================================
AWS::ApiGateway::RestApi           *ServerlessRestApi* 
AWS::ApiGateway::Stage             *ServerlessRestApi*\ **Prod**\ Stage 
AWS::ApiGateway::Deployment        *ServerlessRestApi*\ Deployment\ *SHA* (10 Digits of SHA256 of Swagger)
AWS::Lambda::Permission            MyFunction\ **ThumbnailApi**\ Permission\ **Prod** 
                                   (Prod is the default Stage Name for implicit APIs)
================================== ================================


  NOTE: ``ServerlessRestApi*`` resources are generated one per stack.

HTTP API
^^^^
This is called an "Implicit HTTP API". There can be many functions in the template that define these APIs. Behind the 
scenes, SAM will collect all implicit HTTP APIs from all Functions in the template, generate an OpenApi doc, and create an 
implicit ``AWS::Serverless::HttpApi`` using this OpenApi. This API defaults to a StageName called "$default" that cannot be
configured.

.. code:: yaml

  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      ...
      Events:
        ThumbnailApi:
          Type: HttpApi
          Properties:
            Path: /thumbnail
            Method: GET
      ...

Additional generated resources:

================================== ================================
CloudFormation Resource Type       Logical ID 
================================== ================================
AWS::ApiGatewayV2::Api             *ServerlessHttpApi* 
AWS::ApiGatewayV2::Stage           *ServerlessHttpApiApiGatewayDefaultStage*
AWS::Lambda::Permission            MyFunction\ **ThumbnailApi**\ Permission
================================== ================================


  NOTE: ``ServerlessHttpApi*`` resources are generated one per stack.

Cognito
^^^^^^^

Example:

.. code:: yaml

  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      ...
      Events:
        CognitoTrigger:
          Type: Cognito
          Properties:
            UserPool: !Ref MyUserPool
            Trigger: PreSignUp
      ...

  MyUserPool:
    Type: AWS::Cognito::UserPool

Additional generated resources:

================================== ================================
CloudFormation Resource Type       Logical ID 
================================== ================================
AWS::Lambda::Permissions           *MyFunction*\ CognitoPermission
AWS::Cognito::UserPool             Existing MyUserPool resource is modified to append ``LambdaConfig`` 
                                   property where the Lambda function trigger is defined
================================== ================================

  NOTE: You **must** refer to a Cognito UserPool defined in the same template. This is for two reasons:
  
  1. SAM needs to add a ``LambdaConfig`` property to the UserPool resource by reading and modifying the 
  resource definition

  2. Lambda triggers are specified as a property on the UserPool resource. Since CloudFormation cannot modify a resource
  created outside of the stack, this bucket needs to be defined within the template.

S3
^^

Example:

.. code:: yaml

  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      ...
      Events:
        S3Trigger:
          Type: S3
          Properties:
            Bucket: !Ref MyBucket
            Events: s3:ObjectCreated:*
      ...

  MyBucket:
    Type: AWS::S3::Bucket

Additional generated resources:

================================== ================================
CloudFormation Resource Type       Logical ID 
================================== ================================
AWS::Lambda::Permission            MyFunction\ **S3Trigger**\ Permission
AWS::S3::Bucket                    Existing MyBucket resource is modified to append ``NotificationConfiguration`` 
                                   property where the Lambda function trigger is defined
================================== ================================

  NOTE: You **must** refer to an S3 Bucket defined in the same template. This is for two reasons:
  
  1. SAM needs to add a ``NotificationConfiguration`` property to the bucket resource by reading and modifying the 
  resource definition

  2. Lambda triggers are specified as a property on the bucket resource. Since CloudFormation cannot modify a resource
  created outside of the stack, this bucket needs to be defined within the template.

SNS
^^^

Example:

.. code:: yaml

  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      ...
      Events:
        MyTrigger:
          Type: SNS
          Properties:
            Topic: arn:aws:sns:us-east-1:123456789012:my_topic
            SqsSubscription:
              QueuePolicyLogicalId: CustomQueuePolicyLogicalId
              QueueArn: !GetAtt MyCustomQueue.Arn
              QueueUrl: !Ref MyCustomQueue
              BatchSize: 5
              Enabled: true
      ...

Additional generated resources:

================================== ================================
CloudFormation Resource Type       Logical ID 
================================== ================================
AWS::Lambda::Permission            MyFunction\ **MyTrigger**\ Permission
AWS::Lambda::EventSourceMapping    MyFunction\ **MyTrigger**\ EventSourceMapping
AWS::SNS::Subscription             MyFunction\ **MyTrigger**
AWS::SQS::Queue                    MyFunction\ **MyTrigger**\ Queue
AWS::SQS::QueuePolicy              MyFunction\ **MyTrigger**\ QueuePolicy
================================== ================================

  NOTE: ``AWS::Lambda::Permission`` resources are only generated if SqsSubscription is ``false``. ``AWS::Lambda::EventSourceMapping``, ``AWS::SQS::Queue``, ``AWS::SQS::QueuePolicy`` resources are only generated if SqsSubscription is ``true``.

  ``AWS::SQS::Queue`` resources are only generated if SqsSubscription is ``true``.

  Example:

  .. code:: yaml

    MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      ...
      Events:
        MyTrigger:
          Type: SNS
          Properties:
            Topic: arn:aws:sns:us-east-1:123456789012:my_topic
            SqsSubscription: true
      ...

Kinesis
^^^^^^^

Example:

.. code:: yaml

  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      ...
      Events:
        MyTrigger:
          Type: Kinesis
          Properties:
            Stream: arn:aws:kinesis:us-east-1:123456789012:stream/my-stream
            StartingPosition: TRIM_HORIZON      
      ...

Additional generated resources:

================================== ================================
CloudFormation Resource Type       Logical ID 
================================== ================================
AWS::Lambda::Permission            MyFunction\ **MyTrigger**\ Permission
AWS::Lambda::EventSourceMapping    MyFunction\ **MyTrigger** 
================================== ================================

MQ
^^^^^^^

Example:

.. code:: yaml

  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      ...
      Events:
        MyTrigger:
          Type: MQ
          Properties:
            Broker: arn:aws:mq:us-east-2:123456789012:broker:MyBroker:b-1234a5b6-78cd-901e-2fgh-3i45j6k178l9
            SourceAccessConfigurations:
              Type: BASIC_AUTH
              URI: arn:aws:secretsmanager:us-west-2:123456789012:secret:my-path/my-secret-name-1a2b3c
      ...

Additional generated resources:

================================== ================================
CloudFormation Resource Type       Logical ID
================================== ================================
AWS::Lambda::Permission            MyFunction\ **MyTrigger**\ Permission
AWS::Lambda::EventSourceMapping    MyFunction\ **MyTrigger**
================================== ================================

MSK
^^^^^^^

Example:

.. code:: yaml

  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      ...
      Events:
        MyTrigger:
          Type: MSK
          Properties:
            Stream: arn:aws:kafka:us-east-1:123456789012:cluster/mycluster/6cc0432b-8618-4f44-bccc-e1fbd8fb7c4d-2
            StartingPosition: TRIM_HORIZON
      ...

Additional generated resources:

================================== ================================
CloudFormation Resource Type       Logical ID
================================== ================================
AWS::Lambda::Permission            MyFunction\ **MyTrigger**\ Permission
AWS::Lambda::EventSourceMapping    MyFunction\ **MyTrigger**
================================== ================================

SQS
^^^

Example:

.. code:: yaml

  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      ...
      Events:
        MyTrigger:
          Type: SQS
          Properties:
            Queue: arn:aws:sqs:us-east-1:123456789012:my-queue
      ...

Additional generated resources:

================================== ================================
CloudFormation Resource Type       Logical ID 
================================== ================================
AWS::Lambda::Permission            MyFunction\ **MyTrigger**\ Permission
AWS::Lambda::EventSourceMapping    MyFunction\ **MyTrigger** 
================================== ================================

DynamoDb
^^^^^^^^

Example:

.. code:: yaml

  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      ...
      Events:
        MyTrigger:
          Type: DynamoDb
          Properties:
            Stream: arn:aws:dynamodb:us-east-1:123456789012:table/TestTable/stream/2016-08-11T21:21:33.291
            StartingPosition: TRIM_HORIZON      
      ...

Additional generated resources:

================================== ================================
CloudFormation Resource Type       Logical ID 
================================== ================================
AWS::Lambda::Permission            MyFunction\ **MyTrigger**\ Permission
AWS::Lambda::EventSourceMapping    MyFunction\ **MyTrigger** 
================================== ================================

Schedule
^^^^^^^^

Example:

.. code:: yaml

  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      ...
      Events:
        MyTimer:
          Type: Schedule
          Properties:
            Input: rate(5 minutes)
            DeadLetterConfig:
              Type: SQS
      ...

Additional generated resources:

================================== ================================
CloudFormation Resource Type       Logical ID 
================================== ================================
AWS::Lambda::Permission            MyFunction\ **MyTimer**\ Permission
AWS::Events::Rule                  MyFunction\ **MyTimer** 
AWS::SQS::Queue                    MyFunction\ **MyTimer**\ Queue
AWS::SQS::QueuePolicy              MyFunction\ **MyTimer**\ QueuePolicy
================================== ================================

CloudWatchEvent (superseded by EventBridgeRule, see below)
^^^^^^^^^^^^^^^

Example:

.. code:: yaml

  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      ...
      Events:
        OnTerminate:
          Type: CloudWatchEvent
          Properties:
            Pattern:
              source:
                - aws.ec2
              detail-type:
                - EC2 Instance State-change Notification
              detail:
                state:
                  - terminated
      ...

Additional generated resources:

================================== ================================
CloudFormation Resource Type       Logical ID 
================================== ================================
AWS::Lambda::Permission            MyFunction\ **OnTerminate**\ Permission
AWS::Events::Rule                  MyFunction\ **OnTerminate** 
================================== ================================

EventBridgeRule
^^^^^^^^^^^^^^^

Example:

.. code:: yaml

  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      ...
      Events:
        OnTerminate:
          Type: EventBridgeRule
          Properties:
            Pattern:
              source:
                - aws.ec2
              detail-type:
                - EC2 Instance State-change Notification
              detail:
                state:
                  - terminated
              DeadLetterConfig:
                Type: SQS
              RetryPolicy:
                MaximumEventAgeInSeconds: 600
                MaximumRetryAttempts:3
      ...

Additional generated resources:

================================== ================================
CloudFormation Resource Type       Logical ID
================================== ================================
AWS::Lambda::Permission            MyFunction\ **OnTerminate**\ Permission
AWS::Events::Rule                  MyFunction\ **OnTerminate**
AWS::SQS::Queue                    MyFunction\ **OnTerminate**\ Queue
AWS::SQS::QueuePolicy              MyFunction\ **OnTerminate**\ QueuePolicy
================================== ================================

AWS::Serverless::Api
--------------------

In contrast to Implict APIs, you can explicitly define your API resource by providing an entire Swagger definition of 
your API.

Example:

.. code:: yaml

  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      ...
      DefinitionUri: s3://bucket/swagger.json
      StageName: dev
      ...

Generated resources:

================================== ================================
CloudFormation Resource Type       Logical ID 
================================== ================================
AWS::ApiGateway::RestApi           MyApi
AWS::ApiGateway::Stage             MyApi\ **dev**\ Stage 
AWS::ApiGateway::Deployment        MyApi\ Deployment\ *SHA* (10 Digits of SHA256 of DefinitionUri or DefinitionBody value)
================================== ================================

  NOTE: By just specifying AWS::Serverless::Api resource, SAM will *not* add permission for API Gateway to invoke the
  the Lambda Function backing the APIs. You should explicitly re-define all APIs under ``Events`` section of the
  AWS::Serverless::Function resource but include a `RestApiId` property that references the AWS::Serverless::Api
  resource. SAM will add permission for these APIs to invoke the function.

  Example:

  .. code:: yaml

    MyFunction:
      Type: AWS::Serverless::Function
      Properties:
        ...
        Events:
          GetApi:
            Type: Api
            Properties:
              Path: /
              Method: GET

              # This is the property that instructs SAM to just add permissions for an explicitly defined API
              RestApiId: !Ref MyApi

---

## File: docs/internals/index.rst

SAM Internals
=============

Explore the topics in this section to learn more about the internals of how SAM works.

.. toctree::
    :maxdepth: 1
    :glob:

    *

---

## File: docs/cloudformation_compatibility.rst

CloudFormation Compatibility Section
====================================

.. contents::

SAM is built ontop of CloudFormation Transforms. Therefore, we need to support different CloudFormation Capabilities like: Attributes, Intrinsic functions, etc.

CloudFormation Resources Attributes

======================== ========================
     Attribute Name             Supported?
======================== ========================
CreationPolicy           Not Currently
DeletionPolicy           Not Currently
DependsOn                `DependsOn Attribute`_
Metadata                 Not Currently
UpdatePolicy             Not Currently
======================== ========================

.. _DependsOn Attribute:

DependsOn Attribute:

.. code:: yaml

LambdaFunction:
DependsOn: SomeOtherResources
Type: AWS::Serverless::Function
...

CloudFormation Intrinsic Funtions

Currently, we do not support all Intrinsic Functions for all Property Values in AWS::Serverless::* resources but is fully available in other CloudFormation resources. Please see below tables for a details on which Intrinsic Functions can be used on a given field.

The Condition Function is not currently supported on any AWS::Serverless::* Resource type

AWS::Serverless::Function

text
============================ ================================== ========================
     Property Name           Intrinsic(s) Supported            Reasons
============================ ================================== ========================
Handler                            All
Runtime                            All
CodeUri (String - S3Uri)          None                      SAM does not parse any Parameters, which is needed to support Ref
CodeUri (Bucket & Key)             All
FunctionName                       All
Description                        All
MemorySize                         All
Timeout                            All
Role                               All
Policies                           All
Environment                        All
VpcConfig                          All
Events                             All
Tags                               All
Tracing                            All
KmsKeyArn                          All
DeadLetterQueue                    All
DeploymentPreference               All
Layers                             All
AutoPublishAlias             Ref of a CloudFormation Parameter  Alias resources created by SAM uses a LocicalId <FunctionLogicalId+AliasName>. So SAM either needs a string for alias name, or a Ref to template Parameter that SAM can resolve into a string.
AutoPublishCodeSha256              All
ReservedConcurrentExecutions       All
EventInvokeConfig                  All
============================ ================================== ========================

Events Properties

Cognito

text
======================== ================================== ========================
     Property Name        Intrinsic(s) Supported            Reasons
======================== ================================== ========================
UserPool                 Ref of a AWS::Cognito::UserPool    Properties in the AWS::Cognito::UserPool are used to construct different attributes.
Trigger                  All
======================== ================================== ========================

S3

======================== ================================== ========================
Property Name Intrinsic(s) Supported Reasons
======================== ================================== ========================
Bucket All
Events All
Filter All
======================== ================================== ========================

SNS

text
======================== ================================== ========================
     Property Name        Intrinsic(s) Supported            Reasons
======================== ================================== ========================
Topic                    All
======================== ================================== ========================

Kinesis

======================== ================================== ========================
Property Name Intrinsic(s) Supported Reasons
======================== ================================== ========================
Stream All
Queue All
StartingPosition All
BatchSize All
======================== ================================== ========================

MQ

text
======================== ================================== ========================
     Property Name        Intrinsic(s) Supported            Reasons
======================== ================================== ========================
Broker                          All
Queues                          All
SourceAccessConfigurations      All
======================== ================================== ========================

MSK

======================== ================================== ========================
Property Name Intrinsic(s) Supported Reasons
======================== ================================== ========================
Stream All
Topics All
StartingPosition All
======================== ================================== ========================

DynamoDB

text
======================== ================================== ========================
     Property Name        Intrinsic(s) Supported            Reasons
======================== ================================== ========================
Stream                   All
StartingPosition         All
BatchSize                All
SSESpecification         All
======================== ================================== ========================

Api

======================== ======================================== ========================
Property Name Intrinsic(s) Supported Reasons
======================== ======================================== ========================
Path None
Method None
RestApiId Ref of a AWS::Serverless::Api Resource Properties in the AWS::Serverless::API are used to construct different attributes, policies, etc. SAM expects a Path and Method to exist as defined by the AWs::Serverless::API Resource definition
======================== ======================================== ========================

Schedule

text
======================== ================================== ========================
     Property Name        Intrinsic(s) Supported            Reasons
======================== ================================== ========================
Schedule                 All
Input                    All
Name                     All
Description              All
Enabled                  All
======================== ================================== ========================

CloudWatchEvent (superseded by EventBridgeRule, see below)

======================== ================================== ========================
Property Name Intrinsic(s) Supported Reasons
======================== ================================== ========================
Pattern All
Input All
InputPath All
DeadLetterConfig All
RetryPolicy All
======================== ================================== ========================

EventBridgeRule

text
======================== ================================== ========================
     Property Name        Intrinsic(s) Supported            Reasons
======================== ================================== ========================
Pattern                  All
Input                    All
InputPath                All
DeadLetterConfig         All
RetryPolicy              All
======================== ================================== ========================

IotRule

======================== ================================== ========================
Property Name Intrinsic(s) Supported Reasons
======================== ================================== ========================
Sql All
AwsIotSqlVersion All
======================== ================================== ========================

AlexaSkill

text
This event has no Properties


AWS::Serverless::Api

================================== ======================== ========================
Property Name Intrinsic(s) Supported Reasons
================================== ======================== ========================
Name All
StageName All
DefinitionUri (String - S3URI) None SAM does not parse any Parameters, which is needed to support Ref
DefinitionUri (Bucket & Key) All
DefinitionBody All
CacheClusterEnabled All
CacheClusterSize All
Variables All
EndpointConfiguration All
MethodSettings All
BinaryMediaTypes All
MinimumCompressionSize All
Cors All
TracingEnabled All
OpenApiVersion None
Domain All
================================== ======================== ========================

AWS::Serverless::Application

text
================================== ======================== ========================
     Property Name                 Intrinsic(s) Supported          Reasons
================================== ======================== ========================
Location                            None                     SAM expects exact values for the Location property
Parameters                          All
NotificationARNs                    All
Tags                                All
TimeoutInMinutes                    All
================================== ======================== ========================


AWS::Serverless::SimpleTable

======================== ======================== ========================
Property Name Intrinsic(s) Supported Reasons
======================== ======================== ========================
PrimaryKey None
ProvisionedThroughput All
TableName All
Tags All
======================== ======================== ========================


File: docs/faq.rst

FAQ

Frequently Asked Questions

.. contents::
:local:

How to manage multiple environments?

Terminology clarification: Environment and Stage can normally be used interchangeably but since AWS API Gateway relies on a concrete concept of Stages we'll use the term Environment here to avoid confusion.

We recommend a one-to-one mapping of environment to Cloudformation Stack.

This means having a separate CloudFormation stack per environment, using a single template file with a dynamically set target stack via the --stack-name parameter in the aws cloudformation deploy command.

For example, lets say we have 3 environments (dev, test, and prod).
Each of those would have their own CloudFormation stack β€” dev-stack, test-stack, prod-stack. Our CI/CD system will deploy to dev-stack, test-stack, and then prod-stack but will be pushing one template through all of these stacks.

This approach limits the 'blast radius' for any given deployment since all resources for each environment are scoped to a different CloudFormation Stack, so we will never be editing production resources on accident.

If we need to bring up separate stacks for different reasons (multiple region deployments, developer/branch stacks) it will be straightforward to do so with this approach since the same template can be used to bring up and manage a new stack independent of any others.

In cases where you need to manage different stages differently this can be done through a combination of Stack Parameters, Conditions, and Fn::If statements.

How to enable API Gateway Logs

Work is underway to make this functionality part of the SAM specification. Until then a suggested workaround is to use the aws cli update-stage command to enable it.

.. code-block:: console

text
aws apigateway update-stage \
  --rest-api-id <api-id> \
  --stage-name <stage-name> \
  --patch-operations \
    op=replace,path=/*/*/logging/dataTrace,value=true \
    op=replace,path=/*/*/logging/loglevel,value=Info \
    op=replace,path=/*/*/metrics/enabled,value=true

The command above can be run as a post deployment CI step or it could be triggered by a custom resource <https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources.html/>_ within the same CloudFormation template.

Please note that in either case you will see metric gaps between the time CloudFormation updates API Gateway and the time this command runs.

How to deploy Lambda\@Edge functions with SAM?

At present, SAM doesn't support Lambda@Edge <https://aws.amazon.com/lambda/edge/>_ as a native event. However you can follow this example to ease deployment: Lambda Edge Example <https://github.com/aws/serverless-application-model/tree/c00b8a3/examples/2016-10-31/lambda_edge>_.


File: docs/globals.rst

Globals Section

.. contents::

Resources in a SAM template tend to have shared configuration such as Runtime, Memory,
VPC Settings, Environment Variables, Cors, etc. Instead of duplicating this information in every resource, you can
write them once in the Globals section and let all resources inherit it.

Example:

.. code:: yaml

Globals:
Function:
Runtime: nodejs24.x
Timeout: 180
Handler: index.handler
Environment:
Variables:
TABLE_NAME: data-table

Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
Environment:
Variables:
MESSAGE: "Hello From SAM"

text
ThumbnailFunction:
  Type: AWS::Serverless::Function
  Properties:
    Events:
      Thumbnail:
        Type: Api
        Properties:
          Path: /thumbnail
          Method: POST

In the above example, both HelloWorldFunction and ThumbnailFunction will use nodejs24.x runtime, 180 seconds
timeout and index.handler Handler. HelloWorldFunction adds MESSAGE environment variable in addition to the
inherited TABLE_NAME. ThumbnailFunction inherits all the Globals properties and adds an API Event source.

Supported Resources and Properties

Currently, the following resources and properties are being supported:

.. code:: yaml

Globals:
Function:
# Properties of AWS::Serverless::Function
Handler:
Runtime:
CodeUri:
DeadLetterQueue:
MemorySize:
Timeout:
VpcConfig:
Environment:
Tags:
PropagateTags:
Tracing:
KmsKeyArn:
AutoPublishAlias:
AutoPublishAliasAllProperties:
Layers:
DeploymentPreference:
RolePath:
PermissionsBoundary:
ReservedConcurrentExecutions:
ProvisionedConcurrencyConfig:
AssumeRolePolicyDocument:
EventInvokeConfig:
FileSystemConfigs:
CodeSigningConfigArn:
Architectures:
SnapStart:
EphemeralStorage:
FunctionUrlConfig:
RuntimeManagementConfig:
LoggingConfig:
RecursiveLoop:
SourceKMSKeyArn:
TenancyConfig:
DurableConfig:
CapacityProviderConfig:
FunctionScalingConfig:
PublishToLatestPublished:
VersionDeletionPolicy:

text
Api:
  # Properties of AWS::Serverless::Api
  # Also works with Implicit APIs
  Auth:
  Name:
  DefinitionUri:
  CacheClusterEnabled:
  CacheClusterSize:
  MergeDefinitions:
  Variables:
  EndpointConfiguration:
  MethodSettings:
  BinaryMediaTypes:
  MinimumCompressionSize:
  Cors:
  GatewayResponses:
  AccessLogSetting:
  CanarySetting:
  TracingEnabled:
  OpenApiVersion:
  Domain:
  AlwaysDeploy:
  PropagateTags:
  SecurityPolicy:
  EndpointAccessMode:

HttpApi:
  # Properties of AWS::Serverless::HttpApi
  # Also works with Implicit APIs
  Auth:
  AccessLogSettings:
  StageVariables:
  Tags:
  CorsConfiguration:
  DefaultRouteSettings:
  Domain:
  RouteSettings:
  FailOnWarnings:
  PropagateTags:

SimpleTable:
  # Properties of AWS::Serverless::SimpleTable
  SSESpecification:

StateMachine:
  # Properties of AWS::Serverless::StateMachine
  PropagateTags:

LayerVersion:
  # Properties of AWS::Serverless::LayerVersion
  PublishLambdaVersion:

CapacityProvider:
  # Properties of AWS::Serverless::CapacityProvider
  VpcConfig:
  OperatorRole:
  Tags:
  InstanceRequirements:
  ScalingConfig:
  KmsKeyArn:
  PropagateTags:
  ManagedResourceTags:

WebSocketApi:
  # Properties of AWS::Serverless::WebSocketApi
  AccessLogSettings:
  ApiKeySelectionExpression:
  DefaultRouteSettings:
  DisableExecuteApiEndpoint:
  DisableSchemaValidation:
  Domain:
  FailOnWarnings:
  IpAddressType:
  PropagateTags:
  RouteSelectionExpression:
  RouteSettings:
  StageVariables:
  Tags:

Implicit APIs

text
APIs created by SAM when you have an API declared in the ``Events`` section are called "Implicit APIs". You can use 
Globals to override all properties of Implicit APIs as well. 

Unsupported Properties

Following properties are not supported in Globals section. We made the explicit
call to not support them because it either made the template hard to understand or opened scope for potential security
issues.

AWS::Serverless::Function:

  • Role
  • Policies
  • FunctionName
  • Events

AWS::Serverless::Api:

  • StageName
  • DefinitionBody

AWS::Serverless::HttpApi:

  • StageName
  • DefinitionBody
  • DefinitionUri

Overridable

Properties declared in the Globals section can be overriden by the resource. For example, you can add new Variables
to environment variable map or override globally declared variables. But the resource cannot remove a property
specified in globals environment variables map. More generally, Globals declare properties shared by all your resources.
Some resources can provide new values for globally declared properties but cannot completely remove them. If some
resources use a property but others do not, then you must not declare them in the Globals section.

Here is how overriding works for various data types:

Primitive Values are replaced

text
*String, Number, Boolean etc*

Value specified in the resource will **replace** Global value

Example:

Runtime of ``MyFunction`` will be set to python3.14

.. code:: yaml

  Globals:
    Function:
      Runtime: nodejs24.x

  Resources:
    MyFunction:
      Type: AWS::Serverless::Function
      Properties:
        Runtime: python3.14

Maps are merged
~~~~~~~~~~~~~~~
*Maps are also known as dictionaries or collections of key/value pairs*

Map entries in the resource will be **merged** with global map entries. In case of duplicates the resource entry will override the global entry.

Example:

.. code:: yaml

  Globals:
    Function:
      Environment: 
        Variables:
          STAGE: Production
          TABLE_NAME: global-table

  Resources:
    MyFunction:
      Type: AWS::Serverless::Function
      Properties:
        Environment: 
          Variables:
            TABLE_NAME: resource-table
            NEW_VAR: hello

In the above example the environment variables of ``MyFunction`` will be set to:

.. code:: json

  {
    "STAGE": "Production", 
    "TABLE_NAME": "resource-table", 
    "NEW_VAR": "hello" 
  }

Lists are additive
~~~~~~~~~~~~~~~~~~~
*Lists are also known as arrays*

Global entries will be **prepended** to the list in the resource.

Example:

.. code:: yaml

  Globals:
    Function:
      VpcConfig:
        SecurityGroupIds:
          - sg-123
          - sg-456

  Resources:
    MyFunction:
      Type: AWS::Serverless::Function
      Properties:
        VpcConfig:
          SecurityGroupIds:
            - sg-first
 
In the above example the Security Group Ids of ``MyFunction``'s VPC Config will be set to:

.. code:: json

  [ "sg-123", "sg-456", "sg-first" ]

Resource Properties with Custom Merge Strategy

Certain properties override the default list or map merge behavior described above.

Replace β€” resource value completely replaces global value (no concatenation):

  • Function.Architectures
  • CapacityProvider.InstanceRequirements.Architectures

.. code:: yaml

Globals:
Function:
Architectures: [x86_64]

Resources:
MyFunction:
Type: AWS::Serverless::Function
Properties:
Architectures: [arm64]
# Result: [arm64] β€” not [x86_64, arm64]

Prune and Merge (PRUNE_AND_MERGE) β€” only keys declared in the resource survive; shared keys are deep-merged.
This prevents mutually exclusive properties from being merged together.

  • CapacityProvider.ManagedResourceTags

.. code:: yaml

Direction 1: Global sets Propagate, resource wants explicit Tags.

Globals:
CapacityProvider:
ManagedResourceTags:
Propagate: true

Resources:
MyCP:
Type: AWS::Serverless::CapacityProvider
Properties:
ManagedResourceTags:
Tags: {env: prod, app: svc}
# Result: {Tags: {env: prod, app: svc}}
# "Propagate" is dropped β€” not declared in resource.
# Without prune-and-merge, the result would be
# {Propagate: true, Tags: {env: prod, app: svc}}
# which violates the mutual exclusivity rule.

.. code:: yaml

Direction 2: Global sets Tags, resource opts out entirely.

Globals:
CapacityProvider:
ManagedResourceTags:
Tags: {env: prod, team: plat}

Resources:
MyCP:
Type: AWS::Serverless::CapacityProvider
Properties:
ManagedResourceTags:
Propagate: false
# Result: {Propagate: false} β†’ PropagateTags Mode: "None"
# Global "Tags" is dropped β€” resource only declared "Propagate".
# The resource is explicitly opting out of tag propagation.

.. note::

The prune-and-merge strategy applies symmetrically in both directions.
Whichever keys the resource declares are the only ones that survive the merge.

Contributors can register new per-property strategies in CUSTOM_STRATEGIES
in samtranslator/plugins/globals/globals.py.


File: docs/index.rst

.. SAM documentation master file, created by
sphinx-quickstart on Thu Nov 23 18:15:59 2017.
You can adapt this file completely to your liking, but it should at least
contain the root toctree directive.

Create & deploy serverless applications

What's New?

  • Globals section
  • Support for Traffic Shifting Lambda deployments
  • Refer to resources automatically created by SAM
  • FAQ section

.. toctree::
:hidden:
:glob:

text
globals.rst
safe_lambda_deployments.rst
policy_templates.rst
internals/index
faq.rst

File: docs/policy_templates.rst

Policy Templates

When you define a Serverless Function, SAM automatically creates the IAM Role required to run the function. Let's say
your function needs to access couple of DynamoDB tables, you need to give your function explicit permissions to access
the tables. You can do this by adding AWS Managed Policies to Serverless Function resource definition in your SAM
template.

For Example:

.. code:: yaml

MyFunction:
Type: AWS::Serverless::Function
Properties:
...
Policies:
# Give your Lambda Function Full Access to DynamoDB
- AmazonDynamoDBFullAccess
...

MyTable:
Type: AWS::Serverless::SimpleTable

Behind the scenes, AmazonDynamoDBFullAccess will give your function access to all DynamoDB APIs against all
DynamoDB tables in all regions. This is excessively permissive when all that your function does is Read & Write
values from the MyTable created in the stack.

SAM provides a tighter and more secure version of AWS Managed Policies called Policy Templates. This are a set of
readily available policies that can be scoped to a specific resource in the same region where your stack exists.
Let's modify the above example to use a policy template called DynamoDBCrudPolicy:

.. code:: yaml

MyFunction:
Type: AWS::Serverless::Function
Properties:
...
Policies:

text
# Give just CRUD permissions to one table
    - DynamoDBCrudPolicy:
        TableName: !Ref MyTable

  ...

MyTable:
Type: AWS::Serverless::SimpleTable

How to Use

Policy Templates are specified in Policies property of AWS::Serverless::Function resource. You can mix policy
templates with AWS Managed Policies, custom managed policies or inline policy statements. Behind the scenes
SAM will expand the policy template to an inline policy statement based on the definition listed in
policy_templates.json_ file.

Every policy template requires zero or more parameters, which are the resource that this policy is scoped to.
Your template will fail to deploy if the value for a required parameter is not specified. You can consult the
policy_templates.json_ file for name of the policy templates, parameter names as well as the actual policy statement
it represents.

If you want a quick reference of all policies, checkout the all_policy_templates.yaml_ SAM template in examples
folder.

NOTE: If a policy template does not require a parameter, you should still specify the value to be an empty dictionary
like this:

.. code:: yaml

text
Policies:
  - CloudWatchPutMetricPolicy: {}

.. _policy_templates.json: https://github.com/aws/serverless-application-model/blob/develop/samtranslator/policy_templates_data/policy_templates.json
.. _all_policy_templates.yaml: https://github.com/aws/serverless-application-model/blob/develop/tests/translator/input/all_policy_templates.yaml


File: docs/safe_lambda_deployments.rst

Safe Lambda deployments

.. contents::

Pushing to production can be nerve-wracking even if you have 100% unit test coverage and a state-of-art full CD system.
It is a good practice to expose your new code to a small percentage of production traffic, run tests, watch for alarms
and dial up traffic as you gain more confidence. The goal is to minimize production impact as much as possible.

To enable traffic shifting deployments for Lambda functions, we will use Lambda Aliases, which can balance incoming
traffic between two different versions of your function, based on preassigned weights. Before deployment,
the alias sends 100% of invokes to the version used in production. During deployment, we will upload the code to Lambda,
publish a new version, send a small percentage of traffic to the new version, monitor, and validate before shifting
100% of traffic to the new version. You can do this manually by calling Lambda APIs or let AWS CodeDeploy automate
it for you. CodeDeploy will shift traffic, monitor alarms, run validation logic and even trigger an automatic rollback
if something goes wrong.

SAM comes built-in with CodeDeploy support. You can enable automated traffic shifting Lambda deployments by
adding the following lines to your AWS::Serverless::Function resource property or in the
Globals_ section.

.. code:: yaml

text
AutoPublishAlias: live
DeploymentPreference:
  Type: Linear10PercentEvery10Minutes

The rest of this document dives deep into how this snippet works, available configurations, and debugging techniques
when deployments don't work as expected.

Instant traffic shifting using Lambda Aliases

Every Lambda function can have any number of Versions and Aliases
associated with them. Versions are immutable snapshots of a function
including code & configuration. If you are familiar with git, they are
similar to commits. In general, it is a good practice to publish a new
version every time you update your function code. When you invoke a
specific version (using the function name + version number combination) you
are guaranteed to get the same code & configuration irrespective of the
state of the function. This protects you against accidentally updating
production code.

To effectively use the versions, you should create an Alias which is
literally a pointer to a version. Aliases have a name and an ARN similar
to the function and are accepted by the Invoke APIs. If you invoke an Alias,
Lambda will in turn invoke the version that the Alias is pointing to.

In production, you will first update your function code, publish a new
version, invoke the version directly to run tests against it, and, after
you are satisfied, flip the Alias to point to the new version. Traffic
will instantly shift from using your old version to using the new version.

SAM provides a simple primitive to do this for you. Add the following
property to your AWS::Serverless::Function resource:

.. code:: yaml

text
AutoPublishAlias: <alias-name>

This will:

  • Create an Alias with <alias-name>
  • Create & publish a Lambda version with the latest code & configuration
    derived from the CodeUri property. Optionally it is possible to specify
    property AutoPublishCodeSha256 that will override the hash computed for
    Lambda CodeUri property.
  • Point the Alias to the latest published version
  • Point all event sources to the Alias & not to the function
  • When the CodeUri property of AWS::Serverless::Function changes,
    SAM will automatically publish a new version & point the alias to the
    new version

In other words, your traffic will shift "instantly" to your new code.

text
NOTE: ``AutoPublishAlias`` will publish a new version only when the
``CodeUri`` changes. Updates to other configuration (ex: MemorySize,
Timeout) etc will *not* publish a new version. Hence your Alias will
continue to point to old version that uses the old configurations.

Traffic shifting using CodeDeploy

For production deployments, you may want more controlled traffic shifting
from an old version to a new version which monitors alarms and triggers a
rollback if necessary. CodeDeploy is an AWS service which can do this
for you. It uses Lambda Alias' ability to route a percentage of traffic
to two different Lambda Versions. To use this feature, set the
DeploymentPreference property of AWS::Serverless::Function
resource:

.. code:: yaml

MyLambdaFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs24.x
AutoPublishAlias: live
DeploymentPreference:
Type: Linear10PercentEvery10Minutes
Alarms:
# A list of alarms that you want to monitor
- !Ref AliasErrorMetricGreaterThanZeroAlarm
- !Ref LatestVersionErrorMetricGreaterThanZeroAlarm
Hooks:
# Validation Lambda functions that are run before & after traffic shifting
PreTraffic: !Ref PreTrafficLambdaFunction
PostTraffic: !Ref PostTrafficLambdaFunction
# Provide a custom role for CodeDeploy traffic shifting here, if you don't supply one
# SAM will create one for you with default permissions
Role: !Ref IAMRoleForCodeDeploy # Parameter example, you can pass an IAM ARN

AliasErrorMetricGreaterThanZeroAlarm:
Type: "AWS::CloudWatch::Alarm"
Properties:
AlarmDescription: Lambda Function Error > 0
ComparisonOperator: GreaterThanThreshold
Dimensions:
- Name: Resource
Value: !Sub "${MyLambdaFunction}:live"
- Name: FunctionName
Value: !Ref MyLambdaFunction
EvaluationPeriods: 2
MetricName: Errors
Namespace: AWS/Lambda
Period: 60
Statistic: Sum
Threshold: 0

LatestVersionErrorMetricGreaterThanZeroAlarm:
Type: "AWS::CloudWatch::Alarm"
Properties:
AlarmDescription: Lambda Function Error > 0
ComparisonOperator: GreaterThanThreshold
Dimensions:
- Name: Resource
Value: !Sub "${MyLambdaFunction}:live"
- Name: FunctionName
Value: !Ref MyLambdaFunction
- Name: ExecutedVersion
Value: !GetAtt MyLambdaFunction.Version.Version
EvaluationPeriods: 2
MetricName: Errors
Namespace: AWS/Lambda
Period: 60
Statistic: Sum
Threshold: 0

PreTrafficLambdaFunction:
Type: AWS::Serverless::Function
Properties:
Handler: preTrafficHook.handler
Policies:
- Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "codedeploy:PutLifecycleEventHookExecutionStatus"
Resource:
!Sub 'arn:${AWS::Partition}:codedeploy:${AWS::Region}:${AWS::AccountId}:deploymentgroup:${ServerlessDeploymentApplication}/*'
- Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "lambda:InvokeFunction"
Resource: !GetAtt MyLambdaFunction.Arn
Runtime: nodejs24.x
FunctionName: 'CodeDeployHook_preTrafficHook'
DeploymentPreference:
Enabled: False
Role: ""
Environment:
Variables:
CurrentVersion: !Ref MyLambdaFunction.Version

When you update your function code and deploy the SAM template using
CloudFormation, the following happens:

  • CloudFormation publishes a new Lambda Version from the new code
  • Since a deployment preference is set, CodeDeploy takes over the job of actually shifting traffic from old version to new version.
  • Before traffic shifting starts, CodeDeploy will invoke the PreTraffic Hook Lambda function. This Lambda function must call back to CodeDeploy with an explicit status of Success or Failure, via the PutLifecycleEventHookExecutionStatus_ API. On Failure, CodeDeploy will abort and report a failure back to CloudFormation. On Success, CodeDeploy will proceed with the specified traffic shifting. Here_ is a sample Lambda Hook function.
  • Type: Linear10PercentEvery10Minutes instructs CodeDeploy to start with 10% traffic on new version and add 10% every 10 minutes. It will complete traffic shifting in 100 minutes.
  • During traffic shifting, if any of the CloudWatch Alarms go to Alarm state, CodeDeploy will immediately flip the Alias back to old version and report a failure to CloudFormation.
  • After traffic shifting completes, CodeDeploy will invoke the PostTraffic Hook Lambda function. This is similar to PreTraffic Hook where the function must callback to CodeDeploy to report a Success or a Failure. PostTraffic hook is a great place to run integration tests or other validation actions.
  • If everything went well, the Alias will be pointing to the new Lambda Version.
  • If you supply the "Role" argument to the DeploymentPreference, it will prevent SAM from creating a role and instead use the provided CodeDeploy role for traffic shifting

NOTE: Verify that your AWS SDK version supports PutLifecycleEventHookExecutionStatus. For example, Python requires SDK version 1.4.8 or newer.

.. _PutLifecycleEventHookExecutionStatus: https://docs.aws.amazon.com/codedeploy/latest/APIReference/API_PutLifecycleEventHookExecutionStatus.html

.. _Here: https://github.com/aws/serverless-application-model/blob/d168f371f494196a57032313075db9faae5587e4/examples/2016-10-31/lambda_safe_deployments/src/preTrafficHook.js

Traffic Shifting Configurations

text
In the above example ``Linear10PercentEvery10Minutes`` is one of several preselected traffic shifting configurations 
available in CodeDeploy. You can pick the configuration that best suits your application. See docs_ for the complete list:

.. _docs: https://github.com/aws/serverless-application-model/blob/master/docs/safe_lambda_deployments.rst#traffic-shifting-configurations

- Canary10Percent30Minutes
- Canary10Percent5Minutes
- Canary10Percent10Minutes
- Canary10Percent15Minutes
- AllAtOnce
- Linear10PercentEvery10Minutes
- Linear10PercentEvery1Minute
- Linear10PercentEvery2Minutes
- Linear10PercentEvery3Minutes

They work as follows:

- **LinearXPercentYMinutes**: Traffic to new version will linearly increase in steps of X percentage every Y minutes. 

  Ex: ``Linear10PercentEvery10Minutes`` will add 10 percentage of traffic every 10 minute to complete in 100 minutes.

- **CanaryXPercentYMinutes**: X percent of traffic will be routed to new version for Y minutes. After Y minutes,
  100 percent of traffic will be sent to new version. Some people call this as Blue/Green deployment. 

  Ex: ``Canary10Percent15Minutes`` will send 10 percent traffic to new version and 15 minutes later complete deployment
  by sending all traffic to new version.

- **AllAtOnce**: This is an instant shifting of 100% of traffic to new version. This is useful if you want to run
  run pre/post hooks but don't want a gradual deployment. If you have a pipeline, you can set Beta/Gamma stages to 
  deploy instantly because the speed of deployments matter more than safety here.
- **Custom**: Aside from Above mentioned Configurations, Custom Codedeploy configuration are also supported.
  (Example. Type: CustomCodeDeployConfiguration)

PreTraffic & PostTraffic Hooks
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

CodeDeploy allows you to run an arbitrary Lambda function before traffic shifting actually starts (PreTraffic Hook) 
and after it completes (PostTraffic Hook). With either hook, you have the opportunity to run logic that determines
whether the deployment must succeed or fail. For example, with PreTraffic hook you could run integration tests against
the newly created Lambda version (but not serving traffic). With PostTraffic hook, you could run end-to-end validation
checks.

Hooks are extremely powerful because:

- **Not limited by Lambda function duration**: CodeDeploy invokes the hook function asynchronously. The function will
  receive a ``deploymentId`` and ``lifecycleEventHookExecutionId`` that should be used with a call to the CodeDeploy API to report success or failure. 
  Therefore you can build a workflow that runs for several minutes or hours before completing the hook by calling the 
  CodeDeploy API.

- **New Version is created before PreTraffic Hook runs**: Before PreTraffic hook runs, the Lambda Version containing 
  the new code has been created but this version is not serving any traffic yet. Therefore, in your hook function, 
  you can directly invoke the Version to run integration tests or even pre-warm the Lambda containers before exposing it
  to production traffic.

    NOTE: The event payload delivered to the Hook function will not contain the Lambda ARN to be tested.
    We recommend adding an Environment variable to the Hook function that maintains the current Version of the Lambda requiring safe deployments

.. code:: yaml

  Environment:
    Variables:
      CurrentVersion: !Ref MySafeLambdaFunction.Version


- **Hooks are executed per-function**: Each Lambda function gets its own PreTraffic and PostTraffic hook (technically
  speaking hooks are executed once per DeploymentGroup, but in this case the DeploymentGroup contains only one Lambda
  Function). So you can customize the hooks logic to the function that is being deployed.

    NOTE: If the Hook functions are created by the same SAM template that is deployed, then make sure to turn off
    traffic shifting deployments for the hook functions. Also, the Role SAM generates for a Lambda Execution Role does not include all permissions needed for Pre and Post hook functions, since it
    will not contain the necessary permissions to call the CodeDeploy APIs or Invoke your new Lambda function for testing.
    Instead, use the Policies_ attribute to provide the CodeDeploy and Lambda permissions needed. The example also shows a Policy that provides access to the CodeDeploy resource that SAM automatically generates.
    Finally, use the ``FunctionName`` property to control the exact name of the Lambda function CloudFormation creates. Otherwise, CloudFormation will create your Lambda function with the Stack name and a unique ID added as part of the name.

.. _Policies: https://github.com/aws/serverless-application-model/blob/master/versions/2016-10-31.md#resource-types

.. code:: yaml

    FunctionName: 'CodeDeployHook_preTrafficHook'
    DeploymentPreference:
        Enabled: False
    Policies:
        - Version: "2012-10-17"
          Statement:
          - Effect: "Allow"
            Action:
              - "codedeploy:PutLifecycleEventHookExecutionStatus"
            Resource: "*"
        - Version: "2012-10-17"
          Statement:
          - Effect: "Allow"
            Action:
              - "lambda:InvokeFunction"
            Resource: !GetAtt MyLambdaFunction.Arn

Checkout the lambda_safe_deployments_ folder for an example for how to create SAM template that contains a hook function.

.. _lambda_safe_deployments: https://github.com/aws/serverless-application-model/tree/5f2287613ca46dba8d65e833e00f2f515d1b44a5/examples/2016-10-31/lambda_safe_deployments

Internals
~~~~~~~~~
Internally, SAM will create the following resources in your CloudFormation stack to make all of this work:

-  One ``AWS::CodeDeploy::Application`` per stack, that is referencable via ${ServerlessDeploymentApplication}
-  One ``AWS::CodeDeploy::DeploymentGroup`` per
   ``AWS::Serverless::Function`` resource. Each Lambda Function in your
   SAM template belongs to its own Deployment Group.
-  Adds ``UpdatePolicy`` on ``AWS::Lambda::Alias`` resource that is
   connected to the function's Deployment Group resource.
-  One ``AWS::IAM::Role`` called "CodeDeployServiceRole", if no custom role is provided

CodeDeploy assumes that there are no dependencies between Deployment Groups and hence will deploy them in parallel.
Since every Lambda function is to its own CodeDeploy DeploymentGroup, they will be deployed in parallel.
The CodeDeploy service will assume the new CodeDeployServiceRole to Invoke any Pre/Post hook functions and perform the traffic shifting and Alias updates.

  NOTE: The CodeDeployServiceRole only allows InvokeFunction on functions with names prefixed with  ``CodeDeployHook_``. For example,  you should name your Hook functions as such: ``CodeDeployHook_PreTrafficHook``.

Production errors preventing deployments
~~~~~~~~~
In some situations, an issue that is happening in production may prevent you from deploying a fix. This may happen when a deployment happens when traffic is too low to register enough errors to trigger a roll back, or where someone is sending malicious traffic through to a lambda and you haven’t accounted for the scenario where they do. 

When this happens, the alarm for errors in the current lambda version is in an error state, which will cause code deploy to roll back any attempted deploys straight away.

To release code in this situation, you need to

- Go into the CodeDeploy console
- Select the application you want to deploy to
- Select the corresponding Deployment Group
- Select β€œEdit”
- Select β€œAdvanced - optional”
- Select "ignore alarm configuration"
- Save the changes

Run your deployment as usual

Then once deployment has successfully run, return to the CodeDeploy console, and follow the above steps but this time deselect β€œignore alarm configuration”.

.. _Globals: globals.rst

---

## File: examples/apps/README.md

All example/template applications have been moved to [aws/aws-sam-cli-app-templates](https://github.com/aws/aws-sam-cli-app-templates).