We use cookies on this site to enhance your user experience. You accept to our cookies if you continue to use this website.

Drift detection now available in AWS CloudFormation

CloudFormation drift detection Announced at reinvent 2017 in a CloudFormation Deep Dive session for “early 2018” - now (almost at the end of 2018) the time has come. AWS has added a new and long awaited feature to CloudFormation that will help in many cases: “Drift detection”.

With this feature you can see in the CloudFormation console which stacks have been changed manually. Simply select the desired stack, select “Detect drift” under actions and confirm.

In AWS words: Drift detection lets you detect whether a stack’s actual configuration has been changed outside of CloudFormation. To detect drift on a stack, select the stack, and then select Detect drift for current stack from the Actions menu.
Read more in the official documentation.
Read more in the official blog.

Implement S3 Bucket Lambda triggers in AWS CloudFormation

Lambda Console with S3 trigger

Implement S3 Bucket Lambda triggers in AWS CloudFormation can be quite tricky because of very often circular dependencies or errors like “Unable to validate the following destination configurations” occur. But if you take notice of the following, working with S3 Lambda triggers in CloudFormation will be easier.

  • First, you have to specify a name for the Bucket in the CloudFormation template, this allows you to create policies and permission without worrying about circular dependencies.
  • Secondly, you have to add a DependsOn statement to the Bucket referencing the Lambda Permission, this helps you to fix “Unable to validate the following destination configurations” errors since the bucket will only get created if the Lambda Function and all necessary policies, roles and permissions are in place.

Below you will find a GitHub Gist with a working example which takes care of all tips mentioned above. In this example, created *.txt files are read from a bucket and then deleted.

Read more: https://aws.amazon.com/premiumsupport/knowledge-center/unable-validate-destination-s3/

Use or output Amazon MQ Endpoints in AWS CloudFormation

Amazon MQ with ActiveMQ under the hood offers several different protocols, each with its own endpoint. Unfortunately, you can’t reference or output them directly in AWS CloudFormation. To make this possible I use the following variants in a Single Broker setup, where AMQBroker is a CloudFormation resource of type AWS::AmazonMQ::Broker:

and these in an active/standby setup for high availability:

Output Amazon API Gateway Domain Name URL in AWS CloudFormation

Unfortunately, it is currently not possible to output or use the domain name / URL of an Amazon API gateway via Fn::GetAtt in AWS CloudFormation. Therefore I provide the following CloudFormation snippets that enables you to do exaclty this. The snippets use a resource called RestApi of type AWS::ApiGateway::RestApi and a resource Stage of type AWS::ApiGateway::Stage.

SQS Queue as Lambda Trigger in AWS CloudFormation

Lambda Console with SQS trigger

Recently AWS released that the Amazon Simple Queue Service (SQS) is now available as a supported event source for AWS Lambda Functions. You can read the related blog post here:  https://aws.amazon.com/blogs/aws/aws-lambda-adds-amazon-simple-queue-service-to-supported-event-sources/

Since then I have seen many instructions explaining how to integrate this trigger via AWS Serverless Application Model (AWS SAM). Using this approach I noticed that when rolling out the SAM template via AWS CloudFormation a resource of type AWS::Lambda::EventSourceMapping is created. Since this resource is supported by AWS CloudFormation it should be possible to create the SQS Lambda trigger without SAM.

So I tried it successfully and got the following CloudFormation example template:

One thing to watch out for is that the lambda function timeout is not greater than the visible timeout on the queue. The solution can be tested by sending a test message via the SQS Queue using the SQS Console.

Sending a test message via the SQS Console Sending a test message via the SQS Console

Check if the Lambda Function has been invoked Check if the Lambda Function has been invoked

AWS CloudFormation conditional arrays

Sometimes in CloudFormation a Parameter requires an array, and often an array of variable size is required, determined for example by input parameters. For instance AWS::AmazonMQ::Broker were you need to define an array of SubnetIds. In which either if SINGLE_INSTANCE is selected or if ACTIVE_STANDBY_MULTI_AZ is selected, several ids must be specified.

Using the notation proposed in the documentation this cannot be achieved:

SubnetIds:
        -  !Ref PrivSubnetA
        -  !If [ DeployAmqMultiAzCondition, !Ref PrivSubnetB, ]

But the problem can be solved as follows:

SubnetIds: !If [ DeployAmqMultiAzCondition, [ !Ref PrivSubnetA, !Ref PrivSubnetB ],  [ !Ref PrivSubnetA ]]

Use GitHub source in AWS CodeBuild Project using AWS CloudFormation

AWS CodeBuild with GitHub in North Virigina

I wanted to create an AWS CodeBuild project using AWS CloudFormation, which checks out its sources from GitHub and is triggered via GitHub Webhooks. From these sources, a Node.js application should be built using a self-created docker image stored in ECR (Elastic Container Registry).

Therefore I defined the following template:

At the first try the stack creation failed with the following error message:

No Access token found, please visit AWS CodeBuild console to connect to GitHub (Service: AWSCodeBuild; Status Code: 400; Error Code: InvalidInputException; Request ID: ab458603-6fd4-11e8-9310-ff116e0423f9)

To get rid of this error message it’s necessary to set up the AWS OAuth application to have access to your repositories.

Therefore you have to navigate to the AWS CodeBuild console, create a project and select GitHub as source provider. The project does not need to be saved, it is only important to connect to GitHub.

AWS CodeBuild GitHub AWS CodeBuild GitHub

The next time I tried to deploy the CloudFormation stack, the error message did not appear and the CodeBuild project was created successfully.

CloudFormation CodeBuild CloudFormation CodeBuild

Generate Passwords in AWS CloudFormation Template

Sometimes its necessary to generate random passwords inside a CloudFormation template for instance to secure internet facing applications running on an EC2 or ECS instance. To achieve this you have the possibility to let the user of your Cloud Formation template insert passwords as parameters during the stack creation.

In the following, I will give an example of how to generate passwords in an AWS CloudFormation Template using a Node.js Lambda Function and Custom Resources.

Example Code

Description

We create a Custom CloudFormation Resource and pass a previously created Lambda function as the ServiceToken property. Now on every CloudFormation event (e.g. Create / Update / Delete) on the SampleString resource, the Lambda function will be called. The call contains a so-called ResponseUrl where the Lambda function shall response to. If you understood this procedure the template is really easy to understand. After the creation of the Custom Resource is complete you can use the data stored inside using Fn:GetAtt.

Using the Length property in the Custom Resource you can adjust the password length.

Note: The current version of the script generates a new random password if you performing a stack update which directly involves the Custom Resource (means if you change any parameter or property attached to the Custom Resource). To avoid this you could do a workaround like storing the password in an environment variable of the lambda function and resend it on an update. But normally updates on a custom resource this simple should not happen.

Usage

Inside the AWS Console go to CloudFormation and deploy the example-template.yml. After the stack creation is complete navigate to the Outputs tab and look for the generated password.

AWS Console CloudFormation AWS Console CloudFormation

Rudimentary based on https://github.com/sophos/cloudformation-random-string example implemented in python.