はじめに
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形式でもエラーがでないようにしたい。