Integration & Automation

Deploy CloudFormation stacks at the click of a button

If you frequently set up demo environments using Amazon Web Services (AWS) CloudFormation and wish you had a faster push-button way of doing so, this blog post is for you. Today I present a simple method to launch your stack in a single-button click using the AWS IoT Button. The following diagram gives a quick overview of the architecture.

iot button deployment diagram

Prerequisites

The button setup

This blog requires that you have the AWS IoT Button and that you have connected it to your AWS account and tested out the sample application that sends out email notification to a provided email address. For details, see the AWS IoT Button Overview. Use the iOS or Android app to set up your button and test a new AWS Lambda function, as shown in the screenshot. You can choose the Send Email (python) function, as we are going to use the Python 3.6 runtime to build our Lambda function.

send email python option

After you’ve verified that the button is working and you are able to successfully send email on a button click, you’re ready to move to the next step.

AWS CloudFormation template URL and parameters

In addition to setting up the button, you need to choose the template URL for the AWS CloudFormation template you want to deploy and the input parameters required to launch the template. For testing you, you can use this template URL and input parameter file that will set up a new AWS Systems Manager parameter. Make sure that you copy the parameter file to an Amazon Simple Storage Service (Amazon S3) bucket in your account, and make a note of the S3 URI of the uploaded file.

Setting up a Lambda function to deploy a CloudFormation stack

We’re using the Python 3.6 runtime to build the Lambda function. It takes two inputs as environment variables: the URL of the template you want to deploy and the Amazon S3 URI of the file that contains the necessary parameters used for deploying the stack. You can parse the input parameters to a JSON object in the parse_params method. The launch_stack method uses the JSON parameters and template URL to call the AWS CloudFormation create_stack API. Lastly, the handler method acts as an entry point for the Lambda function.

import json
import boto3
import os
from datetime import datetime
from urllib.parse import urlparse

params_url = os.environ['paramsFile']
template_url = os.environ['templateUrl']

def parse_params():
  s3 = boto3.resource('s3')
  s3_parse = urlparse(params_url)
  bucket = s3_parse.netloc
  s3_key = s3_parse.path.lstrip('/')
  s3_obj = s3.Object(bucket, s3_key)
  template_raw_data = s3_obj.get()["Body"].read().decode('utf-8')
  template_params = json.loads(template_raw_data)
  return template_params
  
def launch_stack():
  cfn = boto3.client('cloudformation')
  current_ts = datetime.now().isoformat().split('.')[0].replace(':','-')
  stackname = 'Iot-qs-deploy-' + current_ts
  capabilities = ['CAPABILITY_IAM', 'CAPABILITY_AUTO_EXPAND']
  try:
    template_params = parse_params()
    stackdata = cfn.create_stack(
      StackName=stackname,
      DisableRollback=True,
      TemplateURL=template_url,
      Parameters=template_params,
      Capabilities=capabilities)
  except Exception as e:
    print(str(e))
  return stackdata  

def handler(event, context):
  print("Received event:")
  stack_result=launch_stack()
  print(stack_result)

Automating the deployment

As an example, I have provided an AWS CloudFormation template to deploy the Lambda-IoT-Deploy Lambda function. It takes the two inputs that I mentioned in the prerequisites section: the URL of the AWS CloudFormation template you want to deploy, and the URI of the input parameter file you want to use for setting up the CloudFormation stack.

Input configuration:

Parameter label
(name)
Description
Template URL
(TemplateURL)
URL of the AWS CloudFormation template you want to deploy; e.g., https://s3.amazonaws.com/aws-quickstart/quickstart-examples/samples/iot-button-deploy-cloudformation/demo-stack.yaml.
Parameters file S3 URI
(ParamsFile)
S3 URI of the parameters file stored in your S3 bucket; e.g., s3://my-bucket/demo-params.json.

You can visit our GitHub repository to dive deep into the source. There are two important points to note.

  • The Lambda function is set up with two variables, templateUrl and paramsFile, that point to your input template URL and parameters file. If in the future you want to test with a different template and input parameters, you can use the Lambda console to update the environment variables of the Lambda function.
  • The Lambda function has been granted the Administrator role to allow AWS CloudFormation to create any AWS resources that are defined in your template.

Deployment steps

  1. Use this direct link to launch the AWS CloudFormation template in the US East (Ohio) Region. If you need to change the Region, choose a different one by using the Region selector in the upper-right corner of the navigation bar.
  2. Choose Next, and then on the Specify stack details page, provide the template URL and S3 URI of the parameters file.
  3. Choose Next, and continue to choose Next on the subsequent pages until you see the Create Stack option.
  4. Choose Create Stack to deploy the stack.
  5. Monitor the status of the stack. When the status is CREATE_COMPLETE, choose the Resources tab for the CloudFormation stack to confirm that the Lambda function Lambda-IoT-Deploy has been created.

resources tab

Now we’re ready to reconfigure our button.

Updating the AWS IoT Button action

Next, we need to update the button action to invoke the Lambda-IoT-Deploy function instead of the current Send Email (python) Lambda function. For that, open the AWS IoT Button app on your device and choose the Lambda configuration icon. On the next view, select Existing λ functions, scroll down to pick the Lambda-IoT-Deploy function that you created, and choose Change action.

screen for choosing new lambda function

Testing the deployment

Now we’re ready to test the CloudFormation deployment using the AWS IoT Button. Press the button once and wait until the blinking light becomes steady green and then turns off. Then go to the AWS CloudFormation console and verify that the stack creation has started.

stack creation status

Conclusion

I have presented a simple method for you to streamline demo deployments by using AWS CloudFormation and the AWS IoT Button. I look forward to reading your feedback and any enhancements you come up with.