Deployment of Serverless Applications through AWS SAM Pipeline

Deployment of Serverless Applications through AWS SAM Pipeline

Photo by JJ Ying on Unsplash

Introduction

SAM CLI provides a capability called "AWS SAM Pipeline" using which we would be able to automatically create Deployment pipelines for Serverless applications.

SAM Pipeline facilitates creating "Secure Continuous Integration Continuous Delivery(CI/CD) Pipeline" very easily by selecting set of options through the SAM CLI.

AWS SAM Pipeline provides templates for popular CI/CD systems as: Jenkins, GitLab CI/CD, GitHub Actions, BitBucket Pipelines, AWS CodePipeline

My SAM Pipeline Deployment

The SAM Pipeline deployment I have done is part of my project ** "Cloud Resume Challenge - AWS" ** available at link

** Create Serverless application stack consisting of "API Gateway" API, Lambda function, DynamoDB Table**

A) Deploy SAM Pipeline using GitHub Actions(2 stage deployment)

To learn how to step by step Deploy Serverless applications through SAM Pipeline using GitHub Actions, refer below AWS blog

**Click here **

For creating my stack have made few changes as mentioned below.

  1. Parameter overriding for Application stack:

This is to pass the parameters from the Parent stack(Pipeline stack) to the Child stack(Application stack)

a) As mentioned in the AWS blog once you run "sam init", samconfig.toml gets created as shown

image.png

Add entry into samconfig.toml for **default.deploy.parameters **if you want to pass the parameters from the Parent stack(Pipeline stack) to the Child stack(Application stack) as shown

version = 0.1
[default]
[default.deploy]
[default.deploy.parameters]
parameter_overrides= "DynamoDBTableName=VisitorCount ACMCertARN=arn:aws:acm:us-east-1:467069435281:certificate/03127741-610e-4062-95c2-450b614918de ApiDomainName=visitorcountapi.stareventhorizon.com R53HostedZoneId=Z02531016FA5JXCA3QJQ ApiPathMapping=Prod"
capabilities = "CAPABILITY_IAM"

b) Once samconfig.toml is updated you can run following

sam pipeline bootstrap --config-file ./samconfig.toml
sam pipeline init --config-file ./samconfig.toml

c) Remaining steps to be followed as mentioned in the AWS blog

2) Snippet of SAM CLI Pipeline configuration

image.png

image.png

image.png

3) Application stack Template(template.yaml)

Here we create resources: "API Gateway" API with Custom Domain, Lambda function with Python implementation and DynamoDB Table

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: 'Maintains My Website Visitor Count
  '

Parameters:
  DynamoDBTableName:
    Description: DynamoDB Table Name
    Type: String

  ACMCertARN:
    Description: ACM CloudFront Certificate ARN
    Type: String

  ApiDomainName:
    Description: Custom Domain name for your API
    Type: String

  R53HostedZoneId:
    Description: Route 53 Hosted Zone Name
    Type: String

  ApiPathMapping:
    Description: Path Mapping for API
    Type: String
    Default: Prod

Resources:
  VisitorCountTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: !Ref DynamoDBTableName
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
      - AttributeName: Label
        AttributeType: S
      KeySchema:
      - AttributeName: Label
        KeyType: HASH

  VisitorCountApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      Domain:
        DomainName: !Ref ApiDomainName
        CertificateArn: !Ref ACMCertARN
        EndpointConfiguration: EDGE
        Route53:
          HostedZoneId: !Ref R53HostedZoneId
          EvaluateTargetHealth: true
        BasePath: 
        - !Ref ApiPathMapping
      Cors:
        AllowMethods: "'*'"
        AllowHeaders: "'*'"
        AllowOrigin: "'*'"

  VisitorCountFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: VisitorCountFunction
      Handler: app.lambda_handler
      Runtime: python3.9
      Environment:
        Variables:
          DynamoDBTableName: !Ref VisitorCountTable      
      Architectures:
        - x86_64      
      Policies:
       - DynamoDBWritePolicy:
          TableName: !Ref VisitorCountTable 
       - DynamoDBReadPolicy:
          TableName: !Ref VisitorCountTable  
      Events:
        VisitorCount:
          Type: Api
          Properties:
            Path: /visitorcount
            Method: ANY
            RestApiId: !Ref VisitorCountApi

Outputs:
  ApiVisitorCountURL:
    Description: API Gateway endpoint URL for Prod stage for Getting Visitor count
    Value:
      Fn::Sub: https://${VisitorCountApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/visitorcount/

image.png

**NOTE: **SAM Pipeline expects template.yaml, so template.yml doesnt work

image.png

  1. Once the SAM Pipeline configuration is completed, you can checkin the code into corresponding GitHub Repo which will trigger the pipeline.

Under GitHub Repo -> Actions we can see the deployment progress and logs

image.png

image.png

Parameters overriden can be seen in the logs

image.png

So now next time onwards whenever file changes happen in the GitHub repo, AWS SAM Pipeline would be triggered which will deploy the Application stack

B) Deploy SAM Pipeline using AWS CodePipeline(2 stage deployment)

  1. Start similar to "Deploy SAM Pipeline using GitHub Actions" by running below command(Note: Prior to running below command "sam init" needs to be run to create the serverless application directory structure)
sam pipeline init –bootstrap

While running above command -> Branch to be selected is Master, if its any other feature branch for you check it in AWS CodeCommit and specify the same

  1. Once above command is completed, following files gets created

image.png

image.png

  1. Parameter overriding for Application stack

This is to pass the parameters from the Parent stack(Pipeline stack) to the Child stack(Application stack)

In new created pipeline\buildspec_deploy.yaml, add paramater overrides as below(which will be referred by the Application stack)

version: 0.2
phases:
  install:
    runtime-versions:
      python: 3.8
    commands:
      - pip install --upgrade pip
      - pip install --upgrade awscli aws-sam-cli
  build:
    commands:
      - . ./assume-role.sh ${ENV_PIPELINE_EXECUTION_ROLE} deploy
      - sam deploy --stack-name ${ENV_STACK_NAME}
                    --template ${ENV_TEMPLATE}
                    --capabilities CAPABILITY_IAM
                    --region ${ENV_REGION}
                    --s3-bucket ${ENV_BUCKET}
                    --no-fail-on-empty-changeset
                    --role-arn ${ENV_CLOUDFORMATION_EXECUTION_ROLE}
                    --parameter-overrides DynamoDBTableName=VisitorCount ACMCertARN=arn:aws:acm:us-east-1:467069435281:certificate/03127741-610e-4062-95c2-450b614918de ApiDomainName=visitorcountapi.stareventhorizon.com R53HostedZoneId=Z02531016FA5JXCA3QJQ ApiPathMapping=Prod
  1. Checkin all your application code into the AWS CodeCommit Repo

  2. Deploy the AWS CodePipeline

sam deploy -t codepipeline.yaml --stack-name resume-sam-pipeline-test --capabilities=CAPABILITY_IAM

image.png

image.png

Once the Pipeline stack is created in AWS CloudFormation, Pipeline will be deployed and started automatically

image.png

image.png

image.png

So now next time onwards whenever file changes happen in the AWS CodeCommit repo, SAM Pipeline would be triggered which will deploy the Application stack.

Conclusion

As AWS SAM Pipeline was part of my project "Cloud Resume Challenge - AWS", have attempted to give an overview of the SAM Pipeline deployment to get started with, which facilitates easy creation of Secure CI/CD Pipeline for Serverless applications.