aws-cloudformation-lambda

📁 giuseppe-trisciuoglio/developer-kit 📅 10 days ago
71
总安装量
71
周安装量
#3097
全站排名
安装命令
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill aws-cloudformation-lambda

Agent 安装分布

claude-code 54
cursor 49
replit 46
opencode 44
codex 43

Skill 文档

AWS CloudFormation Lambda Serverless

Overview

Create production-ready serverless infrastructure using AWS CloudFormation templates. This skill covers Lambda functions, layers, event sources, API Gateway, Step Functions, cold start optimization, and best practices for parameters, outputs, and cross-stack references.

When to Use

Use this skill when:

  • Creating new Lambda functions with CloudFormation
  • Configuring Lambda layers for shared code
  • Integrating Lambda with API Gateway (REST and HTTP API)
  • Implementing event sources (SQS, SNS, EventBridge, S3, DynamoDB)
  • Creating Step Functions with Lambda workflows
  • Optimizing cold start and performance
  • Organizing templates with Parameters, Outputs, Mappings, Conditions
  • Implementing cross-stack references with export/import
  • Using Transform for macros and reuse

CloudFormation Template Structure

Base Template with Standard Format

AWSTemplateFormatVersion: 2010-09-09
Description: Lambda function with API Gateway integration

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: Function Configuration
        Parameters:
          - FunctionName
          - Runtime
          - Handler
      - Label:
          default: Deployment Settings
        Parameters:
          - Environment
          - DeployStage

Parameters:
  FunctionName:
    Type: String
    Default: my-lambda-function
    Description: Name of the Lambda function

  Runtime:
    Type: String
    Default: python3.11
    AllowedValues:
      - python3.8
      - python3.9
      - python3.10
      - python3.11
      - nodejs18.x
      - nodejs20.x
      - java11
      - java17
      - java21

  Handler:
    Type: String
    Default: index.handler

  Environment:
    Type: String
    Default: dev
    AllowedValues:
      - dev
      - staging
      - production

  DeployStage:
    Type: String
    Default: dev

Mappings:
  EnvironmentConfig:
    dev:
      MemorySize: 128
      Timeout: 30
      ReservedConcurrentExecutions: 5
    staging:
      MemorySize: 256
      Timeout: 60
      ReservedConcurrentExecutions: 20
    production:
      MemorySize: 512
      Timeout: 120
      ReservedConcurrentExecutions: 100

Conditions:
  IsProduction: !Equals [!Ref Environment, production]
  IsDev: !Equals [!Ref Environment, dev]

Transform:
  - AWS::Serverless-2016-10-31

Resources:
  # Lambda Function
  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Ref FunctionName
      Runtime: !Ref Runtime
      Handler: !Ref Handler
      Code:
        S3Bucket: !Ref SourceBucket
        S3Key: !Sub "lambda/${Environment}/function.zip"
      MemorySize: !FindInMap [EnvironmentConfig, !Ref Environment, MemorySize]
      Timeout: !FindInMap [EnvironmentConfig, !Ref Environment, Timeout]
      Role: !GetAtt LambdaExecutionRole.Arn
      Environment:
        Variables:
          ENVIRONMENT: !Ref Environment
          LOG_LEVEL: !If [IsProduction, INFO, DEBUG]
      Tags:
        - Key: Environment
          Value: !Ref Environment
        - Key: Project
          Value: !Ref ProjectName

Outputs:
  LambdaFunctionArn:
    Description: ARN of the Lambda function
    Value: !GetAtt MyLambdaFunction.Arn
    Export:
      Name: !Sub "${AWS::StackName}-LambdaFunctionArn"

Best Practices for Parameters

AWS-Specific Parameter Types

Parameters:
  # AWS-specific types for validation
  VPCId:
    Type: AWS::EC2::VPC::Id
    Description: VPC where Lambda will run

  SubnetIds:
    Type: List<AWS::EC2::Subnet::Id>
    Description: Subnets for Lambda VPC config

  SecurityGroupIds:
    Type: List<AWS::EC2::SecurityGroup::Id>
    Description: Security groups for Lambda

  LambdaRuntime:
    Type: AWS::Lambda::Runtime
    Description: Lambda runtime selection

  IAMRoleArn:
    Type: AWS::IAM::Role::Arn
    Description: IAM role for Lambda execution

  S3BucketForCode:
    Type: AWS::S3::Bucket
    Description: S3 bucket for Lambda code

  KMSKeyArn:
    Type: AWS::KMS::Key::Arn
    Description: KMS key for environment variables

Parameter Constraints

Parameters:
  FunctionName:
    Type: String
    Default: my-function
    Description: Lambda function name
    ConstraintDescription: Must be 1-64 characters, alphanumeric and hyphens
    MinLength: 1
    MaxLength: 64
    AllowedPattern: "[a-zA-Z0-9-_]+"

  MemorySize:
    Type: Number
    Default: 128
    Description: Memory allocation in MB
    MinValue: 128
    MaxValue: 10240
    ConstraintDescription: Must be between 128 and 10240 MB

  Timeout:
    Type: Number
    Default: 30
    Description: Function timeout in seconds
    MinValue: 1
    MaxValue: 900
    ConstraintDescription: Must be between 1 and 900 seconds

  EnvironmentName:
    Type: String
    Default: dev
    Description: Deployment environment
    AllowedValues:
      - dev
      - staging
      - production
    ConstraintDescription: Must be dev, staging, or production

SSM Parameter References

Parameters:
  DatabaseConnectionString:
    Type: AWS::SSM::Parameter::Value<String>
    Default: /myapp/database/connection-string
    Description: Database connection string from SSM

  ApiKey:
    Type: AWS::SSM::Parameter::Value<SecureString>
    Default: /myapp/external-api/key
    Description: API key from SSM Parameter Store

Outputs and Cross-Stack References

Export/Import Patterns

# Stack A - Network Stack
AWSTemplateFormatVersion: 2010-09-09
Description: Network infrastructure stack

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsHostnames: true
      EnableDnsSupport: true
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-vpc"

Outputs:
  VPCId:
    Description: VPC ID
    Value: !Ref VPC
    Export:
      Name: !Sub "${AWS::StackName}-VPCId"

  PublicSubnetIds:
    Description: Public subnet IDs
    Value: !Join [",", [!Ref PublicSubnet1, !Ref PublicSubnet2]]
    Export:
      Name: !Sub "${AWS::StackName}-PublicSubnetIds"

  PrivateSubnetIds:
    Description: Private subnet IDs
    Value: !Join [",", [!Ref PrivateSubnet1, !Ref PrivateSubnet2]]
    Export:
      Name: !Sub "${AWS::StackName}-PrivateSubnetIds"

  LambdaSecurityGroupId:
    Description: Security group ID for Lambda
    Value: !Ref LambdaSecurityGroup
    Export:
      Name: !Sub "${AWS::StackName}-LambdaSecurityGroupId"
# Stack B - Application Stack (imports from Stack A)
AWSTemplateFormatVersion: 2010-09-09
Description: Lambda application stack

Parameters:
  NetworkStackName:
    Type: String
    Default: network-stack
    Description: Name of the network stack

Resources:
  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-processor"
      Runtime: python3.11
      Handler: index.handler
      Code:
        S3Bucket: !Ref CodeBucket
        S3Key: lambda/function.zip
      Role: !GetAtt LambdaExecutionRole.Arn
      VpcConfig:
        SecurityGroupIds:
          - !ImportValue
            !Sub "${NetworkStackName}-LambdaSecurityGroupId"
        SubnetIds:
          - !Select [0, !Split [",", !ImportValue !Sub "${NetworkStackName}-PrivateSubnetIds"]]
          - !Select [1, !Split [",", !ImportValue !Sub "${NetworkStackName}-PrivateSubnetIds"]]

Nested Stacks for Modularity

AWSTemplateFormatVersion: 2010-09-09
Description: Main stack with nested Lambda stacks

Resources:
  # Nested stack for Lambda functions
  LambdaFunctionsStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://s3.amazonaws.com/bucket/lambda-functions.yaml
      TimeoutInMinutes: 15
      Parameters:
        Environment: !Ref Environment
        FunctionNamePrefix: !Ref FunctionNamePrefix

  # Nested stack for API Gateway
  ApiGatewayStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://s3.amazonaws.com/bucket/api-gateway.yaml
      TimeoutInMinutes: 15
      Parameters:
        Environment: !Ref Environment
        LambdaFunctionArn: !GetAtt LambdaFunctionsStack.Outputs.FunctionArn

Lambda Functions with Advanced Configurations

Lambda Base with VPC and Environment

AWSTemplateFormatVersion: 2010-09-09
Description: Lambda function with VPC, environment variables, and monitoring

Parameters:
  Environment:
    Type: String
    Default: dev
    AllowedValues:
      - dev
      - staging
      - production

  VpcConfig:
    Type: String
    Default: full
    AllowedValues:
      - none
      - full
      - internal

Resources:
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-lambda-role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-vpc-policy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - ec2:CreateNetworkInterface
                  - ec2:DescribeNetworkInterfaces
                  - ec2:DeleteNetworkInterface
                Resource: "*"
        - PolicyName: !Sub "${AWS::StackName}-secrets-policy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - secretsmanager:GetSecretValue
                Resource: !Ref SecretsArn

  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-processor"
      Runtime: python3.11
      Handler: index.handler
      Code:
        S3Bucket: !Ref CodeBucket
        S3Key: !Sub "lambda/${Environment}/function.zip"
      MemorySize: 256
      Timeout: 60
      Role: !GetAtt LambdaExecutionRole.Arn
      VpcConfig:
        !If
          - IsFullVpc
          - SecurityGroupIds:
              - !Ref LambdaSecurityGroup
            SubnetIds:
              - !Ref PrivateSubnet1
              - !Ref PrivateSubnet2
          - !Ref AWS::NoValue
      Environment:
        Variables:
          ENVIRONMENT: !Ref Environment
          LOG_LEVEL: !If [IsProduction, INFO, DEBUG]
          DB_HOST: !Ref DatabaseHost
          DB_NAME: !Ref DatabaseName
      TracingConfig:
        Mode: !If [IsProduction, Active, PassThrough]
      Tags:
        - Key: Environment
          Value: !Ref Environment
        - Key: Project
          Value: !Ref ProjectName
        - Key: CostCenter
          Value: !Ref CostCenter

  LambdaFunctionUrl:
    Type: AWS::Lambda::Url
    Properties:
      AuthType: AWS_IAM
      TargetFunctionArn: !GetAtt MyLambdaFunction.Arn
      Cors:
        AllowCredentials: true
        AllowHeaders:
          - "*"
        AllowMethods:
          - GET
          - POST
        AllowOrigins:
          - !If [IsProduction, !Ref ProductionCorsOrigin, "*"]
        MaxAge: 86400

Conditions:
  IsFullVpc: !Equals [!Ref VpcConfig, full]
  IsProduction: !Equals [!Ref Environment, production]

Lambda with Provisioned Concurrency

Resources:
  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-api"
      Runtime: python3.11
      Handler: app.handler
      Code:
        S3Bucket: !Ref CodeBucket
        S3Key: lambda/api.zip
      MemorySize: 512
      Timeout: 30
      Role: !GetAtt LambdaExecutionRole.Arn

  ProvisionedConcurrencyConfig:
    Type: AWS::Lambda::ProvisionedConcurrencyConfig
    Properties:
      FunctionName: !Ref MyLambdaFunction
      ProvisionedConcurrentExecutions: 5
      ProvisionedExecutionTarget:
        AllocationStrategy: PRICE_OPTIMIZED

Lambda Layers

AWSTemplateFormatVersion: 2010-09-09
Description: Lambda function with layers

Resources:
  CommonLibraryLayer:
    Type: AWS::Lambda::LayerVersion
    Properties:
      LayerName: !Sub "${AWS::StackName}-common-lib"
      Description: Common utilities for Lambda functions
      Content:
        S3Bucket: !Ref LayersBucket
        S3Key: layers/common-lib.zip
      CompatibleRuntimes:
        - python3.9
        - python3.10
        - python3.11
      CompatibleArchitectures:
        - x86_64
        - arm64

  DataProcessingLayer:
    Type: AWS::Lambda::LayerVersion
    Properties:
      LayerName: !Sub "${AWS::StackName}-data-processing"
      Description: Data processing utilities
      Content:
        S3Bucket: !Ref LayersBucket
        S3Key: layers/data-processing.zip
      CompatibleRuntimes:
        - python3.11

  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-processor"
      Runtime: python3.11
      Handler: index.handler
      Code:
        S3Bucket: !Ref CodeBucket
        S3Key: lambda/processor.zip
      Layers:
        - !Ref CommonLibraryLayer
        - !Ref DataProcessingLayer

API Gateway Integration

API Gateway REST with Lambda Proxy

AWSTemplateFormatVersion: 2010-09-09
Description: API Gateway REST with Lambda proxy integration

Resources:
  ApiGatewayRestApi:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Name: !Sub "${AWS::StackName}-api"
      Description: REST API for Lambda backend
      EndpointConfiguration:
        Types:
          - REGIONAL
      MinimumCompressionSize: 1024
      DisableExecuteApiEndpoint: false

  ApiGatewayResource:
    Type: AWS::ApiGateway::Resource
    Properties:
      RestApiId: !Ref ApiGatewayRestApi
      ParentId: !GetAtt ApiGatewayRestApi.RootResourceId
      PathPart: items

  ApiGatewayMethod:
    Type: AWS::ApiGateway::Method
    Properties:
      RestApiId: !Ref ApiGatewayRestApi
      ResourceId: !Ref ApiGatewayResource
      HttpMethod: GET
      AuthorizationType: COGNITO_USER_POOLS
      AuthorizerId: !Ref ApiGatewayAuthorizer
      RequestParameters:
        method.request.querystring.id: true
      Integration:
        Type: AWS_PROXY
        IntegrationHttpMethod: POST
        Uri: !Sub "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyLambdaFunction.Arn}/invocations"
        IntegrationResponses:
          - StatusCode: 200
            ResponseParameters:
              method.response.header.Access-Control-Allow-Origin: "'*'"
              method.response.header.Content-Type: "'application/json'"
        PassthroughBehavior: WHEN_NO_MATCH
      MethodResponses:
        - StatusCode: 200
          ResponseModels:
            application/json: Empty
          ResponseParameters:
            method.response.header.Access-Control-Allow-Origin: true

  ApiGatewayDeployment:
    Type: AWS::ApiGateway::Deployment
    DependsOn: ApiGatewayMethod
    Properties:
      RestApiId: !Ref ApiGatewayRestApi
      StageName: !Ref DeployStage
      StageDescription:
        LoggingLevel: !If [IsProduction, INFO, ERROR]
        DataTraceEnabled: !If [IsProduction, false, true]
        MetricsEnabled: true
        ThrottlingRateLimit: 100
        ThrottlingBurstLimit: 200
      Variables:
        Environment: !Ref Environment

  LambdaPermission:
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName: !Ref MyLambdaFunction
      Action: lambda:InvokeFunction
      Principal: apigateway.amazonaws.com
      SourceArn: !Sub "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${ApiGatewayRestApi}/*/*/*"

  ApiGatewayAuthorizer:
    Type: AWS::ApiGateway::Authorizer
    Properties:
      Name: !Sub "${AWS::StackName}-authorizer"
      Type: COGNITO_USER_POOLS
      RestApiId: !Ref ApiGatewayRestApi
      ProviderARNs:
        - !Ref CognitoUserPoolArn
      IdentitySource: method.request.header.Authorization
      AuthorizerResultTtlInSeconds: 300

Outputs:
  ApiEndpoint:
    Description: API Gateway endpoint URL
    Value: !Sub "https://${ApiGatewayRestApi}.execute-api.${AWS::Region}.amazonaws.com/${DeployStage}/items"

API Gateway HTTP API with Lambda

Resources:
  HttpApi:
    Type: AWS::ApiGatewayV2::Api
    Properties:
      Name: !Sub "${AWS::StackName}-http-api"
      ProtocolType: HTTP
      CorsConfiguration:
        AllowOrigins:
          - !If [IsProduction, !Ref ProductionDomain, "*"]
        AllowMethods:
          - GET
          - POST
          - PUT
          - DELETE
          - OPTIONS
        AllowHeaders:
          - "*"
        MaxAge: 86400

  HttpApiStage:
    Type: AWS::ApiGatewayV2::Stage
    Properties:
      ApiId: !Ref HttpApi
      StageName: !Ref DeployStage
      AutoDeploy: true
      DefaultRouteSettings:
        DetailedMetricsEnabled: true
        ThrottlingBurstLimit: 100
        ThrottlingRateLimit: 50

  HttpApiIntegration:
    Type: AWS::ApiGatewayV2::Integration
    Properties:
      ApiId: !Ref HttpApi
      IntegrationType: AWS_PROXY
      IntegrationUri: !Sub "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyLambdaFunction.Arn}/invocations"
      PayloadFormatVersion: "2.0"

  HttpApiRoute:
    Type: AWS::ApiGatewayV2::Route
    Properties:
      ApiId: !Ref HttpApi
      RouteKey: ANY /items/{id}
      Target: !Sub "integrations/${HttpApiIntegration.Id}"

Event Sources

SQS Event Source

Resources:
  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-sqs-processor"
      Runtime: python3.11
      Handler: sqs_handler.handler
      Code:
        S3Bucket: !Ref CodeBucket
        S3Key: lambda/sqs-processor.zip
      Timeout: 300
      Role: !GetAtt LambdaExecutionRole.Arn

  Queue:
    Type: AWS::SQS::Queue
    Properties:
      QueueName: !Sub "${AWS::StackName}-queue"
      VisibilityTimeout: 360
      MessageRetentionPeriod: 1209600
      RedrivePolicy:
        deadLetterTargetArn: !GetAtt DeadLetterQueue.Arn
        maxReceiveCount: 5

  DeadLetterQueue:
    Type: AWS::SQS::Queue
    Properties:
      QueueName: !Sub "${AWS::StackName}-dlq"

  EventSourceMapping:
    Type: AWS::Lambda::EventSourceMapping
    Properties:
      FunctionName: !Ref MyLambdaFunction
      EventSourceArn: !GetAtt Queue.Arn
      BatchSize: 10
      MaximumBatchingWindowInSeconds: 60
      ScalingConfig:
        MaximumConcurrency: 10
      FilterCriteria:
        Filters:
          - Pattern: '{"body": {"messageType": ["order", "notification"]}}'
      Enabled: true

  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-sqs-role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaSQSQueueExecutionRole
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-dlq-policy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - sqs:DeleteMessage
                  - sqs:ReceiveMessage
                Resource: !GetAtt DeadLetterQueue.Arn

SNS Event Source

Resources:
  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-sns-processor"
      Runtime: python3.11
      Handler: sns_handler.handler
      Code:
        S3Bucket: !Ref CodeBucket
        S3Key: lambda/sns-processor.zip

  Topic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: !Sub "${AWS::StackName}-topic"
      DisplayName: !Sub "${AWS::StackName} Notifications"
      Subscription:
        - Endpoint: !GetAtt MyLambdaFunction.Arn
          Protocol: lambda
      Tags:
        - Key: Environment
          Value: !Ref Environment

  TopicPolicy:
    Type: AWS::SNS::TopicPolicy
    Properties:
      Topics:
        - !Ref Topic
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: sns.amazonaws.com
            Action: sns:Publish
            Resource: !Ref Topic

  LambdaPermission:
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName: !Ref MyLambdaFunction
      Action: lambda:InvokeFunction
      Principal: sns.amazonaws.com
      SourceArn: !Ref Topic

EventBridge (CloudWatch Events)

Resources:
  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-scheduler"
      Runtime: python3.11
      Handler: scheduler.handler
      Code:
        S3Bucket: !Ref CodeBucket
        S3Key: lambda/scheduler.zip
      Timeout: 300
      Role: !GetAtt LambdaExecutionRole.Arn

  ScheduledRule:
    Type: AWS::Events::Rule
    Properties:
      Name: !Sub "${AWS::StackName}-scheduled-rule"
      ScheduleExpression: "rate(5 minutes)"
      State: ENABLED
      Targets:
        - Id: !Ref MyLambdaFunction
          Arn: !GetAtt MyLambdaFunction.Arn
          RetryPolicy:
            MaximumEventAgeInSeconds: 86400
            MaximumRetryAttempts: 3

  LambdaPermission:
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName: !Ref MyLambdaFunction
      Action: lambda:InvokeFunction
      Principal: events.amazonaws.com
      SourceArn: !GetAtt ScheduledRule.Arn

S3 Event Source

Resources:
  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-s3-processor"
      Runtime: python3.11
      Handler: s3_handler.handler
      Code:
        S3Bucket: !Ref CodeBucket
        S3Key: lambda/s3-processor.zip
      Timeout: 300
      Role: !GetAtt LambdaExecutionRole.Arn

  Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub "${AWS::StackName}-uploads-${AWS::AccountId}-${AWS::Region}"
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: AES256
      VersioningConfiguration:
        Status: Enabled
      NotificationConfiguration:
        LambdaConfigurations:
          - Event: s3:ObjectCreated:*
            Filter:
              S3Key:
                Rules:
                  - Name: suffix
                    Value: .csv
            Function: !GetAtt MyLambdaFunction.Arn
          - Event: s3:ObjectCreated:*
            Filter:
              S3Key:
                Rules:
                  - Name: prefix
                    Value: processed/
            Function: !GetAtt MyLambdaFunction.Arn

  LambdaPermission:
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName: !Ref MyLambdaFunction
      Action: lambda:InvokeFunction
      Principal: s3.amazonaws.com
      SourceArn: !GetAtt Bucket.Arn

Step Functions Integration

AWSTemplateFormatVersion: 2010-09-09
Description: Step Functions with Lambda tasks

Resources:
  # Lambda functions for Step Functions
  ProcessItemFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-process-item"
      Runtime: python3.11
      Handler: process_item.handler
      Code:
        S3Bucket: !Ref CodeBucket
        S3Key: lambda/process-item.zip
      Timeout: 300
      Role: !GetAtt LambdaExecutionRole.Arn

  ValidateItemFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-validate-item"
      Runtime: python3.11
      Handler: validate_item.handler
      Code:
        S3Bucket: !Ref CodeBucket
        S3Key: lambda/validate-item.zip
      Timeout: 60
      Role: !GetAtt LambdaExecutionRole.Arn

  NotifyCompletionFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-notify-completion"
      Runtime: python3.11
      Handler: notify.handler
      Code:
        S3Bucket: !Ref CodeBucket
        S3Key: lambda/notify.zip
      Timeout: 60
      Role: !GetAtt LambdaExecutionRole.Arn

  # Step Functions State Machine
  ProcessingStateMachine:
    Type: AWS::StepFunctions::StateMachine
    Properties:
      StateMachineName: !Sub "${AWS::StackName}-processor"
      StateMachineType: STANDARD
      DefinitionString: !Sub |
        {
          "Comment": "Item processing state machine",
          "StartAt": "ValidateItem",
          "States": {
            "ValidateItem": {
              "Type": "Task",
              "Resource": "${ValidateItemFunction.Arn}",
              "Retry": [
                {
                  "ErrorEquals": ["States.TaskFailed"],
                  "IntervalSeconds": 2,
                  "MaxAttempts": 3,
                  "BackoffRate": 2
                }
              ],
              "Next": "ProcessItem"
            },
            "ProcessItem": {
              "Type": "Task",
              "Resource": "${ProcessItemFunction.Arn}",
              "Retry": [
                {
                  "ErrorEquals": ["States.TaskFailed"],
                  "IntervalSeconds": 5,
                  "MaxAttempts": 2,
                  "BackoffRate": 2
                }
              ],
              "Catch": [
                {
                  "ErrorEquals": ["States.ALL"],
                  "Next": "HandleFailure"
                }
              ],
              "Next": "NotifyCompletion"
            },
            "NotifyCompletion": {
              "Type": "Task",
              "Resource": "${NotifyCompletionFunction.Arn}",
              "End": true
            },
            "HandleFailure": {
              "Type": "Pass",
              "End": true
            }
          }
        }
      RoleArn: !GetAtt StepFunctionsExecutionRole.Arn
      LoggingConfiguration:
        Level: ALL
        IncludeExecutionData: true
        Destinations:
          - CloudWatchLogsLogGroup: !Ref StateMachineLogGroup

  StepFunctionsExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${AWS::StackName}-sfn-role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: states.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-lambda-invoke"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - lambda:InvokeFunction
                Resource:
                  - !GetAtt ProcessItemFunction.Arn
                  - !GetAtt ValidateItemFunction.Arn
                  - !GetAtt NotifyCompletionFunction.Arn

  StateMachineLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/state-machine/${AWS::StackName}"
      RetentionInDays: 30

Cold Start Optimization

AWSTemplateFormatVersion: 2010-09-09
Description: Lambda function optimized for cold start

Parameters:
  Environment:
    Type: String
    Default: dev
    AllowedValues:
      - dev
      - staging
      - production

Resources:
  # Use AWS::Serverless::Function for better cold start
  OptimizedLambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-optimized"
      CodeUri: s3://bucket/function.zip
      Handler: app.handler
      Runtime: python3.11
      MemorySize: 512
      Timeout: 30
      EphemeralStorage:
        Size: 1024
      SnapStart:
        ApplyOn: PublishedVersions
      ProvisionedConcurrencyConfig:
        ProvisionedConcurrentExecutions: !If [IsProduction, 5, 0]
      Layers:
        - !Ref CommonDependenciesLayer
      Environment:
        Variables:
          PYTHONPATH: "/var/task:/opt"
      Policies:
        - AWSLambdaVPCAccessExecutionRole
        - AmazonS3ReadOnlyAccess
      VpcConfig:
        SecurityGroupIds:
          - !Ref LambdaSecurityGroup
        SubnetIds: !Ref PrivateSubnetIds
      EventInvokeConfig:
        MaximumEventAgeInSeconds: 3600
        MaximumRetryAttempts: 2

  # Optimized layer with pre-installed dependencies
  CommonDependenciesLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      LayerName: !Sub "${AWS::StackName}-dependencies"
      Description: Pre-installed Python dependencies for Lambda
      ContentUri: s3://bucket/layers/dependencies.zip
      CompatibleRuntimes:
        - python3.11
      CompatibleArchitectures:
        - x86_64
      RetentionPolicy: Retain

Conditions:
  IsProduction: !Equals [!Ref Environment, production]

Outputs:
  FunctionArn:
    Description: Lambda function ARN
    Value: !GetAtt OptimizedLambdaFunction.Arn
  FunctionUrl:
    Description: Lambda function URL for direct invocation
    Value: !GetAtt OptimizedLambdaFunction.Url

Monitoring and Logging

AWSTemplateFormatVersion: 2010-09-09
Description: Lambda with comprehensive monitoring

Resources:
  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-monitored"
      Runtime: python3.11
      Handler: app.handler
      Code:
        S3Bucket: !Ref CodeBucket
        S3Key: lambda/function.zip
      Role: !GetAtt LambdaExecutionRole.Arn
      TracingConfig:
        Mode: Active

  # Log group with retention
  LambdaLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/lambda/${AWS::StackName}-monitored"
      RetentionInDays: 30
      KmsKeyId: !Ref LogKmsKey

  # Metric filter for errors
  ErrorMetricFilter:
    Type: AWS::Logs::MetricFilter
    Properties:
      LogGroupName: !Ref LambdaLogGroup
      FilterPattern: 'ERROR'
      MetricTransformations:
        - MetricValue: "1"
          MetricNamespace: !Sub "${AWS::StackName}/Lambda"
          MetricName: ErrorCount

  # CloudWatch Alarms
  HighErrorRateAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName: !Sub "${AWS::StackName}-high-error-rate"
      AlarmDescription: Alert when error rate exceeds threshold
      MetricName: Errors
      Namespace: AWS/Lambda
      Dimensions:
        - Name: FunctionName
          Value: !Ref MyLambdaFunction
      Statistic: Sum
      Period: 60
      EvaluationPeriods: 5
      Threshold: 10
      ComparisonOperator: GreaterThanThreshold
      AlarmActions:
        - !Ref AlertTopic

  HighThrottlesAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName: !Sub "${AWS::StackName}-high-throttles"
      AlarmDescription: Alert when throttling occurs
      MetricName: Throttles
      Namespace: AWS/Lambda
      Dimensions:
        - Name: FunctionName
          Value: !Ref MyLambdaFunction
      Statistic: Sum
      Period: 60
      EvaluationPeriods: 3
      Threshold: 5
      ComparisonOperator: GreaterThanThreshold

  AlertTopic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: !Sub "${AWS::StackName}-alerts"

  # Lambda Destination for async invocations
  LambdaDestination:
    Type: AWS::Lambda::EventInvokeConfig
    Properties:
      FunctionName: !Ref MyLambdaFunction
      MaximumEventAgeInSeconds: 3600
      MaximumRetryAttempts: 2
      Qualifier: $LATEST

Conditions and Transform

Conditions for Environment-Specific Resources

AWSTemplateFormatVersion: 2010-09-09
Description: Lambda with conditional resources

Parameters:
  Environment:
    Type: String
    Default: dev
    AllowedValues:
      - dev
      - staging
      - production
    Description: Deployment environment

Conditions:
  IsProduction: !Equals [!Ref Environment, production]
  IsStaging: !Equals [!Ref Environment, staging]
  CreateDeadLetterQueue: !Or [!Equals [!Ref Environment, staging], !Equals [!Ref Environment, production]]
  EnableXray: !Not [!Equals [!Ref Environment, dev]]

Resources:
  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-function"
      Runtime: python3.11
      Handler: app.handler
      Code:
        S3Bucket: !Ref CodeBucket
        S3Key: !Sub "lambda/${Environment}/function.zip"
      Timeout: !If [IsProduction, 60, 30]
      MemorySize: !If [IsProduction, 512, 256]
      Role: !GetAtt LambdaExecutionRole.Arn
      TracingConfig: !If
        - EnableXray
        - Mode: Active
        - !Ref AWS::NoValue
      Environment:
        Variables:
          LOG_LEVEL: !If [IsProduction, INFO, DEBUG]

  DeadLetterQueue:
    Type: AWS::SQS::Queue
    Condition: CreateDeadLetterQueue
    Properties:
      QueueName: !Sub "${AWS::StackName}-dlq"

Transform for Code Reuse

AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31

Description: Using SAM Transform for Lambda

Globals:
  Function:
    Timeout: 30
    Runtime: python3.11
    Tracing: Active
    Environment:
      Variables:
        LOG_LEVEL: INFO
    Metadata:
      DockerBuild: true
      Dockerfile: Dockerfile
      DockerContext: lambda_function/

Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-sam-function"
      Handler: app.handler
      CodeUri: lambda_function/
      Policies:
        - S3ReadPolicy:
            BucketName: !Ref DataBucket
        - DynamoDBReadPolicy:
            TableName: !Ref DataTable
      Events:
        Api:
          Type: Api
          Properties:
            Path: /items
            Method: get
        SqsQueue:
          Type: SQS
          Properties:
            Queue: !GetAtt Queue.Arn
            BatchSize: 10
      AutoPublishAlias: !Ref Environment
      DeploymentPreference:
        Type: !Ref DeploymentConfig
        Alarms:
          - !Ref ErrorAlarm
          - !Ref LatencyAlarm

  DataTable:
    Type: AWS::Serverless::SimpleTable
    Properties:
      TableName: !Sub "${AWS::StackName}-table"
      PrimaryKey:
        Name: id
        Type: String

Parameters:
  Environment:
    Type: String
    Default: dev
  DeploymentConfig:
    Type: String
    Default: AllAtOnce
    AllowedValues:
      - Canary10Percent5Minutes
      - Canary10Percent10Minutes
      - Canary10Percent15Minutes
      - AllAtOnce
      - Linear10PercentEvery1Minute
      - Linear10PercentEvery2Minutes
      - Linear10PercentEvery3Minutes

Best Practices

Security

  • Use IAM roles with minimum necessary permissions
  • Encrypt environment variables with KMS
  • Use VPC for private resource access
  • Configure resource-based policies for invocations
  • Enable AWS WAF for API Gateway protection
  • Use API keys and throttling for protection

Performance

  • Choose memory size based on profiling
  • Use provisioned concurrency for critical latency
  • Optimize package size for cold start
  • Use layers for shared dependencies
  • Pre-compile code for interpreted languages
  • Consider SnapStart for Java/.NET

Monitoring

  • Enable detailed metrics and tracing
  • Configure appropriate log retention
  • Create alarms for errors and throttling
  • Use Lambda destinations for async error handling
  • Implement distributed tracing

Deployment

  • Use change sets before deployment
  • Test templates with cfn-lint
  • Organize stacks by lifecycle and ownership
  • Use nested stacks for modularity
  • Implement blue/green deployments

CloudFormation Stack Management Best Practices

Stack Policies

Stack policies protect stack resources from unintentional updates that could cause critical changes or deletions.

Resources:
  LambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      # Function configuration

# Stack policy to protect Lambda function from updates
StackPolicy:
  Type: AWS::CloudFormation::StackPolicy
  Properties:
    PolicyDocument:
      Version: '2012-10-17'
      Statement:
        - Effect: Allow
          Principal: "*"
          Action: "Update:*"
          Resource: "*"
        - Effect: Deny
          Principal: "*"
          Action:
            - Update:Replace
            - Update:Delete
          Resource:
            - LogicalId: LambdaFunction
              ResourceType: AWS::Lambda::Function
          Condition:
            StringEquals:
              ResourceAttribute: Arn:
                Fn::Ref: LambdaFunction

Termination Protection

Enable termination protection to prevent accidental stack deletion, especially for production environments.

AWSTemplateFormatVersion: 2010-09-09
Description: Lambda function with termination protection

Resources:
  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-function"
      Runtime: python3.11
      Handler: app.handler
      Code:
        S3Bucket: !Ref CodeBucket
        S3Key: lambda/function.zip
      Role: !GetAtt LambdaExecutionRole.Arn

# Enable termination protection (must be set during stack creation)
# This is a stack-level attribute, not a resource

Important: Termination protection must be enabled during stack creation via AWS Console, CLI, or API:

aws cloudformation create-stack \
  --stack-name my-lambda-stack \
  --template-body file://template.yaml \
  --enable-termination-protection \
  --capabilities CAPABILITY_IAM

Drift Detection

Detect when infrastructure has diverged from the CloudFormation template.

Resources:
  # All Lambda resources support drift detection
  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-function"
      Runtime: python3.11
      Handler: app.handler
      Code:
        S3Bucket: !Ref CodeBucket
        S3Key: lambda/function.zip
      Role: !GetAtt LambdaExecutionRole.Arn
      Environment:
        Variables:
          ENVIRONMENT: !Ref Environment
          LOG_LEVEL: !Ref LogLevel

CLI commands for drift detection:

# Detect drift on a stack
aws cloudformation detect-drift --stack-name my-lambda-stack

# Get drift detection status
aws cloudformation describe-stack-drift-detection-status \
  --stack-drift-detection-id <detection-id>

# Get resource drift status
aws cloudformation describe-stack-resource-drifts \
  --stack-name my-lambda-stack

# Compare actual vs expected resource properties
aws cloudformation get-stack-policy --stack-name my-lambda-stack

Change Sets

Use change sets to preview and review stack changes before execution.

Resources:
  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-function"
      Runtime: python3.11
      Handler: app.handler
      Code:
        S3Bucket: !Ref CodeBucket
        S3Key: lambda/function.zip
      Role: !GetAtt LambdaExecutionRole.Arn
      MemorySize: !Ref MemorySize
      Timeout: !Ref Timeout

Parameters:
  MemorySize:
    Type: Number
    Default: 256
    Description: Memory allocation in MB

  Timeout:
    Type: Number
    Default: 30
    Description: Function timeout in seconds

Change set workflow:

# 1. Create a change set
aws cloudformation create-change-set \
  --stack-name my-lambda-stack \
  --change-set-name my-changeset \
  --template-body file://template.yaml \
  --capabilities CAPABILITY_IAM \
  --parameters ParameterKey=MemorySize,ParameterValue=512

# 2. Describe the change set to review changes
aws cloudformation describe-change-set \
  --stack-name my-lambda-stack \
  --change-set-name my-changeset

# 3. Execute the change set
aws cloudformation execute-change-set \
  --stack-name my-lambda-stack \
  --change-set-name my-changeset

# Or delete if changes are not acceptable
aws cloudformation delete-change-set \
  --stack-name my-lambda-stack \
  --change-set-name my-changeset

Change set types:

  • CREATE: For new stacks
  • UPDATE: For existing stacks
  • IMPORT: For importing existing resources

Related Resources

Additional Files

For complete details on resources and their properties, see:

  • REFERENCE.md – Detailed reference guide for all CloudFormation resources
  • EXAMPLES.md – Complete production-ready examples