AWS
CloudFormation

CloudFormationを使ってCloudFormationマクロを作成する


はじめに

本記事では、AWS CloudFormation管理コンソールを使って、CloudFormationマクロを作成する手順を説明しています。(初心者向け)

また、

本記事でサンプルとして紹介しているテンプレートのマクロの処理は、マクロに「Key」と「Description」を引数として渡すと、10桁のランダムな文字列を生成し、Systems Managerのパラメータストアに、キーとその値として10桁のランダムな文字列とその説明を登録する処理を提供しています。

本記事で掲載しているテンプレートの最新版は、下記に置いてます。

https://github.com/okubo-t/aws-cloudformation


CloudFormationマクロとは

CloudFormationのテンプレートの標準的な定義だけでは実現できない処理を、

テンプレート内からLambda関数(マクロ)を呼び出すことで実現できるようにするCloudFormationの拡張機能のことです。


参考

AWS ブログ

AWS CloudFormation を AWS Lambda によるマクロで拡張する


設定手順

1 AWS CloudFormation管理コンソールから、スタックの作成をクリックします。

2 後述のテンプレートを選択します。

3 各パラメータを入力します。

パラメータ名
用途
備考

スタックの名前
テンプレートから作成するリソース一式の名前
例 prd-stack-vpc-20180801

CFnMacroName
作成するCloudFormation マクロの名前

4 後続は、デフォルトのまま次へ次へで、作成します。

作成する前に、下記のチェックをつけること

AWS CloudFormation によってカスタム名のついた IAM リソースが作成される場合があることを承認します。

5 状況が CREATE COMPLETEになれば、CloudFormationマクロの作成が完了です。

6 Lambdaの管理コンソールで、作成したLambda関数(マクロ)が作成されているか確認できます。


テンプレート


cfn-macro-01.yml

AWSTemplateFormatVersion: "2010-09-09"

Description:
CloudFormation Macro Create

# ------------------------------------------------------------#
# Input Parameters
# ------------------------------------------------------------#
Parameters:
CFnMacroName:
Type: String

# ------------------------------------------------------------#
# LambdaExecutionRole
# ------------------------------------------------------------#
Resources:
LambdaExecutionRole:
Type: "AWS::IAM::Role"
Properties:
RoleName: !Sub "${CFnMacroName}-LambdaExecutionRole"
Policies:
- PolicyName: !Sub "${CFnMacroName}-LambdaExecutionRole-Policy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: "arn:aws:logs:*:*:*"

- Effect: Allow
Action:
- "ssm:PutParameter"
Resource: "*"

AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: ""
Effect: Allow
Principal:
Service: "lambda.amazonaws.com"
Action: "sts:AssumeRole"

# ------------------------------------------------------------#
# Lambda Function for CloudFormation Macro
# example : generate random string(10) and register SSM
# ------------------------------------------------------------#
LambdaFunction:
Type: "AWS::Lambda::Function"
Properties:
FunctionName: !Ref CFnMacroName
Role: !GetAtt LambdaExecutionRole.Arn
Handler: index.handler

Code:
ZipFile: !Sub |
import boto3
import string
import random

ssm = boto3.client('ssm')

def handler(event, context):
key = event['params']['Key']
description = event['params']['Description']
randomstr = ''.join(random.choices(string.ascii_letters + string.digits, k=10))

ssm.put_parameter(
Name=key,
Value=randomstr,
Type='SecureString',
Description=description
)
return {'requestId': event['requestId'], 'status': 'success', 'fragment': randomstr}

Runtime: "python3.6"
MemorySize: 128
Timeout: 5

# ------------------------------------------------------------#
# CloudFormation Macro
# ------------------------------------------------------------#
CFnMacro:
Type: "AWS::CloudFormation::Macro"
Properties:
FunctionName: !Ref LambdaFunction
Name: !Ref CFnMacroName
Description: !Ref CFnMacroName



CloudFormationマクロの使い方

テンプレート内からCloudFormationマクロを呼び出す時の定義方法は、下記になります。

(この例では、RDSの MasterUserPasswordで使用しています。)

Resources:

DBInstance:
Type: "AWS::RDS::DBInstance"
Properties:

MasterUserPassword:
"Fn::Transform":
- Name: CFnMacroName #呼び出したいCloudFormationマクロの名前
Parameters:
Key: MasterUserPassword #各引数
Description: "MasterUserPassword for RDS" #各引数

DBInstanceIdentifier: !Ref DBInstanceIdentifier
Engine: MySQL
EngineVersion: 5.7
DBInstanceClass: !Ref DBInstanceClass
AllocatedStorage: 100
StorageType: gp2
DBName: !Ref DBName

## 以下 省略