ljmc's blog

YAML booleans in cloudformation templates

I work with a lot of YAML in my day job, mostly CFN and SAM templates. I had not thought about YAML's Norway Problem in this context until recently, when I reviewed a PR in which a teammate had added a new environment variable set to true which a YAML bool, not a string.

Resources:
  SomeVeryInterestingFunction:
    Type: AWS::Serverless::Function
    Properties:
      
      Environment:
        Variables:
          ENABLE_FOO: true

In this case, my teammate had tested true and false values, and confirmed they were expectedly passed as string "true" and "false". But, while true and false are the only bool values in YAML 1.2, most YAML parsers will be somewhat compliant with YAML 1.1, which has 22 distinct values for bool type.

y|Y|yes|Yes|YES|n|N|no|No|NO
|true|True|TRUE|false|False|FALSE
|on|On|ON|off|Off|OFF

What do all these other bool values produce in CFN environment variables ? I wondered that too, so I passed all those YAML 1.1 boolean values to a simple python function with returns them in a JSON object from the os.environ dict.

Resources:
  YamlBoolEnvVarCheckerFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: python3.11
      MemorySize: 128
      InlineCode: |
        import json
        import os

​       def handler(*_):
    ​       return json.dumps(
                {k: v for k, v in os.environ.items() if k.startswith("BOOL")}
            )
      Environment:
        Variables:
          BOOL_y: y
          BOOL_Y: Y
          BOOL_yes: yes
          BOOL_Yes: Yes
          BOOL_YES: YES
          BOOL_n: n
          BOOL_N: N
          BOOL_no: no
          BOOL_No: No
          BOOL_NO: NO  # hello ISO-3166-1 Norway
          BOOL_true: true
          BOOL_True: True
          BOOL_TRUE: TRUE
          BOOL_false: false
          BOOL_False: False
          BOOL_FALSE: FALSE
          BOOL_on: on
          BOOL_On: On
          BOOL_ON: ON
          BOOL_off: off
          BOOL_Off: Off
          BOOL_OFF: OFF

Built it and ran it locally:

% sam build && sam local invoke | jq 'fromjson'

And this is the output. Most values give "true" and "false" as expected, the exceptions being the single letter bool values which give themselves as string value.

{
  "BOOL_y": "y",
  "BOOL_Y": "Y",
  "BOOL_yes": "true",
  "BOOL_Yes": "true",
  "BOOL_YES": "true",
  "BOOL_n": "n",
  "BOOL_N": "N",
  "BOOL_no": "false",
  "BOOL_No": "false",
  "BOOL_NO": "false",
  "BOOL_true": "true",
  "BOOL_True": "true",
  "BOOL_TRUE": "true",
  "BOOL_false": "false",
  "BOOL_False": "false",
  "BOOL_FALSE": "false",
  "BOOL_on": "true",
  "BOOL_On": "true",
  "BOOL_ON": "true",
  "BOOL_off": "false",
  "BOOL_Off": "false",
  "BOOL_OFF": "false"
}

All in all, this bool value in environment variable seems like a footgun to me, so I share it here and we improved our internal SAM template standards with a new rule to use unambiguous strings.

#aws #experiment #yaml