Menu

CloudFormation toJSON in YAML template

November 16, 2022 by Christopher Sherman

When writing CloudFormation templates, it is not uncommon for the documentation to state a property’s data type is JSON. If you write your templates in JSON, this is no obstacle. However, I prefer to write my templates in YAML, so I found myself looking for a toJSON intrinsic function to which I could pass a YAML object. My search came up empty, but I did uncover a couple of ways to satisfy JSON property types while keeping my templates readable.

Just use YAML

To illustrate the problem, consider the EventBridge EventsRule resource. It has a property, EventPattern, of type JSON. Now the reason I am writing my template in YAML is because I prefer its readability; I do not want to use JSON for this property. As it turns out, I do not have to, and the solution is simple: create a YAML object that matches the shape of the JSON object.

EventPattern:
  account:
    - !Sub '${AWS::AccountId}'
  source:
    - 'aws.ecr'
  detail-type:
    - 'ECR Image Action'
  detail:
    action-type:
      - 'PUSH'
    result:
      - 'SUCCESS'
    repository-name:
      - !Ref EcrRepository
    image-tag:
      - 'latest'

What about JSON strings?

Some CloudFormation properties expect a JSON string, and these properties have a type String. One such case is the LifecyclePolicyText property of the Elastic Container Registry’s Repository > LifeCyclePolicy resource. This property is a JSON string containing about 10 child properties, so I would prefer not to place the entire string on a single line. Thankfully I do not have to if I use the pipe symbol. The YAML specification instructs the interpreter to interpret any indented text following the pipe symbol as a single, multi-line value. This allows me to write a JSON string in a readable format within my YAML template.

LifecyclePolicyText: |
  {
      "rules": [
          {
              "rulePriority": 1,
              "description": "Keep only one untagged image, expire all others",
              "selection": {
                  "tagStatus": "untagged",
                  "countType": "imageCountMoreThan",
                  "countNumber": 1
              },
              "action": {
                  "type": "expire"
              }
          }
      ]
  }  

AWS CloudFormation