AWS CloudFormation Parameters Tips: Size and AWS Types

While AWS CloudFormation is one of the best ways to ensure your AWS environments are reproducible it can also be a bit of an awkward beast to use. Here are a couple of simple time saving tips for refining your CFN template parameters.

The first one is also the simplest, always define at the least a MinLength property on your parameters and ideally an AllowedValues or AllowedPattern. This ensures that your stack will fail early if no value is provided. Once you start using other tools, like Ansible, to glue your stacks together it becomes very easy to create a stack parameter that has an undefined value. Without one of the above parameters CloudFormation will happily use the null and you’ll either get an awkward failure later in the stack creation or a stack that doesn’t quite work.

The second tip is for the parameters type property. While it’s possible to use a ‘type’ of ‘String’ and an ‘AllowedPattern’ to ensure a value looks like an AWS resource, such as a subnet id, the addition of AWS- specific types, available from November 2014, allows you to get a lot more specific:

  # note the value of "Type"
  "Parameters" : {

    "KeyName" : {
      "Description" : "Name of an existing EC2 KeyPair",
      "Type" : "AWS::EC2::KeyPair::KeyName",
      "Default" : "i-am-the-gate-keeper" 
    }

  }

This goes one step beyond ‘Allowed*’ and actually verifies the resource exists in the users account. It doesn’t do this at the template validation stage, which would be -really- nice, but it does it early in the stack creation so you don’t have a long wait and a failed, rolled back, set of resources.

    # a parameter with a default key name that does not exist in aws
    "KeyName" : {
      "Description" : "Name of an existing EC2 KeyPair",
      "Type" : "AWS::EC2::KeyPair::KeyName",
      "MinLength": "1",
      "Default" : "non-existent-key"
    }

    # validate shows no errors
    $ aws cloudformation validate-template --template-body file://constraint-tester.json
    {
        "Description": "Test an AWS-specific type constraint", 
        "Parameters": [
            {
                "NoEcho": false, 
                "Description": "Name of an existing EC2 KeyPair", 
                "ParameterKey": "KeyName"
            }
        ], 
        "Capabilities": []
    }

    # but after we start stack creation and check the dashboard
    # CloudFormation shows an error as the second line in events
    ROLLBACK_IN_PROGRESS    AWS::CloudFormation::Stack      dsw-test-sg
    Parameter value non-existent-key for parameter name KeyName
    does not exist. . Rollback requested by user.

Neither of these tips will prevent you from making the error, or unfortunately catch them on validation. They will surface the issues much quicker on actual stack creation and make your templates more robust. Here’s a list of the available AWS Specific Parameter Types, in the table under the ‘Type’ property and you can find more details in the ‘AWS-Specific Parameter Types’ section.