Serverless computing allows you to build and run applications without thinking about servers. Building serverless applications means that your developers can focus on their core product instead of worrying about managing and operating servers. This reduced overhead lets developers reclaim time and energy that can be spent on developing great products that scale and are reliable.

Infrastructure as Code (IaC) services like AWS CloudFormation enable you to easily provision resources. However, if newly created resources are not organized properly, it quickly becomes difficult to manage and operate those resources as a single unit. Previously, to perform bulk actions and gather group insights, customers had to manually select CloudFormation stacks and organize those resources into groups. Now, with AWS Resource Groups support for AWS CloudFormation, you can organize resources into groups instantly while deploying your CloudFormation stack templates.

In this post, you will learn how to: a) provision serverless application resources using CloudFormation and organize those resources using AWS Resource Groups and b) gather performance insights using Amazon CloudWatch with auto-generated created dashboards. The example in this blog post uses the following AWS services:


Creating a resource group BeerService that contains all of the stack’s resources takes only four lines of CloudFormation template. The source code is available on GitHub.

    Type: "AWS::ResourceGroups::Group"
      Name: BeerService

If you want to create a new resource group which contains all the resources from an existing CloudFormation Stack, you can do so by including the ResourceQuery object as a property. The StackIdentifier field contains the Amazon Resource Name (ARN) of a CloudFormation Stack:

ResourceGroup: Type: "AWS::ResourceGroups::Group" Properties: Name: BeerService ResourceQuery: StackIdentifier: "arn:aws:cloudformation:us-east-1:0123456789:stack/stack-name/9b6f8604-4a39-490c-870b-44b0ebdd38b9"

Additionally, you can use the ResourceQuery object to create a tag-based resource group containing resources that share one or more common tags. With the following example, you can create a group of all resources with a tag key “Environment” and a tag value “Production”:

ResourceGroup: Type: "AWS::ResourceGroups::Group" Properties: Name: BeerService ResourceQuery: Type: "TAG_FILTERS_1_0" Query: TagFilters: - Key: "Environment" Values: - "Production"

Provisioning and organizing

Getting started (provisioning)

The demo uses the Serverless Application Model (SAM) to simplify the creation of resources. The template specification provides a clean syntax to describe functions, APIs, permissions, configurations, and events. Clone the repository from the AWS Resource Groups Samples GitHub repository and install the SAM command line interface (CLI). The SAM CLI will guide you step-by-step through the creation of the serverless application.

Ensure that the AWS CLI is configured for your account and that you have permissions to create a CloudFormation stack. You need the capability CAPABILITY_IAM to create a new IAM role for our Lambda function. Go to the subfolder samples/instantly-monitor-serverless-applications. Run the following two commands in the subfolder to deploy the application to your AWS account. When asked Allow SAM CLI IAM role creation [Y/n] reply with Y:

$ sam build
$ sam deploy \ --guided \ --stack-name BeerService \ --region us-east-1 \ --no-confirm-changeset


As mentioned above, a resource group BeerService is created which contains all resources within the serverless application that you defined. All resources that you add to the CloudFormation stack in the future will be included in this resource group without any additional effort, so you never lose track of resources. You can list the resources that were created with the deployment by using the AWS CLI:

$ aws resource-groups list-group-resources --group BeerService
{ "ResourceIdentifiers": [ { "ResourceArn": "arn:aws:dynamodb:us-east-1:123456789012:table/Beers", "ResourceType": "AWS::DynamoDB::Table" }, { "ResourceArn": "arn:aws:lambda:us-east-1:123456789012:function:BeerService-LambdaFunction-QCPYQGMU8X9O", "ResourceType": "AWS::Lambda::Function" }, { "ResourceArn": "arn:aws:iam::123456789012:role/BeerService-LambdaFunctionRole-1ORIMKXTOBXYE", "ResourceType": "AWS::IAM::Role" }, { "ResourceArn": "arn:aws:apigateway:us-east-1::/restapis/d04fsct329", "ResourceType": "AWS::ApiGateway::RestApi" } ]

You can achieve the same by navigating to the Resource Groups console. Anywhere in the AWS console, choose Resource Groups, Saved Groups from the top menu bar and choose the group BeerService.

Figure 1: Navigating to Resource Groups in the AWS Console

Figure 1: Navigating to Resource Groups in the AWS Console

Testing the application

There are multiple ways to test our application. This blog post shows how to use the API Gateway console to test the two endpoints:

  • PUT /beer
  • GET /beer/{name}

Navigate to the API Gateway console and select the BeerService API.

Figure 2: Selecting the BeerService API in the AWS Console

Figure 2: Selecting the BeerService API in the AWS Console

PUTting a beer

Under Resources on the left side of the console, select the PUT /beer operation and press the button Test (see the small lightning icon). The Method Test for the operation opens. Paste the following payload into the Request Body text field and replace {name} with your favorite brand:

{ "name": "{name}" }

Press the button Test and you should see the following response on the right side with status code 200:

"message": "Added favorite beer: {name}"

Our service now stored an entry with your favorite beer brand in the Beers DynamoDB table. You can optionally verify that by navigating to the DynamoDB console and checking the items in the table.

GETting a beer

In the API Gateway console, select Resources again on the left side of the console. This time, select the GET /beer/{name} operation and press the button Test again. Enter the same {name} in the Path section that you chose earlier for the PUT /beer operation and press the button Test again. You should see the following response on the right side with status code 200:

"message": "My favorite beer is: {name}"

If you are a bit more curious, use a {name} that you did not previously store using the PUT /beer operation.

Monitoring the application

Another benefit of using Resource Groups is that grouped applications come with monitoring included. CloudWatch can automatically generate dashboards for a resource group. In the CloudWatch console main page, there is a dropdown in the section CloudWatch: Overview, where All resources is currently selected. This dropdown allows you to organize your dashboards by Resource Groups.

Select the group BeerService. The following dashboards have automatically been created on your behalf. Inspect these key metrics for the two (or more) requests that you made earlier using the API Gateway console:

  • DynamoDB: Successful Request Latency Average and Throttled Requests Sum
  • Lambda: Duration Average and Errors Sum

Figure 3: Inspecting auto-generated dashboards in the AWS Console

Figure 3: Inspecting auto-generated dashboards in the AWS Console

Cleaning up

After you are done, you can tear down all of the previously created resources in our AWS account by using the following command with the AWS CLI:

$ aws cloudformation delete-stack --stack-name BeerService


This blog post demonstrated how to use the Serverless Application Model to deploy a serverless application with a CloudFormation template. You learned how to test the application in API Gateway and inspect auto-generated dashboards in CloudWatch. As next steps, we suggest you to check out the source code in the referenced GitHub repository and inspect how the different components of the example interact.



About the Author

The author of the blog post: Florian Katenbrink
Florian Katenbrink is a Software Development Engineer at AWS Resource Groups. He builds innovative solutions with his team to further improve grouping mechanisms for AWS customers. In his spare time, Florian enjoys a fresh cappuccino in the morning, discovering one country every year, and a competitive game of soccer.