Self Exploding Cloudformation Stacks

Let's discover how can we Automatically delete a Cloudformation Stack with a pre-defined TTL

ยท

5 min read

Self Exploding Cloudformation Stacks

Sometimes we create a stack for testing or checking something and then we forget to delete it and then those resources, which we have created, keep burning our money for a long time.

So At the end of this Article, we will be able to understand some key concepts like -

  1. What are Custom Resources (Lambda Backed) in CloudFormation?
  2. The service token in Custom Resource
  3. The cfn-response module in Lamba Functions
  4. And Much more minor but useful things...

We will try to understand each piece of the puzzle and then we will fit all pieces together. So, let's dive right into it.

A high-level View

  • We will take TTL as Input (in form of CF Parameter)
  • We will generate a cron expression(using a Lambda Function) to represent the exact time in the future of our TTL.
  • This Cron will be used in a CloudWatch Events Rule which will trigger another Lambda Function at that specified time which will delete our Entire stack using API Calls.

Cron Generation

Now we have a challenge that we have to generate cron expression for CloudWatch Events Rule, We can solve this easily by using some programming Skills.

Suppose we are taking TTL from the user in minutes.

We can write a few lines in Python to get the corn exp we want.

The datetime module makes it pretty easy to do various operations with time.


So now we have our Cron Expression we generated using TTL value. Now we can assign this Cron Expression to a CloudWatch Rule in Cloudformation.

Now, The Next Challenge is to Delete a stack using another Lambda Function.

Delete your CF Stack

You know what, deleting a CF stack using a Lambda function is way easier than you can think. Thanks to SDKs & Resource APIs AWS provides us for various operations.

The point to be noted here is that the deletion of Resources depends on the role that is assigned to the Lambda function, if it lacks any permission the deletion will fail, so for our demo purpose I have given the Administrator Access but I will highly recommend you to not to do the same when using this approach

So, You can delete a stack using code like the below example:

import boto3
import os

stack_name = os.environ['stackName']

def delete_cfn(stack_name):
    try:
        cfn = boto3.resource('cloudformation')
        stack = cfn.Stack(stack_name)
        stack.delete()
        return "SUCCESS"
    except:
        return "ERROR" 

delete_cfn(stack_name)

Now, we have to pass the generated cron expression from the first lambda function to the second lambda function.

We can do the above-mentioned thing using CloudFormation Custom Resource.

How do Custom Resources work?

With the help of Custom Resource, we can write a custom provisioning logic, (for resources that aren't available directly in CloudFormation). Also, CF executes these logical resources whenever you create/update/delete the stack.

The one property which is mandatory for Custom Resources is Service Token. Note this -> Service Token is the address where CloudFormation will send all the requests (create, delete, etc.) and after sending requests CF waits for a Response (SUCCESS/FAILED) so it can continue the creation/deletion of that custom Resource.

As we are using a Lambda Function for our custom resource the service token would be the ARN of that Lambda function.

With the service token, we can also pass some variables for our use. (we will pass TTL.)

So we will design our Custom Resource in a way that it will take TTL from CF Parameters, Calculate the cron expression and pass the calculated cron expression to the next lambda function.

Example -

  GenerateCronExpression:
    Type: "Custom::GenerateCronExpression"
    Version: "1.0"
    Properties:
      ServiceToken: !GetAtt GenerateCronExpLambda.Arn
      ttl: !Ref 'TTL'

So, this is how all pieces look together:

I have tried to add comments wherever possible. So If you go through the below code you will get an idea, what we have done here.


If you have reached down till here then I have the explanation of the above code for you :) - Resources section of CF has three types of resources -

  1. Cron Generation Resources
  2. Resources that will help that lambda function to delete all other resources
  3. Actual CF Resources that we want to create and delete after TTL.

And as I promised at the start of the blog that we will learn about a utility called cfn-response, Well, When you use the ZipFile property to specify your function's source code and that function interacts with an AWS CloudFormation custom resource, you can load the cfn-response module to send responses to those resources.

In our case, we are using this module to send a Success signal when we have generated our Cron Expression for deletion. See this,

def handler(event, context):
print('Received event: %s' % json.dumps(event))
status = cfnresponse.SUCCESS
try:
    if event['RequestType'] == 'Delete':
        cfnresponse.send(event, context, status, {})
    else:
        ttl = event['ResourceProperties']['ttl']
        responseData = {}
        responseData['cron_exp'] = deletion_time(ttl)
        cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData)

I want you to notice the part where it sends a response after processing TTL and generating the Cron Expression and then, sending all info as a response using cfnresponse.send().

our corn expression is In the responseData dict with key as cron_exp.

Read the blog I have attached at the bottom for more info.


What Next? ๐Ÿค”

Now you can use this template to create AWS Resources which will be deleted after a certain point of time aka TTL(Time-to-live).


I have just started writing this kind of stuff so if you find a mistake or have any suggestion for me, feel free to shoot a text to me @ Kratik Jain


References:

  1. Cloudformation Custom Resources - AWS Offical Docs
  2. AWS::CloudFormation::CustomResource
  3. cfn-response module
  4. How custom resources work
  5. AWS Official Blog by Vinod Shukla
  6. GitHub - AWS QuickStart Example - cloudformation-stack-ttl
  7. Sample Template from AWS for EC2,SG & EIP

Wanna buy me a Coffee โ˜• ?

buy-me-a-coffee.jpeg

Did you find this article valuable?

Support Kratik Jain by becoming a sponsor. Any amount is appreciated!

ย