DEV Community

Cover image for 12. Infrastructure as Code
jicoing
jicoing

Posted on • Updated on

12. Infrastructure as Code

Using AWS SAM to deploy the infrastructure.

Previously I had deployed the API Gateway, Lambda function and DynamoDB table by tinkering around in the AWS console. However the real challenge was using SAM to deploy the entire infrastructure using the SAM template for my bio.

AWS Serverless Architecture Model

AWS Serverless Application Model (SAM) deploys=> DynamoDB + Lambda function + API gateway.

Git: https://github.com/jicoing/git-komlalebu-sam
Alt Text

  • Step 1 - Prerequisites The system must have the below installed:

AWS profile set up
Python, preferably version > 3.6
AWS SAM CLI
Docker

  • Step 2 - Create new AWS SAM project
    Using the below command in cmd for windows.

    CMD

                      sam init
    

Alt Text

I chose the default project name, with the quick start template for Hello World application. This created a directory structure that looks like this.

Alt Text

The application uses several AWS resources, including Lambda functions and an API Gateway API. These resources are defined in the template.yaml file in this sam-app directory. I modified the directory a little bit to remove the default /hello_world directory and created my own lambda handler /komla_function directory containing my python code.

Alt Text

Tree:

📦sam-app
┣ 📂.aws-sam
┃ ┣ 📂build
┃ ┃ ┣ 📂KomlalebuFunction
┃ ┃ ┃ ┣ 📜app.py
┃ ┃ ┃ ┗ 📜requirements.txt
┃ ┃ ┗ 📜template.yaml
┃ ┗ 📜build.toml
┣ 📂events
┃ ┗ 📜event.json
┣ 📂komla_function
┃ ┣ 📜app.py
┃ ┗ 📜requirements.txt
┣ 📂tests
┃ ┗ 📂unit
┃ ┃ ┣ 📜test_handler.py
┃ ┃ ┗ 📜init.py
┣ 📜.gitignore
┣ 📜packaged.yaml
┣ 📜README.md
┣ 📜SAM.md
┗ 📜template.yaml

template.yaml

Alt Text

We can see the template.yaml code below.

Alt Text

  • Step 3 - Python code for lambda handler app.py. Runtime - Python 3.8. I created a separate folder komla_function which contains the app.py file. The python script for the lambda function is defined in this file.

Alt Text

  • Step 4 - Modifying the template file. I defined the below Globals, one for extented timeout of the API calls and the second one for CORS, because my browser was misbehaving.😀

Alt Text

The second change was defining the resources properly for my project requirements. AWS::Serverless::Function - Defines the lambda function and its runtime information.

Alt Text

  • Changed

    CodeUri: komla_function/
    
  • Added

    Policies:
    # Give DynamoDB Full Access to your Lambda Function
    - AmazonDynamoDBFullAccess
    

    To give the lambda function full access to the dynamoDB.

  • Modified the API method to do a post.

    KomlalebuAPI:
      Type: Api 
      Properties:
        Path: /
        Method: post
    
  • Finally added template for DynamoDB table creation. The name of my table is komlalebuTable. Refer AWS::Serverless::SimpleTable

     komlalebuTable:
        Type: AWS::Serverless::SimpleTable
        Properties:
          PrimaryKey:
             Name: id
             Type: String
         TableName: komlalebuTable
    
  • Step 5 - Build, package and deploy.
    From the /sam-app directory in CMD running the below command compiles the source code along with all the dependencies into /sam-app/.aws-sam/build directory. It also updates template.yml.

sam build
Alt Text

Once the package is built the below command uploads the output-template and build artifacts as a .zip to my S3 bucket ci******evops.

sam package
Alt Text

The package is deployed from SAM CLI, where SAM packages the output-template as package.yaml and uploads to S3 bucket. The name of my stack is aws-sam-komlalebu.

sam deploy
Alt Text

We can see below the stack created in cloudformation with the output-template file fetched from S3 bucket.

Alt Text

With the events and resources created (API, Lambda function & DynamoDB table.

Alt Text

Simultaneously

We can verify in the respective AWS services for those resource creation status.

DynamoDB
Alt Text

APIGateway
Alt Text

Lambda
Alt Text

  • Step 6 - Testing. I went ahead and started testing the API from API gateway console (I am still struggling with Docker setup due to low C: Drive space for local testing). I was also consistently getting "message": "Internal server error" (502 Bad Gateway) due to json body to string conversion issue. Finally this Article from stackoverflow saved me. 😀 . The API was working fine.

API call
Alt Text

The values passed to the lambda function by the API are also stored in the DynamoDB table created by SAM. It all came together.

DynamoDB
Alt Text

I went ahead and updated my website code in 'index.html' to hit the API url and it is working as expected i.e storing the visitor count in DynamoDB.

Alt Text

Alt Text

Top comments (0)