Skip to content

Custom CloudFormation

Jeff Bachtel edited this page Sep 15, 2018 · 14 revisions

Custom CloudFormation

Anytime mu manages AWS resources, it is done via a CloudFormation template. To preview the template without actually making any changes in your AWS account, add the --dryrun or -d flag. For example:

> mu -d env up acceptance
Upserting VPC environment 'acceptance' ...
  DRYRUN: Skipping create of stack named 'mu-vpc-acceptance'.  Template and parameters written to '/tmp/mu-cloudformation'
Upserting ECS environment 'acceptance' ...
  DRYRUN: Skipping create of stack named 'mu-cluster-acceptance'.  Template and parameters written to '/tmp/mu-cloudformation'

You can then view the CloudFormation templates and the parameter files passed into the templates in the directory provided in the output message.

Customization

You can customize the generated CloudFormation by adding a templates section to your mu.yml file. Additionally, you can override the tags applied to the stacks and the parameters used by the stacks via the tags: and parameters: sections respectively. The custom-cloudformation example in the GitHub repo provides a good demonstration:

environments:
  - name: example

templates:
  mu-cluster-example:
    Resources:

      # Define a new security group
      ExtraSG:
        Type: AWS::EC2::SecurityGroup
        Properties:
          VpcId:
            Fn::ImportValue: !Sub ${VpcId}
          GroupDescription: Example additional ECS Host Security Group
          SecurityGroupIngress:
          - IpProtocol: tcp
            FromPort: '8080'
            ToPort: '8080'
            CidrIp: !Ref SshAllow

      ## Update the existing launch config to reference new SG
      ContainerInstances:
        Properties:
          SecurityGroups: [ !Ref ExtraSG ]


## Override stack parameters
parameters:
  'mu-environment-acceptance':
    ImageId: ami-xxx

## Override stack tags
tags:
  'mu-environment-acceptance':
    CostCenter: research

In this example, the mu-cluster-example stack will be updated to include an additional security group named ExtraSG. Additionally, the existing resource that mu creates named ContainerInstances will be modified to include the additional security group.

WARNING: do not use the short for for intrinsic functions (e.g. use Fn::Sub, not !Sub). The ! is a YAML tag and is not able to survive deserialization and serialization.

Handling Arrays

By default, arrays are merged by concatenating them together. In some cases, you may want to replace an entire array. This can be done with Fn::Replace:

      ...

      ContainerInstances:
        Properties:
          SecurityGroups:
            Fn::Replace:
              - !Ref ExtraSG

Additionally, if you want to merge values in a array, consider Fn::Splice:

    ...

    Actions:
      Fn::Splice:
        - 1                 # start splice at index `1` in the existing list
        - 2                 # merge with next `2` items
        - - RunOrder: 10    # set the `RunOrder` for index `1`
          - RunOrder: 20    # set the `RunOrder` for index `2`

Extensions

You can share custom CloudFormation via extensions. The extension example in the GitHub repo provides a good demonstration:

## Supported URL can be:
##  - relative path to a directory, zipball or tarball
##  - s3 URL to zipball or tarball
##  - http/https/file URL to zipball or tarball
extensions:
  - url: security-group                     # relative path
  - url: s3://my-bucket/prefix/file.zip
  - url: https://www.mysite.com/file.tar.gz

You can optionally specify a mu-extension.yml file in the root of your extension:

name: bucket            # name of extension
version: '1.0'          # version of extension

## use 'templateUpdateMode: replace' to completely replace a template
templateUpdateMode: merge

Blog

See Create extensions for the mu DevOps on AWS framework

WARNING

WARNING: do not use the short form for intrinsic functions (e.g. use Fn::Sub, not !Sub). The ! is a YAML tag and is not able to survive deserialization and serialization.