[PYTHON] I want to make a parameter list from CloudFormation code (yaml)

Introduction

I tried to make a list by extracting only the information about the parameters from the cloudFormation yaml file. It is an unfinished product that may cause an error depending on how to write yaml, but I personally got the point, so I will leave it here.

reference

This is the site that I used as a reference when creating this script.

-Handling YAML files in Python -[Small story] How to avoid being disturbed by the abbreviated syntax of built-in functions when parsing CloudFormation templates in Python

Script (Python3)

Immediately, I will introduce the script.

--Script flow -(1) Read the CloudFormation code (yaml) as a text file -(2) Extend the abbreviated syntax (Example: ! Sub-> Fn :: Sub, ! Ref-> Fn :: Ref) -(3) Read as yaml without abbreviated syntax -(4) Check the contents of yaml and display the information under Parameters in a list.

paramlist.py


## command sample
## python paramlist.py test.yml

#yaml module installation`$ pip install pyyaml`
import yaml
import sys
import re

#Do not dig deep
exclusionStr = "|AWSTemplateFormatVersion|Description|Type|TemplateURL|DependsOn|Mappings|Outputs|"

args = sys.argv
path = args[1]

#(1) CloudFormation code(yaml)As a text file
f = open(path)
s0 = f.read()
f.close()

#(2) Extend the abbreviated syntax (example:`!Sub` -> `Fn::Sub` , `!Ref` -> `Fn::Ref`)
s1 = re.sub("!((Sub|Ref|Join|GetAtt|FindInMap))\s", r'Fn::\1 ', s0)

#(3) Read as yaml without abbreviated syntax
obj = yaml.safe_load(s1)

#(4) Check the contents of yaml and display a list of information under Parameters.
def readYaml( curObj, pathStr , exeFlg):
    try:
        if exeFlg == 0:
            for key in curObj:
                #Go to the next level
                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 ) )
            #Display parameter items and values
            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 )

Execution result

Run the script against the following CloudFormation code.

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

Execution result

$ 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

bonus

[Bonus 1] Cloud9 setup

This is the environment setting when using this script on AWS Cloud9.

#Default to Python 2->Switch to Python 3
$ sudo alternatives --config python

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

#install yaml module
$ pip install pyyaml

[Bonus 2] If you load yaml as it is, an error will occur.

-[Small story] How to avoid being disturbed by the abbreviated syntax of built-in functions when parsing CloudFormation templates in Python

As introduced on the site above, loading CloudFormation code with abbreviated syntax as yaml will result in an error.

$ 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

line.png

The script I made is incomplete and I want to make sure there are no errors in any yaml format.

Recommended Posts

I want to make a parameter list from CloudFormation code (yaml)
I want to make C ++ code from Python code!
[Python] I want to make a nested list a tuple
I want to make a game with Python
I want to make fits from my head
I want to make a blog editor with django admin
I want to start a lot of processes from python
I want to make a click macro with pyautogui (desire)
I want to make a click macro with pyautogui (outlook)
I want to install a package from requirements.txt with poetry
I want to send a message from Python to LINE Bot
I want to make the Dictionary type in the List unique
I want to make input () a nice complement in python
python / Make a dict from a list.
[Introduction] I want to make a Mastodon Bot with Python! 【Beginners】
I want to print in a comprehension
I want to use jar from python
I want to build a Python environment
I want to make an automation program!
I tried to make a Web API
I want to send a signal only from the sub thread to the main thread
[Python memo] I want to get a 2-digit hexadecimal number from a decimal number
I want to sort a list in the order of other lists
I want to make a web application using React and Python flask
I want to connect to PostgreSQL from various languages
I want to easily create a Noise Model
I want to INSERT a DataFrame into MSSQL
I want to create a window in Python
I want to email from Gmail using Python.
[Python] I want to manage 7DaysToDie from Discord! 1/3
I want to perform SageMaker inference from PHP
I don't want to take a coding test
I want to use ceres solver from python
I want to create a plug-in type implementation
I read "How to make a hacking lab"
[Python] I want to manage 7DaysToDie from Discord! 2/3
I want to easily find a delicious restaurant
I want to write to a file with Python
I tried to make a ○ ✕ game using TensorFlow
I want to upload a Django app to heroku
[LINE Messaging API] I want to send a message from the program to everyone's LINE
I made a library to operate AWS CloudFormation stack from CUI (Python Fabric)
I want to make a music player and file music at the same time
I want to see a list of WebDAV files in the Requests module
I made a package to create an executable file from Hy source code
I want to write in Python! (1) Code format check
I want to see the file name from DataLoader
I tried to make a "fucking big literary converter"
I want to easily implement a timeout in python
I want to detect images of cats from Instagram
I want to iterate a Python generator many times
I want DQN Puniki to hit a home run
[Python] I want to use only index when looping a list with a for statement
100 image processing knocks !! (021-030) I want to take a break ...
I want to give a group_id to a pandas data frame
I want to transition with a button in flask
I want to climb a mountain with reinforcement learning
I want to write in Python! (2) Let's write a test
[Python] I made a system to introduce "recipes I really want" from the recipe site!
I want to tell people who want to import from a higher directory with Python direnv
[Mac] I want to make a simple HTTP server that runs CGI with Python