BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News AWS CloudFormation Adds New Language Extensions

AWS CloudFormation Adds New Language Extensions

AWS has added new language transforms that enhance the core CloudFormation language. For this initial release it includes new intrinsic functions for JSON string conversion, obtaining the length of a list, and support for intrinsic functions and pseudo-parameter references in update and deletion policies.

The new Fn::ToJsonString intrinsic function provides a simpler way to provide JSON data as input to an attribute. For example, AWS::CloudWatch::Dashboard requires a JSON string for the DashboardBody attribute. Prior to this release, JSON could be used but had to be pre-converted to a JSON string affecting the readability of the script:

"MyDashboard": {
    "Type": "AWS::CloudWatch::Dashboard",
    "Properties": {
        "DashboardBody": "{\"start\":\"-PT6H\",\"periodOverride\":\"inherit\",\"widgets\":[{\"type\":\"text\",\"x\":0,\"y\":7,\"width\":3,\"height\":3,\"properties\":{\"markdown\":\"Hello world\"}}]}"
    }
}

The new Fn::ToJsonString intrinsic function allows for the above to be written as:

"MyDashboard": {
    "Type": "AWS::CloudWatch::Dashboard",
    "Properties": {
        "DashboardBody": {
            "Fn::ToJsonString": {
                "start": "-PT6H",
                "periodOverride": "inherit",
                "widgets": [
                    {  
                        "type": "text",
                        "x": 0,
                        "y": 7,
                        "width": 3,
                        "height": 3,
                        "properties": { "markdown": "Hello world" }
                    }
                ]
            }
        }
    }
}

Intrinsic functions (e.g., Fn::If, Ref) or pseudo-parameters (e.g., AWS::NoValue) can be used within the input template block. The resolved value of the function will be converted to the output string and not the function itself. At the time of release, the following pseudo parameters are supported: AWS::AccountId, AWS::Region, AWS::Partition, AWS::NoValue, AWS::StackId, AWS::StackName, and AWS::URLSuffix. Conversions will retain the same ordering of key-value pairs ensuring that the converted string does not change during subsequent runs.

The second new intrinsic function is Fn::Length which returns the length of a given list. It supports parameters of the type List<Number> and CommaDelimitedList. It can be combined with other intrinsic functions such as !Select and !Split.

One limitation of the new function is that it can only compute values that are known when the transform runs, so the following example will not work:

{
  "Fn::Length": { "Fn::Split": [":", { "Fn::GetAtt": [ "MyBucket", "Arn" ] } ] }
}

In the example above, assume that MyBucket is the logical ID of an AWS:S3:Bucket resource. This won't work as the ARN of MyBucket is not known until provisioning. The team has stated that this limitation will be removed at some point.

The final addition allows for dynamically resolving intrinsic functions and parameter references within DeletionPolicy and UpdateReplacePolicy. This allows for resolving values from the Parameters, Mappings, and Conditions sections of the CloudFormation template.

The following example makes use of Fn::FindInMap and the AWS::Region pseudo-parameter to appropriately set the DeletionPolicy based on the current region:

{
    "AWSTemplateFormatVersion" : "2010-09-09",
    "Parameters": {
        "Stage": {
            "Type": "String",
            "AllowedValues": ["Prod", "Staging", "Dev"]
        }
    },
    "Mappings" : {
        "RegionMap" : {
            "eu-west-1" : {
                "DeletionPolicy": "Retain"
            },
            "ap-southeast-1" : {
                "DeletionPolicy": "Delete"
            }
        }
    },
    "Resources": {
        "Bucket": {
            "Type": "AWS::S3::Bucket",
            "DeletionPolicy": {
                "Fn::FindInMap" : [
                    "RegionMap",
                    { "Ref" : "AWS::Region" },
                    "DeletionPolicy"
                ]
            }
        }
    }
}

These new features require that you add AWS::LanguageExtensions to the transform section of your template. If there is a list of transforms, they recommend having AWS managed transforms at the end. Note that AWS::LanguageExtensions must be listed before AWS::Serverless:

---
AWSTemplateFormatVersion: 2010-09-09
Transform: 
  - 'AWS::LanguageExtensions'
  - 'AWS::Serverless-2016-10-31'

These new features are available for use in Cloudformation in both YAML and JSON forms. Dan Blanco, senior AWS developer advocate, notes that the team has more extensions planned and is welcoming feedback via their Request for Comments (RFC) process.

About the Author

Rate this Article

Adoption
Style

BT