CloudFormationコード(yaml)からパラメータ一覧を作りたい


はじめに

CloudFormationのyamlファイルから、パラメータに関する情報のみ抜き出して、一覧を作れるか挑戦しました。yamlの書き方によってはエラーになる未完成品ですが、個人的には及第点をとれたのでここに残します。

参考

今回のスクリプト作成にあたり、参考にさせて頂いたサイトです。

スクリプト(Python3)

早速ですが、スクリプトを紹介します。

  • スクリプトの流れ
    • (1)CloudFormationコード(yaml)をテキストファイルとして読み込む
    • (2)短縮構文を拡張する(例: !Sub -> Fn::Sub , !Ref -> Fn::Ref
    • (3)短縮構文がない状態でyamlとして読み込む
    • (4)yamlの中身を確認し、Parameters配下の情報をリスト表示する
paramlist.py
## command sample
## python paramlist.py test.yml

# yamlモジュールインストール `$ pip install pyyaml`
import yaml
import sys
import re

# 深堀りしない
exclusionStr = "|AWSTemplateFormatVersion|Description|Type|TemplateURL|DependsOn|Mappings|Outputs|"

args = sys.argv
path = args[1]

#(1)CloudFormationコード(yaml)をテキストファイルとして読み込む
f = open(path)
s0 = f.read()
f.close()

# (2)短縮構文を拡張する(例: `!Sub` -> `Fn::Sub` , `!Ref` -> `Fn::Ref`)
s1 = re.sub("!((Sub|Ref|Join|GetAtt|FindInMap))\s", r'Fn::\1 ', s0)

#(3)短縮構文がない状態でyamlとして読み込む
obj = yaml.safe_load(s1)

#(4)yamlの中身を確認し、Parameters配下の情報をリスト表示する
def readYaml( curObj, pathStr , exeFlg):
    try:
        if exeFlg == 0:
            for key in curObj:
                # 次の階層に進む
                curFlg = key in exclusionStr
                if not curFlg:
                    if key == "Parameters":
                        nxtFlg = 1
                    else:
                        nxtFlg = 0
                    pathStr += "/" + key
                    readYaml( curObj[key] , pathStr , nxtFlg)
        else:
            print("---- {0} ----".format( pathStr ) )
            # パラメータの項目と値を表示
            for key in curObj:
                print( "\t{0} - {1}".format(key , curObj[key] ) )
    except Exception as e:
        print("ERROR curObj = {0}, pathStr = {1}, exeFlg = {2}".format( curObj, pathStr, exeFlg ) )
        print(e)

#############################
## -------- START -------- ##
print("---- Parameter List ----" )
readYaml( obj , "" , 0 )

実行結果

以下のCloudFormationコードに対してスクリプトを実行します。

test.yml
AWSTemplateFormatVersion: "2010-09-09"
Description: cloudformation yaml sample

Parameters:
  hogePrefix:  { Type: String , Default: hogefuga123 }
  BucketUrl: { Type: String , Default: "https://hogefuga123.s3.amazonaws.com/" }
  AZName001: { Type: String , Default: ap-northeast-1a }
  AZName002: { Type: String , Default: ap-northeast-1c }
  VPCName: { Type: String , Default: vhoge01 }

Resources:
  VPC:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: !Sub "${BucketUrl}${VPCTemplate}"
      Parameters: 
        hogePrefix: !Ref hogePrefix
        BucketUrl: !Ref BucketUrl
        VPCName: !Ref VPCName

実行結果

$ python paramlist.py test.yml
---- Parameter List ----
---- /Parameters ----
        hogePrefix - {'Type': 'String', 'Default': 'hogefuga123'}
        BucketUrl - {'Type': 'String', 'Default': 'https://hogefuga123.s3.amazonaws.com/'}
        AZName001 - {'Type': 'String', 'Default': 'ap-northeast-1a'}
        AZName002 - {'Type': 'String', 'Default': 'ap-northeast-1c'}
        VPCName - {'Type': 'String', 'Default': 'vhoge01'}
---- /Parameters/Resources/VPC/Properties/Parameters ----
        hogePrefix - Fn::Ref hogePrefix
        BucketUrl - Fn::Ref BucketUrl
        VPCName - Fn::Ref VPCName

おまけ

[おまけ1] Cloud9 のセットアップ

本スクリプトを AWS Cloud9 で使うときの環境設定です。

# デフォルトを Python 2 -> Python 3 に切り替える
$ sudo alternatives --config python

$ pip -V
$ sudo pip install --upgrade pip
$ pip -V

# yamlモジュールをインストール
$ pip install pyyaml

[おまけ2] そのままyamlロードするとエラーになる

上のサイトで紹介されている通り、短縮系の構文を含むCloudFormationコードをyamlとしてロードするとエラーになります。

$ python sample.py test.yml
test.yaml
Exception occurred while loading YAML...
could not determine a constructor for the tag '!Sub'
  in "test.yaml", line 72, column 20

作ったスクリプトは未完成、どんなyaml形式でもエラーがでないようにしたい。