CloudFormation YAML について

この記事は公開されてから半年以上経過しています。情報が古い可能性がありますので、ご注意ください。

CloudFormation を YAML で書く時、当然ながら YAML の仕様も理解しないといけないんだなと感じたきっかけ等についてお話します。
得た結論としては以下です。

  • CloudFormation を YAML で書く時は YAML の仕様にも注意
  • AWSアカウントIDはクォートするのが無難

発生した事象

以下のようなテンプレートで CloudFormation スタックを作成すると、リソースの作成に失敗しました。

Parameters:
  ReceiverAccountId:
    Type: String
    Default: 012345678901

Resources:
  Policy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Action: 'events:PutEvents'
            Resource: !Sub "arn:aws:events:us-east-1:${ReceiverAccountId}:event-bus/default"

対象リソース(IAM Policy)作成時、以下のようなエラーが発生していました。

The policy failed legacy parsing (Service: AmazonIdentityManagement; Status Code: 400; Error Code: MalformedPolicyDocument; Request ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx; Proxy: null)

よく見るとパラメータ「ReceiverAccountId」のデフォルト値が、012345678901 -> 1.2345678901E10 というように指数表示に変換されてしまったようです。

解決した方法

以下のように Default 値をクオーテーションで囲むと本来の「012345678901」となり、デプロイが成功しました。

Parameters:
  ReceiverAccountId:
    Type: String
    Default: '012345678901'

気づいたこと

上記事象について、当初は「数値だけ書くとおかしくなるからクォートすればいいんだな」としか考えてなかったのですが、本記事を書くにあたりいくつか検証したところ気づくことがありました。

以下テンプレート(一部)の場合は該当のパラメータが「1」になりました。
まぁ、ゼロが取り除かれちゃったのかな?

Parameters:
  ReceiverAccountId:
    Type: String
    Default: 000000000001

以下の場合は「9」でした。
??

Parameters:
  ReceiverAccountId:
    Type: String
    Default: 000000000011

以下の場合は「10」でした。
ここでようやく、どうやら8進数になってるらしいぞと気づきました。

Parameters:
  ReceiverAccountId:
    Type: String
    Default: 000000000012

更に調べると、以下のような情報も見つけました。
どうやら YAML の解釈プロセスによって値が変換されていたようです。
YAML Version 1.1 – 2.4. Tags ※1

Example 2.19. Integers

canonical: 12345
decimal: +12,345
sexagesimal: 3:25:45
octal: 014
hexadecimal: 0xC

最初の 012345678901 -> 1.2345678901E10 という変換についてはハッキリとした答えを見つけられませんでした。
ただ、「012345678901」という値については「0から始まっているが」「8以上の数が含まれている=8進数ではない」という点がポイントなのかなと思っています。

※1 CloudFormation は YAML 1.1 に対応
AWS CloudFormation テンプレート形式

AWS CloudFormation は、いくつかの例外を除き、YAML バージョン 1.1 の仕様をサポートしています。

まとめ

再掲ですが、下記となります。

  • CloudFormation を YAML で書く時は YAML の仕様にも注意
  • AWSアカウントIDはクォートするのが無難