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.
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.
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.
Below is the code snippet from the SAM template that describes the DynamoDB table resource.
DynamodbTable:
Type: 'AWS::Serverless::SimpleTable'
Properties:
PrimaryKey:
Name: name
Type: StringUnicorns 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.
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:
Runtime: nodejs6.10
CodeUri: app
Handler: read.lambda_handler
Description: View Unicorn by name
Events:
ReadApi:
Type: Api
Properties:
Path: /unicorns/{name}
Method: get
Environment:
Variables:
TABLE_NAME: !Ref DynamodbTable
Policies:
- Version: '2012-10-17'
Statement:
- Effect: Allow
Resource: !Sub 'arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${DynamodbTable}'
Action:
- 'dynamodb:GetItem'There are several properties defined for the AWS::Serverless::Function resource, which we'll review in turn.
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.
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.
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.
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.
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.
The Policies property defines the access permissions to AWS resources in the Lambda execution policy. For each Unicorn API resource, an IAM policy s defined that describes only the actions required for that Lambda function when communicating with the DynamoDB table. In this way, our application follows the IAM best practice of granting least privilege.
For the Unicorn API that views the details of a Unicorn, the Lambda function need only use the GetItem method to find the Unicorn by its name, the primary key on the table.
Alternatively, the AWS::Serverless::Function Role property can be used to refer to an IAM Role that contains the list of IAM Policies that define the access permissions required by the Lambda execution policy.
Take a minute to review the SAM definitions in the app-sam.yaml file for the other API methods. Note their simularities and differences.
Next, we'll look at how CloudFormation is used to deploy the SAM Unicorn API.
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.
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, 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.
Use the console or AWS CLI to create an Amazon S3 bucket with versioning enabled. Keep in mind that your bucket's name must be globally unique. We recommend using a name like wildrydes-devops-yourname.
Step-by-step instructions (expand for details)
-
In the AWS Management Console choose Services then select S3 under Storage.
-
Choose +Create Bucket
-
Provide a globally unique name for your bucket such as
wildrydes-devops-yourname. -
Select the Region you've chosen to use for this workshop from the dropdown.
-
Choose Next in the lower right of the dialog.
-
Choose the Versioning properties box.
-
Choose Enable versioning and click Save in the dialog box.
-
Choose Next in the lower right of the dialog.
-
Choose Next in the lower right of the dialog.
-
Choose Create Bucket in the lower right of the dialog.
This workshop requires you to modify text files on your workstation and to package the application project for deployment. To obtain a local copy, you will need to clone or download this GitHub Repository.
- In your web browser, open the following link to the Wild Rydes Serverless Workshop.
- If you choose, follow the GitHub instructions to clone the repository to a directory on your workstation: Cloning a Repository
- If you are unfamiliar with git, you can also download the repository as a zip file. The screenshot below illustrates where to click to download the zip file.
- Once downloaded to your workstation, you will need expand the
aws-serverless-workshops-master.zipfile into a directory calledaws-serverless-workshops-masterthat you will use to edit and package the application code.
On your workstation:
-
Change directory to
aws-serverless-workshops-master/DevOps/1_ServerlessApplicationModel/unicorn-api. -
Use the AWS CLI to execute the CloudFormation package command to upload the local code from the
unicorn-apidirectory to S3. Use the following command to do so. Make sure you replaceYOUR_BUCKET_NAMEwith the name you used in the previous section.
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:
Handler: read.lambda_handler
Runtime: nodejs6.10
CodeUri: appAfter:
ReadFunction:
Type: 'AWS::Serverless::Function'
Properties:
Handler: read.lambda_handler
Runtime: nodejs6.10
CodeUri: s3://YOUR_BUCKET_NAME/540839c2fc11f0214f88f6c5dfacd389-
Change directory to
aws-serverless-workshops-master/DevOps/1_ServerlessApplicationModel/unicorn-api, if necessary. -
Use the AWS CLI to execute the CloudFormation deploy command to deploy the
app-sam-output.yamlCloudFormation template returned by the package command, specifying the CloudFormation stack namewildrydes-unicorn-apiand theCAPABILITY_IAMCloudFormation 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 wildrydes-unicorn-api --template-file app-sam-output.yaml --capabilities CAPABILITY_IAM
After the CloudFormation deploy command completes, you will use the browser to test your API.
-
In the AWS Management Console, click Services then select API Gateway under Application Services.
-
In the left nav, click on
wildrydes-unicorn-api. -
In the left nav, under the
wildrydes-unicorn-apiAPI click on Stages -
In the list of Stages, expand the Prod stage section
-
Click on the GET link under the
/unicornsresource -
Open the Invoke URL in another browser window and confirm that the Unicorn API responds successfully with an empty JSON list:
[]
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.
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.
-
Runtime is
nodejs6.10 -
CodeUri is
app -
Handler is
update.lambda_handler -
Event type is
Apiassociated to the/unicorns/{name}Path andputMethod -
Environment variable named
TABLE_NAMEthat references theDynamodbTableResources for its value. -
Policies should mirror other Functions, however the Action to allow is
dynamodb:PutItem
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:
Runtime: nodejs6.10
CodeUri: app
Handler: update.lambda_handler
Description: Create or Update Unicorn
Events:
UpdateApi:
Type: Api
Properties:
Path: /unicorns/{name}
Method: put
Environment:
Variables:
TABLE_NAME: !Ref DynamodbTable
Policies:
- Version: '2012-10-17'
Statement:
- Effect: Allow
Resource: !Sub 'arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${DynamodbTable}'
Action:
- 'dynamodb:PutItem'Use the AWS CLI to execute the CloudFormation package command to upload the local code from the unicorn-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
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 wildrydes-unicorn-api 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 wildrydes-unicorn-api --template-file app-sam-output.yaml --capabilities CAPABILITY_IAM
CloudFormation will generate a ChangeSet for the wildrydes-unicorn-api CloudFormation Stack and only update the resources that have changed since the previous deployment. In this case, a new Lambda Function and API Gateway resource will be created for the UpdateFunction resource that you added to the SAM template.
After the CloudFormation deploy command completes, you will use the AWS API Gateway to test your API.
-
In the AWS Management Console, click Services then select API Gateway under Application Services.
-
In the left nav, click on
wildrydes-unicorn-api. -
From the list of API resources, click on the
PUTlink under the/{name}resource. -
On the resource details panel, click the
TESTlink in the client box on the left side of the panel. -
On the test page, enter
Shadowfoxin the Path field. -
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." } -
Click on the Test button.
-
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.
-
In the left nav, under the
wildrydes-unicorn-apiAPI click on Stages, expand the Prod stage, and choose theGETmethod below the/unicornsresource. -
At the top of the Prod Stage Editor panel, choose the Invoke URL to display a list of Unicorns in the browser.
Shadowfoxshould be listed with the breed and description entered above.
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.






