Skip to content

Latest commit

 

History

History
 
 

1_ServerlessApplicationModel

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

Module 1: Serverless Application Model

In this module you'll use the Serverless Application Model (SAM) to define a serverless RESTful API that has functionality to list, create, view, update, and delete the unicorns in the Wild Rydes stable.

Architecture Overview

The architecture for the Unicorn API uses API Gateway to define an HTTP interface that trigger Lambda functions to read and write data to the DynamoDB database.

Wild Rydes DevOps RESTful API Application Architecture

Serverless Application Model (SAM) Overview

AWS SAM is a model used to define serverless applications on AWS.

AWS SAM is based on AWS CloudFormation. A serverless application is defined in a CloudFormation template and deployed as a CloudFormation stack. An AWS SAM template is a CloudFormation template.

AWS SAM defines a set of objects which can be included in a CloudFormation template to describe common components of serverless applications easily. In order to include objects defined by AWS SAM within a CloudFormation template, the template must include a Transform section in the document root with a value of AWS::Serverless-2016-10-31.

The Unicorn API includes Amazon API Gateway HTTP endpoints that trigger AWS Lambda functions that read and write data to a Amazon DynamoDB database. The SAM template for the Unicorn API describes a DynamoDB table with a hash key and Lambda functions to list, view and update Unicorns in the Wild Rydes stable.

The Unicorn API components are defined in the app-sam.yaml CloudFormation template. Next we'll review the Unicorn API components in more detail.

AWS::Serverless::SimpleTable

Below is the code snippet from the SAM template that describes the DynamoDB table resource.

  Table:
    Type: 'AWS::Serverless::SimpleTable'
      Properties:
        PrimaryKey:
          Name: name
          Type: String

Unicorns are uniquely identified in the Wild Rydes stable by name, a single String attribute that is used as the primary key in the DynamoDB table. The AWS::Serverless::SimpleTable resource meets this requirement and is used to define the DynamoDB table used by the API. If a more complex configuration is required, you can substitute the SimpleTable with a AWS::DynamoDB::Table resource definition.

AWS::Serverless::Function

Below is the code snippet from the SAM template that describes the Lambda function that handles requests to view Unicorn data by Unicorn name.

  ReadFunction:
    Type: 'AWS::Serverless::Function'
    Properties:
      FunctionName: 'uni-api-read'
      Runtime: nodejs6.10
      CodeUri: app
      Handler: read.lambda_handler
      Description: View Unicorn by name
      Timeout: 10
      Events:
        GET:
          Type: Api
          Properties:
            Path: /unicorns/{name}
            Method: get
      Environment:
        Variables:
          TABLE_NAME: !Ref Table
      Role:
        Fn::ImportValue:
          !Join ['-', [!Ref 'ProjectId', !Ref 'AWS::Region', 'LambdaTrustRole']]

There are several properties defined for the AWS::Serverless::Function resource, which we'll review in turn.

FunctionName

The FunctionName property defines a custom name for the Lambda function. If not specified, CloudFormation will generate a name using the CloudFormation Stack name, CloudFormation Resource name, and random ID.

Runtime

The Unicorn API is implemented in Node.js 6.10. Additional runtimes are available for AWS Lambda. Please refer to the Lambda Execution Environment and Available Libraries for the complete list.

CodeUri

The CodeUri property defines the location to the function code on your workstation relative to the SAM template. In this example, "app" is used for the property value because the function code is in the app directory relative to the SAM template.

Handler

The Handler property defines the entry point for the Lambda function. For Javascript, This is formatted as "file.function", where file is the Javascript filename without the ".js" extension relative to the CodeUri path defined above and function is the name of the function in the file that will be executed with the Lambda function is invoked.

Events

The Events property defines the sources that trigger the Lambda function invocation. An Api event source is defined to integrate the Lambda function with an API Gateway endpoint, however SAM supports Lamdba function triggers from a variety of sources.

The Api event source to view details of a Unicorn is defined at the RESTful resource /unicorns/{name} accessed using the HTTP GET method. SAM will transform the Api event to an API Gateway resource and map the name value in the URL to a pathParameter in the event used to invoke the Lambda function.

Environment

The Environment property defines a list of variables and values that will be accessible in the Lambda function, according to the access method defined by the Runtime.

The Lambda functions communicate with DynamoDB to read and write data. The DynamoDB table created by the CloudFormation Stack is referenced as the value for the TABLE_NAME environment variable, which can be referenced within the Lambda function.

Role

The Role property defines the IAM Role that specifies the access permissions to AWS resources in the Lambda execution policy. For each project, CodeStar generates a Lambda execution role that has access to a default set of AWS resources. This role can be modified with additional policies, as you will see in a later module.

Next, we'll look at how CloudFormation is used to deploy the SAM Unicorn API.

Implementation Instructions

Each of the following sections provide an implementation overview and detailed, step-by-step instructions. The overview should provide enough context for you to complete the implementation if you're already familiar with the AWS Management Console or you want to explore the services yourself without following a walkthrough.

If you're using the latest version of the Chrome, Firefox, or Safari web browsers the step-by-step instructions won't be visible until you expand the section.

Region Selection

This workshop can be deployed in any AWS region that supports the following services:

  • Amazon API Gateway
  • Amazon S3
  • Amazon DynamoDB
  • AWS CodeBuild
  • AWS CodePipeline
  • AWS Lambda
  • AWS X-Ray

You can refer to the region table in the AWS documentation to see which regions have the supported services. Among the supported regions you can choose are N. Virginia, Ohio, N. California, Oregon, Ireland, Frankfurt, and Sydney.

Once you've chosen a region, you should deploy all of the resources for this workshop there. Make sure you select your region from the dropdown in the upper right corner of the AWS Console before getting started.

Region selection screenshot

1. Update CodeStar IAM Role

CodeStar generates IAM Roles and Policies that control access to AWS resources. In this module, we will add permissions to Roles using IAM Managed Policies to support the customizations we will make to the Lambda function names.

1a. Add IAM Policies to the CodeStarWorker-uni-api-CloudFormation Role

  1. In the AWS Management Console choose Services then select IAM under Security, Identity & Compliance.

  2. Select Role in the left navigation, type CodeStarWorker-uni-api-CloudFormation in the filter text box, and click the Role name link in the Role table.

    Select Role

  3. On the Role Summary page, click the Attach Policy button in the Managed Policies section of the Permissions tab.

    Role Details

  4. Type AWSLambdaReadOnlyAccess in the filter text box, select the checkbox next to the AWSLambdaReadOnlyAccess Managed Policy, and click the Attach Policy button.

    Attach Policy

  5. The Role Summary will now include the AWSLambdaReadOnlyAccess policy in the list of Managed Policies.

    Policy Attached

2. Seed the uni-api CodeCommit Git repository

  1. Each module has corresponding source code used to seed the CodeCommit Git repository for the CodeStart project. To seed the CodeCommit Git repository, click on the Launch Stack button for your region below:

    Region Launch
    US East (N. Virginia) Launch Module 1 in us-east-1
    US West (N. California) Launch Module 1 in us-west-1
    US West (Oregon) Launch Module 1 in us-west-2
    EU (Ireland) Launch Module 1 in eu-west-1
    EU (Frankfurt) Launch Module 1 in eu-central-1
    Asia Pacific (Sydney) Launch Module 1 in ap-southeast-2
  2. The CloudFormation template has been prepopulated with the necessary fields for this module. No changes are necessary

  3. Select the I acknowledge that AWS CloudFormation might create IAM resources. checkbox to grant CloudFormation permission to create IAM resources on your behalf

  4. Click the Create button in the lower right corner of the browser window to create the CloudFormation stack and seed the CodeCommit repository.

    Seed Repository CloudFormation Stack Review

  5. There will be a short delay as the Git repository seeded with the new source code. Upon successful completion, the CloudFormation will show Status CREATE_COMPLETE.

    CloudFormation Stack Creation Complete

3. Fetch CodeCommit Git Repository

Now that the CodeCommit Git repository has been seeded with new source code, you will need to fetch the changes locally so that you may modify the code. Typically, this is accomplished using the git pull command, however for the workshop we have replaced the repository with a new history and different Git commands will be used.

Using your preferred Git client, run the commands on your local uni-api Git repository:

  • git fetch --all
  • git reset --hard origin/master

4. Identify CodeStar uni-api S3 Bucket

CodeStar creates an S3 bucket to store the artifacts created by packaging SAM-based projects. The S3 bucket has the format, where {AWS::Region} and {AWS::AccountId} are populated with your details.

aws-codestar-{AWS::Region}-{AWS::AccountId}-uni-api-pipe

5. Package the Unicorn API for Deployment

On your workstation:

  1. Change directory to your local uni-api Git repository directory.

  2. Use the AWS CLI to execute the CloudFormation package command to upload the local code from the uni-api directory to S3. Use the following command to do so. Make sure you replace YOUR_BUCKET_NAME with the name you identified in the previous step (i.e. aws-codestar-{AWS::Region}-{AWS::AccountId}-uni-api-pipe)

aws cloudformation package --template-file app-sam.yaml --s3-bucket YOUR_BUCKET_NAME --output-template-file app-sam-output.yaml

The CloudFormation package command archives the local source code, uploads it to the S3 location specified, and returns an new CloudFormation template to the app-sam-output.yaml file with the local CodeUri reference substituted with the location to the S3 object. For example:

Before:

  ReadFunction:
    Type: 'AWS::Serverless::Function'
    Properties:
      FunctionName: 'uni-api-read'
      Handler: read.lambda_handler
      Runtime: nodejs6.10
      CodeUri: app

After:

  ReadFunction:
    Type: 'AWS::Serverless::Function'
    Properties:
      FunctionName: 'uni-api-read'
      Handler: read.lambda_handler
      Runtime: nodejs6.10
      CodeUri: s3://YOUR_BUCKET_NAME/540839c2fc11f0214f88f6c5dfacd389

6. Deploy the Unicorn API

  1. Change directory to your local uni-api Git repository, if necessary.

  2. Use the AWS CLI to execute the CloudFormation deploy command to deploy the app-sam-output.yaml CloudFormation template returned by the package command, specifying the CloudFormation stack name awscodestar-uni-api-lambda and the CAPABILITY_IAM CloudFormation capability as the stack will be creating IAM trust and execution policies for the Lambda functions. You can use the following command to do so.

aws cloudformation deploy --stack-name awscodestar-uni-api-lambda --template-file app-sam-output.yaml --capabilities CAPABILITY_IAM --parameter-overrides ProjectId=uni-api

Implementation Validation

After the CloudFormation deploy command completes, you will use the browser to test your API.

  1. In the AWS Management Console choose Services then select CodeStar under Developer Tools.

  2. Select the uni-api project

  3. Copy the URL from the Application endpoints tile on the right side of the dashboard.

  4. Paste the URL in a browser window and append /unicorns to the path and hit enter. For example: https://xxxxxxxxxx.execute-api.us-west-1.amazonaws.com/Prod/unicorns/

  5. Confirm that the browser shows a JSON result with an empty list: []

API Enhancement

Now that you've reviewed and deployed the Unicorn API, let's enhance the API with the ability to create or update a Unicorn in the Wild Rydes stables. The code to do so is already present in the project, so you need to add an AWS::Serverless::Function resource in the SAM app-sam.yaml template.

1. Add Update Function to app-sam.yaml

Using a text editor, open the app-sam.yaml file and append a new AWS::Serverless::Function Resource labeled UpdateFunction that has the following definition.

Note: whitespace is important in YAML files. Please verify that the configuration below is added with the same space indentation as the CloudFormation Resources in the app-sam.yaml file.

  1. FunctionName is uni-api-update

  2. Runtime is nodejs6.10

  3. CodeUri is app

  4. Handler is update.lambda_handler

  5. Description is Create or Update Unicorn

  6. Timeout is 10

  7. Event type is Api associated to the /unicorns/{name} Path and put Method

  8. Environment variable named TABLE_NAME that references the Table Resource for its value.

  9. Role is duplicated from another function.

If you are unsure of the syntax to add to app-sam.yaml please refer to the code snippet below.

app-sam.yaml additions to support Update function (expand for details)

  UpdateFunction:
    Type: 'AWS::Serverless::Function'
    Properties:
      FunctionName: 'uni-api-update'
      Runtime: nodejs6.10
      CodeUri: app
      Handler: update.lambda_handler
      Description: Create or Update Unicorn
      Timeout: 10
      Events:
        PUT:
          Type: Api
          Properties:
            Path: /unicorns/{name}
            Method: put
      Environment:
        Variables:
          TABLE_NAME: !Ref Table
      Role:
        Fn::ImportValue:
          !Join ['-', [!Ref 'ProjectId', !Ref 'AWS::Region', 'LambdaTrustRole']]

2. Package the Unicorn API for Deployment

Use the AWS CLI to execute the CloudFormation package command to upload the local code from the uni-api directory to S3. You can use the following command to do so. Make sure you replace YOUR_BUCKET_NAME with the name you used for the previous package command.

aws cloudformation package --template-file app-sam.yaml --s3-bucket YOUR_BUCKET_NAME --output-template-file app-sam-output.yaml

3. Deploy the Unicorn API

Use the AWS CLI to execute the CloudFormation deploy command to deploy the app-sam-output.yaml CloudFormation template returned by the package command, specifying the CloudFormation stack name awscodestar-uni-api-lambda and the CAPABILITY_IAM CloudFormation capability as the stack will be creating IAM trust and execution policies for the Lambda functions. You can use the following command to do so.

aws cloudformation deploy --stack-name awscodestar-uni-api-lambda --template-file app-sam-output.yaml --capabilities CAPABILITY_IAM

CloudFormation will generate a ChangeSet for the awscodestar-uni-api-lambda CloudFormation Stack and only update the resources that have changed since the previous deployment. In this case, awscodestar-uni-api-lambda was the CloudFormation stack created by CodeStar for the Lambda functions and API Gateway specification, which you will be updating.

Enhancement Validation

After the CloudFormation deploy command completes, you will use the AWS API Gateway to test your API.

1. Add a Unicorn

  1. In the AWS Management Console, click Services then select API Gateway under Application Services.

  2. In the left nav, click on awscodestar-uni-api-lambda.

  3. From the list of API resources, click on the PUT link under the /{name} resource.

  4. On the resource details panel, click the TEST link in the client box on the left side of the panel.

    Validate 1

  5. On the test page, enter Shadowfox in the Path field.

  6. Scroll down the test page and enter the following as the Request Body:

    {
      "breed": "Brown Jersey",
      "description": "Shadowfox joined Wild Rydes after completing a distinguished career in the military, where he toured the world in many critical missions. Shadowfox enjoys impressing his ryders with magic tricks that he learned from his previous owner."
    }

    Validate 2

  7. Scroll down and click the Test button.

  8. Scroll to the top of the test page, and verify that on the right side of the panel that the Status code of the HTTP response is 200.

    Validate 3

2. List Unicorns

  1. In the AWS Management Console choose Services then select CodeStar under Developer Tools.

  2. Select the uni-api project

    CodeStar Project List

  3. Copy the URL from the Application endpoints tile on the right side of the dashboard.

    CodeStar App Endpoint

  4. Paste the URL in a browser window and append /unicorns to the path and hit enter. For example: https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/Prod/unicorns/

  5. Confirm that the browser shows a JSON result that includes Shadowfox, with the breed and description entered above.

Note: You may notice that your CodeStar project shows the Build stage has failed in the project pipeline. That's to be expected, and will be corrected in the next module.

Completion

Congratulations! You have successfully deployed a RESTful serverless API using the Serverless Application Model, and demonstrated that the same tools can be used to make modifications to the API. In the next Continuous Delivery Pipeline Module, you will learn how to automate this deployment process using AWS CodePipeline and AWS CodeBuild.