By default, an Amazon SNS topic that subscribes to AWS CloudFormation stack notifications receives notifications for all events. This article describes how to use an AWS Lambda function to filter stack notifications and send email alerts when CloudFormation generates a ROLLBACK_IN_PROGRESS notification.

This article describes how to send email alerts to designated recipients if unexpected notifications such as ROLLBACK_IN_PROGRESS are generated by AWS CloudFormation during the stack creation process. The following summary requirements for this scenario are described in greater detail in the Resolution section:

  1. An Amazon Simple Notification Service (Amazon SNS) topic that subscribes to CloudFormation notifications and publishes the notifications to an AWS Lambda function for filtering.
  2. An AWS Identity and Access Management (IAM) policy that allows Lambda to publish filtered notifications to an SNS topic and also write to Amazon CloudWatch Logs.
  3. An IAM role for Lambda to run as an AWS service. You will attach the IAM policy that you just created to this role.
  4. A Lambda function to filter CloudFormation notifications.
  5. An SNS topic that subscribes to the output of the Lambda function and publishes email alerts to designated recipients.

Follow these steps to configure CloudFormation to send email alerts when a ROLLBACK_IN_PROGRESS notification is generated while creating a stack with the appropriate triggers enabled.

Create an SNS topic for email notification

1.    Open the Amazon SNS console and create a new SNS topic; make a note of the topic name you enter (for example LambdaEmailAlert). Optionally specify a value for Display name, and then choose Create topic.

2.    Open the topic details page and choose Create subscription.

3.    Specify the following values for the topic subscription:
            Protocol: Email
            Endpoint: [enter your e-mail address here]

4.    Choose Create subscription. You will receive email to confirm the subscription.

5.    Confirm the subscription by clicking on the link in the email. Make note of the Topic ARN you see in the dashboard; for example: arn:aws:sns:us-west-2:0123456789012:LambdaEmailAlert.

Create an IAM policy

1.    Open the AWS IAM console, choose Policies, and then choose Create policy.

2.    Choose Create Your Own Policy, specify a Policy Name (make a note of the Policy name because you will need it later), and enter the following Policy Document text.

{   "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sns:Publish"
            ],
            "Resource": [
                "arn:aws:sns:us-west-2:0123456789012:LambdaEmailAlert"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:*:*"
        }
    ]
}

Note: Substitute your topic ARN for the Resource value.

3.    Choose Create Policy.

This policy allows Lambda to publish to the email notification SNS topic and to write to CloudWatch logs.

Create an IAM role

1.    Open the AWS IAM console, choose Roles, and then choose Create new role.

2.    On the Select Role Type page, under AWS Service Roles, choose AWS Lambda. The Attach Policy page will be displayed.

3.    On the Attach Policy page, locate your new IAM policy, select the check box next to the policy name, and choose Next Step.

4.    On the Set role name and review page, enter a name for the role. Note: Make a note of the role name; you will need it when you create your Lambda function.

5.    Verify that the role information is correct, and then choose Create role.

Create a Lambda function

1.    Open the AWS Lambda console and choose Create a Lambda function to start the new Lambda function wizard.

2.    Choose the Blank Function blueprint to open the Configure triggers page.

3.    Choose Next to open the Configure function page.

4.    Specify the following values:
            Name: LambdaSNSNo
            Description: LambdaSNSNo
            Runtime: Node.js 4.3

5.    Under Lambda function handler and role, specify the name of the IAM role that you created earlier.

6.    Leave the remaining options unchanged and choose Next to display the Review page.

7.    Choose Create Function.

Create an SNS topic for CloudFormation to notify Lambda

1.    Open the AWS SNS console and create a new SNS topic. Make a note of the topic name (for example, CF-Notifications).

2.    Open the topic details page and choose Create subscription.

3.    Specify the following values for the topic subscription:
            Protocol: AWS Lambda
            Endpoint: [select full ARN to LambdaSNSNo function]
            Version or alias: default

4. Choose Create subscription.

Update the Lambda function

1.    Open the AWS Lambda console.

2.    Replace the Code section of the LambdaSNSNo function with the following example script. Substitute the appropriate values for AWS.config.region and topic_arn (topic_arn is the ARN of the SNS topic you originally created for email notifications):

topic_arn = "arn:aws:sns:us-west-2:123456789012:LambdaEmailAlert";
var AWS = require('aws-sdk'); 
AWS.config.region_array = topic_arn.split(':'); // splits the ARN in to and array 
AWS.config.region = AWS.config.region_array[3];  // makes the 4th variable in the array (will always be the region)


// ####################   BEGIN LOGGING   ########################

console.log(topic_arn);   // just for logging to the that the var was parsed correctly
console.log(AWS.config.region_array); // to see if the SPLIT command worked
console.log(AWS.config.region_array[3]); // to see if it got the region correctly
console.log(AWS.config.region); // to confirm that it set the AWS.config.region to the correct region from the ARN

// ####################  END LOGGING (you can remove this logging section)  ########################


exports.handler = function(event, context) {
    const message = event.Records[0].Sns.Message;
    if (message.indexOf("ROLLBACK_IN_PROGRESS") > -1) {
        var fields = message.split("\n");
        subject = fields[11].replace(/['']+/g, '');
        send_SNS_notification(subject, message);   
    }
};

function send_SNS_notification(subject, message) {
    var sns = new AWS.SNS();
    subject = subject + " is in ROLLBACK_IN_PROGRESS";
    sns.publish({ 
        Subject: subject,
        Message: message,
        TopicArn: topic_arn
    }, function(err, data) {
        if (err) {
            console.log(err.stack);
            return;
        } 
        console.log('push sent');
        console.log(data);
    });
}

Note: You can use environment variables to set the value for topic_arn. Instead of setting topic_arn to a hard-coded value, you can set it as follows:  

topic_arn = process.env.NotificationARN;

3.    Select the Triggers tab of your Lambda function and choose Add Trigger.

4.    Select the empty box to the left of the Lambda icon to choose the trigger type.

5.    Choose SNS from the drop-down menu.

6.    From the SNS topic drop-down menu, choose the first SNS topic (for example, LambdaEmailAlert) that you created.

7.    Verify that the option to Enable trigger is selected, and then choose Submit.

To monitor your CloudFormation stack for rollback events when you create a stack, select the existing Amazon SNS topic CF-Notifications from the Advanced section. You can also run the following AWS CLI command to create a stack (note that you will need to provide a location for the --template-url parameter)

aws cloudformation create-stack --stack-name testlambda7771234 --notification-arns arn:aws:sns:us-west-2:123456789012:CF-notifications --template-url https://s3-eu-west-1.amazonaws.com/stackrollback/eb.template

Now when a stack generates a ROLLBACK_IN_PROGRESS notification, you should receive email similar to the following:

Subject:  StackName=testlambda123777 is in ROLLBACK_IN_PROGRESS
StackId='arn:aws:cloudformation:us-west-2:282684616245:stack/testlambda7771234/5799b7c0-9546-11e6-a2f7-500c4227269a'
Timestamp='2016-10-18T15:20:10.528Z'
EventId='5c0ec520-9546-11e6-aad3-500c3cd570d2'
LogicalResourceId='testlambda7771234'
Namespace='282684616245'
PhysicalResourceId='arn:aws:cloudformation:us-west-2:123456789012:stack/testlambda7771234/5799b7c0-9546-11e6-a2f7-500c4227269a'
PrincipalId='AIDAJBXSERGUK7FXYRBHI'
ResourceProperties='null'
ResourceStatus='ROLLBACK_IN_PROGRESS'
ResourceStatusReason='The following resource(s) failed to create: [CommunityAppEB]. Rollback requested by user.'
ResourceType='AWS::CloudFormation::Stack'
StackName='testlambda7771234'


Did this page help you? Yes | No

Back to the AWS Support Knowledge Center

Need help? Visit the AWS Support Center

Published: 2017-07-03