benedetti68 - Fotolia

Tip

How CloudFormation Macros stack up against other IaC tools

Developers can use an updated CloudFormation feature to manage and deploy IaC templates with Lambda. However, other native and third-party tools may be better choices depending on users' needs.

Developers can use CloudFormation Macros to customize their stack via Lambda functions -- one of several ways they can manage infrastructure as code on AWS.

CloudFormation Macros eliminate the need to copy and paste the same chunk of configuration code multiple times, either within the same or several different CloudFormation templates. It's the latest tool developers can use to manage and deploy infrastructure as code, but multiple factors will determine if it's the right fit for their architecture -- or whether they're better with other native tools or a third-party option.

How to use CloudFormation Macros

Developers can use CloudFormation Macros in either YAML or JSON format; however, the Lambda functions will always receive a JSON version of the template, or template fragment, to process. The Lambda macro must also return the template in JSON format, which should then be added back into the CloudFormation template.

Additionally, developers can use the output from one CloudFormation Macro as input for another CloudFormation Macro, essentially chaining the macros together. This lets developers stitch together complex tasks, which can be broken down into more manageable pieces. This can be helpful when a developer wants to return a template snippet that's then passed into the AWS Serverless Application Model (SAM) macro.

For example, there could be a template called DefaultProxyFunction that creates an API Gateway proxy for all the requests to be sent to a single Lambda function:

LambdaFunction:

  Type: AWS::Serverless::Function

  Properties:

    'Fn::Transform':

      - Name: DefaultProxyFunction

        Parameters:

          CodeUri: 's3://exampleBucket/fnc.zip'

The associated Lambda function can get the CodeUri from the transform function call and then return the appropriate SAM template to create a Lambda function:

function handler(event) {

  return {

    requestId: event.requestId,

    status: 'success',

    fragment: {

      CodeUri: event.params.CodeUri,

      Hander: 'index.handler',

      Runtime: 'nodejs8.10',

      Events: {

        ProxyApiRoot: {

          Type: 'API',

          Properties: {

            RestApiId: '!Ref ApiGatewayApi',

            Path: '/',

            Method: 'ANY',

          }

        },

        ProxyApiGreedy: {

          Type: 'API',

          Properties: {

            RestApiId: '!Ref ApiGatewayApi',

            Path: '/{proxy+}',

            Method: 'ANY',

          }

        }

      }

    }

  }
}

In the CloudFormation template, this example Lambda function transforms the last four lines from the previous example into the 16 lines required to create a basic serverless function that accepts all the requests from an API Gateway. These 16 lines are then passed into the SAM template, which converts them into the final CloudFormation template, which is about 30 lines of code.

For developers who create many Lambda functions that proxy all HTTP requests from an API Gateway to the same function, this greatly reduces the amount of repeated code and ensures all the templates are uniformly created. Additionally, if developers decide to, for example, update everything to a newer version of Node.js, they only need to change it in the DefaultProxyFunction CloudFormation Macro.

CloudFormation Macros vs. Amazon CDK

Organizations can also use the Amazon Cloud Development Kit (CDK) to produce complex CloudFormation templates with code. However, unlike Macros, CDK runs locally and isn't part of the CloudFormation launch process. CDK consists of two parts: the CDK Toolkit and the AWS Construct Library.

The Construct Library is available for most programming languages, and it is a set of wrapper functions developers can use to more easily design and define the infrastructure the CloudFormation template will create. Developers can use the CDK to describe the infrastructure in their preferred programming language rather than writing CloudFormation templates in either JSON or YAML.

For example, to create a Lambda function that accepts any HTTP request via API Gateway in TypeScript, a developer would use the following:

import cdk = require('@aws-cdk/cdk');
import sam = require('@aws-cdk/aws-sam');

class SimpleLambdaFunction extends cdk.Stack {

    constructor(parent: cdk.App, id: string, props?: cdk.StackProps) {

        super(parent, id, props);

        new sam.LambdaFunction(this, simpleLambdaFunction('s3://…'))

    }

}

function simpleLambdaFunction(CodeUri: string) {

  return {

    CodeUri,,

    Handler: 'index.handler',

    Runtime: 'nodejs8.10',

    Events: {

      ProxyApiRoot: {

        Type: 'API',

        Properties: {

        RestApiId: '!Ref ApiGatewayApi',

        Path: '/',

        Method: 'ANY',

     },

     ProxyApiGreedy: {

       Type: 'API',

       Properties: {

       RestApiId: '!Ref ApiGatewayApi',

       Path: '/{proxy+}',

       Method: 'ANY',

    }

 };
}

Before the stack is launched, a developer can use the CDK command line to see what kind of template this will produce. To do this, he must call cdk synth and then launch the stack with cdk deploy.

Terraform, the third-party alternative

Terraform is an open source tool and isn't specific to AWS. Similar to CloudFormation, developers can use Terraform to create a template that defines an application stack, but in a proprietary, JSON-like language. Unlike CloudFormation, the Terraform application can exist across multiple cloud providers or launch on a different provider depending on the input parameters.

Terraform creates infrastructure using Modules, which developers can use to deploy an application stack on local or physical hardware or on public clouds. Developers can create their own Modules for additional functionality, and those self-contained packages can also call on other Modules. In this way, Terraform is similar to CloudFormation Macros because it makes it easier to create more complex resources.

Terraform is popular with traditional IT operations teams because it supports multiple environments, including on premises. It's also popular with Go users because it's not only written in Go, but also uses a definition language similar to Go.

So which template language is right for you?

Organizations that exclusively use AWS can incorporate CloudFormation Macros or CDK into their development processes to create complex resources with fewer lines of code. Alternatively, Terraform might be a better choice for those who need to create application stacks that are reusable across multiple cloud providers or that are deployed to local hardware.

Next Steps

Steps to launch an EC2 instance using AWS CloudFormation

Dig Deeper on AWS cloud development

App Architecture
Cloud Computing
Software Quality
ITOperations
Close