rainとMakefileを使って効率的にCloudFormationを管理する
はじめに
AWSのCloudFormationを効率的に扱うためのユーティリティとしてrain
コマンドがあります。本記事では、rain.mk
というMakefileでrainを使用し、中小規模のCloudFormationテンプレート管理をシンプルにする方法を紹介します。
rainとは?
rainは、CloudFormationテンプレートを扱うための便利なCLIツールです。フォーマット整形、リソースの差分確認、テンプレートのデプロイや削除など、多機能なCLIツールとして、AWSリソース管理を効率化します。詳しくは、下記のURLを参照してください。
私の環境は?
- Lubuntu24.04
- rain v1.21.0
- aws-cli v2.22.33
- cfn-lint v1.22.4
- envsubst v0.23
- GNU Make v4.3
rain.mkのコード解説
rainコマンドの使用方法を共通化して再利用できるように、rain.mk
を用意します。
makefileの内容は以下のとおり。
rain.mkのコード全体
############################################################################
#
# rain command utilities
#
# [required commands]
# - rain
# - aws-cli
# - cfn-lint
# - envsubst
# - make
#
# [parameters]
# - required
# - RAIN_STACK_NAME: name of the stack
# - RAIN_CFN_YML : name of the CFN template file
# - RAIN_PROFILE : aws profile
# - options
# - RAIN_CONFIG : name of the rain config file (cfn parameters, tags)
# - RAINOPT : rain additional options (except for pkg)
# - RAINPKGOPT : rain pkg options
#
############################################################################
# variables ---------------------------------------------------------------
RAIN_CFN_DIR := $(shell basename $(shell dirname $(PWD)))/$(shell basename $(PWD))
RAIN_CONFIG_DEFAULT_TAG := ../rain_conf_default_tags.yml
RAIN_TEMPLATE_TMP := $(RAIN_STACK_NAME).tmpl.raintmp.yml
RAIN_CONFIG_TMP := $(RAIN_STACK_NAME).conf.raintmp.yml
# defines -----------------------------------------------------------------
RAIN_I_COL1 := \033[32m
RAIN_I_ICON := *🌂* rain.mk *
RAIN_I_COL2 := \033[0m
define rain_msg_info
@echo -e "$(RAIN_I_COL1)$(RAIN_I_ICON) $1$(RAIN_I_COL2)"
endef
RAIN_E_COL1 := \033[31m
RAIN_E_ICON := *☔* rain.mk *
RAIN_E_COL2 := \033[0m
define rain_msg_err
echo -e "$(RAIN_E_COL1)$(RAIN_E_ICON) Error: $1$(RAIN_E_COL2)"
endef
define rain_create_tmp
@if [ -e "$(RAIN_TEMPLATE_TMP)" ]; then \
$(call rain_msg_err,"$(RAIN_TEMPLATE_TMP) already exists. run 'make rain_clean'."); \
exit 1; \
fi
@if [ -e "$(RAIN_CONFIG_TMP)" ]; then \
$(call rain_msg_err,"$(RAIN_CONFIG_TMP) already exists. run 'make rain_clean'."); \
exit 1; \
fi
$(call rain_msg_info,"run rain pkg.")
@if ! rain pkg $(RAIN_CFN_YML) --no-analytics -o $(RAIN_TEMPLATE_TMP) $(RAINPKGOPT); then \
$(call rain_msg_err,"rain pkg failed."); \
exit 1; \
fi
$(call rain_msg_info,"run cfn-lint.")
@if ! cfn-lint $(RAIN_TEMPLATE_TMP); then \
$(call rain_msg_err,"cfn-lint failed."); \
exit 1; \
fi
@if ! envsubst < $(RAIN_CONFIG_DEFAULT_TAG) > $(RAIN_CONFIG_TMP); then \
$(call rain_msg_err,"envsubst failed. $(RAIN_CONFIG_DEFAULT_TAG)"); \
exit 1; \
fi
@if [ ! -z "$(RAIN_CONFIG)" ]; then \
if ! envsubst < "$(RAIN_CONFIG)" >> $(RAIN_CONFIG_TMP); then \
$(call rain_msg_err,"envsubst failed. $(RAIN_CONFIG)"); \
exit 1; \
fi \
fi
$(call rain_msg_info,"print rain config.")
@cat $(RAIN_CONFIG_TMP)
endef
# targets -----------------------------------------------------------------
all:
$(eval SHELL := /bin/bash)
$(call rain_msg_info,"Available targets:")
$(call rain_msg_info," rain_lint - Lint the CloudFormation template")
$(call rain_msg_info," rain_forecast - Show the forecast of stack changes")
$(call rain_msg_info," rain_deploy - Deploy the stack")
$(call rain_msg_info," rain_rm - Remove the stack")
$(call rain_msg_info," rain_diff - Compare local and deployed stack")
$(call rain_msg_info," rain_ls - Show stack information")
$(call rain_msg_info," rain_logs - Show stack logs")
$(call rain_msg_info," rain_tree - Show stack resource tree")
$(call rain_msg_info," rain_info - Display the AWS account and region.")
$(call rain_msg_info," rain_clean - Clean temporary files")
rain_lint:
$(eval SHELL := /bin/bash)
$(call rain_msg_info,"Lint the CloudFormation template.")
$(call rain_msg_info,"print stack name.")
@echo "$(RAIN_STACK_NAME)"
$(call rain_create_tmp)
$(call rain_msg_info,"run rain.")
-rain fmt $(RAIN_TEMPLATE_TMP) $(RAINOPT)
@make rain_clean
rain_forecast:
$(eval SHELL := /bin/bash)
$(call rain_msg_info,"Show the forecast of stack changes.")
$(call rain_msg_info,"print stack name.")
@echo "$(RAIN_STACK_NAME)"
$(call rain_create_tmp)
$(call rain_msg_info,"run rain.")
-rain forecast $(RAIN_TEMPLATE_TMP) $(RAIN_STACK_NAME) $(RAINOPT) \
--experimental \
--profile $(RAIN_PROFILE) \
--config $(RAIN_CONFIG_TMP)
@make rain_clean
rain_deploy:
$(eval SHELL := /bin/bash)
$(call rain_msg_info,"Deploy the stack.")
$(call rain_msg_info,"print stack name.")
@echo "$(RAIN_STACK_NAME)"
$(call rain_create_tmp)
$(call rain_msg_info,"run rain.")
-rain deploy $(RAIN_TEMPLATE_TMP) $(RAIN_STACK_NAME) $(RAINOPT) \
--profile $(RAIN_PROFILE) \
--config $(RAIN_CONFIG_TMP)
@make rain_clean
rain_rm:
$(eval SHELL := /bin/bash)
$(call rain_msg_info,"Remove the stack.")
$(call rain_msg_info,"print stack name.")
@echo "$(RAIN_STACK_NAME)"
$(call rain_msg_info,"run rain.")
rain rm $(RAIN_STACK_NAME) $(RAINOPT) \
--profile $(RAIN_PROFILE)
rain_diff:
$(eval SHELL := /bin/bash)
$(call rain_msg_info,"Compare local and deployed stack.")
$(call rain_msg_info,"print stack name.")
@echo "$(RAIN_STACK_NAME)"
$(call rain_create_tmp)
$(call rain_msg_info,"run rain.")
-rain diff <(rain cat $(RAIN_STACK_NAME) --profile $(RAIN_PROFILE) $(RAINOPT)) \
$(RAIN_TEMPLATE_TMP)
@make rain_clean
rain_ls:
$(eval SHELL := /bin/bash)
$(call rain_msg_info,"Show stack information.")
$(call rain_msg_info,"print stack name.")
@echo "$(RAIN_STACK_NAME)"
$(call rain_msg_info,"run rain.")
rain ls $(RAIN_STACK_NAME) $(RAINOPT) \
--profile $(RAIN_PROFILE)
rain_logs:
$(eval SHELL := /bin/bash)
$(call rain_msg_info,"Show stack logs.")
$(call rain_msg_info,"print stack name.")
@echo "$(RAIN_STACK_NAME)"
$(call rain_msg_info,"run rain.")
rain logs $(RAIN_STACK_NAME) $(RAINOPT) \
--all \
--profile $(RAIN_PROFILE)
rain_tree:
$(eval SHELL := /bin/bash)
$(call rain_msg_info,"Show stack resource tree.")
$(call rain_msg_info,"print stack name.")
@echo "$(RAIN_STACK_NAME)"
$(call rain_create_tmp)
$(call rain_msg_info,"run rain.")
-rain tree $(RAIN_TEMPLATE_TMP) $(RAINOPT)
@make rain_clean
rain_info:
$(eval SHELL := /bin/bash)
$(call rain_msg_info,"Display the AWS account and region.")
$(call rain_msg_info,"print stack name.")
@echo "$(RAIN_STACK_NAME)"
$(call rain_msg_info,"run rain.")
rain info $(RAINOPT) \
--profile $(RAIN_PROFILE)
rain_clean:
@rm -f *.raintmp.yml > /dev/null 2>&1
############################################################################
.PHONY: all rain_lint rain_forecast rain_deploy rain_rm rain_diff rain_ls rain_logs rain_tree rain_info rain_clean
必要なコマンドとパラメータ
必須コマンド
rain.mk
には下記のコマンドが必要です。インストールしておいてください。
- rain: CloudFormationを操作するツール。
- aws-cli: AWSのサービスをコマンドラインから操作できるツール。
- cfn-lint: CloudFormationテンプレートの検証ツール。
- envsubst: 環境変数の置換に使用。
- make: Makefileの実行に使用。
必須パラメータ
rain.mk
を使用する場合、下記の環境変数は、必ず設定してください。
- RAIN_STACK_NAME: デプロイするスタック名。
- RAIN_CFN_YML: CloudFormationテンプレートファイル名。
- RAIN_PROFILE: 使用するAWSプロファイル。
オプションパラメータ
rain.mk
を使用する場合、下記の環境変数は、必要な場合に設定してください。
- RAIN_CONFIG: rainの設定ファイル(CloudFormationパラメータやタグを含む)。
- RAINOPT: rainコマンドに渡す追加オプション。(pkg除く)
- RAINPKGOPT: rain pkgに渡す追加オプション。
主なターゲットの説明
rain_lint
CloudFormationテンプレートを検証し、フォーマットしたテンプレートと一緒にパラメータとタグも表示します。
-
CloudFormationテンプレートの再生成:
rain pkg
を使用。!RAIN::Include
などのrain特有の機能を処理してCloudFormationテンプレートを生成。 -
テンプレートの検証:
cfn-lint
を使用。 -
rainのフォーマットを適用して表示:
rain fmt
を使用。
make rain_lint
rain_forecast
変更がAWSリソースに与える影響を事前に予測・可視化します。
make rain_forecast
rain_deploy
CloudFormationテンプレートを適用してスタックを作成または更新します。
make rain_deploy
rain_rm
スタックを削除します。
make rain_rm
rain_diff
ローカルテンプレートと現在のデプロイ済みスタックの差分を確認します。
make rain_diff
rain.mk
の使用方法
rain.mk
は、単独では使用しません。Makefileにincludeして使用します。
ディレクトリ構造例
以下は、ディレクトリ構造の例です。プロジェクト単位またはサービス単位などに分けてディレクトリを作成し、複数のスタックを管理する想定です。
├── projectA/
│ ├── Makefile
│ ├── cfn_iam_role.yml
│ ├── cfn_sg.yml
│ └── rain_sg.yml
├── rain.mk
├── rain_conf_default_tags.yml
└── rain_inc_map_vpc.yml
Makefileの内容解説
Makefileではrain.mk
をincludeして簡潔にCloudFormationを操作します。exportは必須です。
Makefileのコード全体
#
# CloudFormation sample
#
include ../rain.mk
export
# parameters of rain.mk (required)
RAIN_PROFILE := sandbox
# parameters of rain.mk (optional)
#RAINOPT :=
# parameters of RAIN_CONFIG (sample)
# SECRET := $(shell aws secretsmanager get-secret-value --secret-id password --query SecretString --output text --profile $(RAIN_PROFILE))
# target of rain.mk
RAINCMD := rain_lint
# stack of Security Group
sg:
$(eval RAIN_STACK_NAME := sample-sg)
$(eval RAIN_CFN_YML := cfn_sg.yml)
$(eval RAIN_CONFIG := rain_sg.yml)
$(eval SG_NAME := sample)
make $(RAINCMD)
# stack of IAM Role
role:
$(eval RAIN_STACK_NAME := sample-role)
$(eval RAIN_CFN_YML := cfn_iam_role.yml)
make $(RAINCMD)
# .PHONY targets are used to declare targets that are not associated with real files.
.PHONY: sg role
ターゲットの定義
sg
およびrole
は、異なるスタックを操作するためのターゲットです。
-
sg:
- スタック名:
sample-sg
- テンプレート:
cfn_sg.yml
- 設定ファイル:
rain_sg.yml
- スタック名:
-
role:
- スタック名:
sample-role
- テンプレート:
cfn_iam_role.yml
- スタック名:
RAINCMDの設定
RAINCMD
に目的の操作を設定します。デフォルトは、rain_lint
とし、make実行時にRAINCMD
を変更します。これにより、RAINCMDを打ち間違うと、rain_lint
が実行されます。
RAINCMD := rain_lint
目的の操作を切り替えたいときは、makeコマンド実行時に以下のようにします。
make sg RAINCMD=rain_deploy
RAIN_PROFILEの設定
RAIN_PROFILE
にはCloudFormation対象のAWS環境を設定します。
設定値は、awscliに定義したprofileです。MakefileにはデフォルトのAWS環境(開発環境など)を記述します。
RAIN_PROFILE := sandbox
処理対象の環境を切り替えるときは、makeコマンド実行時に以下のようにします。
make sg RAINCMD=rain_deploy RAIN_PROFILE=production
localstackでCloudFormationのテストをしたい場合は、以下のように実行します。
下記例の192.168.10.10は、PCのIPアドレスです。localhostはNGです。
make sg RAINCMD=rain_deploy RAIN_PROFILE=localstack AWS_ENDPOINT_URL=http://192.168.10.10:4566
rain_config_default_tags.yml
全スタックに必須のタグを定義します。
Tags:
author: sre
cfn_location: ${RAIN_CFN_DIR}/${RAIN_CFN_YML}
orchestrator: rain.mk
rain_sg.yml
cfn_sg.yml
に入力するパラメータを定義します。この設定により、実行時にパラメータを手動で入力する必要を無くし、誰でも簡単に実行できるようにしています。
Parameters:
SgName: ${SG_NAME}
固有のタグ(ex. コストタグ)を設定したい場合は以下のようにします。
CostGroup: projectA
Parameters:
RoleName: ${SG_NAME}
固有のタグ(ex. コストタグ)だけ設定したい場合は以下のようにします。
CostGroup: projectA
環境変数は、envsubst
コマンドによって置換されるため、以下のようなメリットがあります。
-
一貫性のある設定管理
環境変数を使用することで、異なる環境(開発、テスト、本番など)に対して一貫した設定を適用できます。これにより、環境ごとに異なる設定ファイルを用意する手間が省けます。 -
簡単なメンテナンス
環境変数を変更するだけで設定を更新できるため、設定ファイルのメンテナンスが容易になります。特に、複数のプロジェクトやスタックを管理する場合に便利です。 -
セキュリティの向上
環境変数を使用することで、機密情報(例: APIキーやパスワード)をコードベースに直接記述することを避けられます。これにより、セキュリティリスクを低減できます。
例として、Makefileには環境変数(SECRET)を定義するコメントがあります。 -
柔軟性の向上
環境変数を使うことで、同じテンプレートを異なる用途や条件で再利用しやすくなります。これにより、コードの再利用性が向上します。
rain_inc_map_vpc.yml
以下は、他のスタックと共有するMappingsの定義です。rainの機能を利用してテンプレートにインクルードして使用します。
私は、CFNテンプレートのMappingsをよく使うのですが、複数のテンプレートで共有したいMappingsがある場合に、この方法を利用しています。
AccountToVpcParams:
"012345678901":
VpcId: vpc-1234
VpcCidr: 10.0.0.0/16
PrivateSubnetId1: subnet-2345
PrivateSubnetId2: subnet-6789
cfn_sg.yml
CloudFormationのテンプレートを定義します。!RAIN::Include
のようなrainのプロパティも使用できます。
cfn_sg.ymlのコード全体
AWSTemplateFormatVersion: "2010-09-09"
Description: sg
Parameters:
SgName:
Type: String
Rain:
Constants:
Test1: sample
Test2: !Sub ${Rain::Test1}-comment
Mappings:
!Rain::Include ../rain_inc_map_vpc.yml
Resources:
SecurityGroup1:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !FindInMap [ AccountToVpcParams, !Ref "AWS::AccountId", "VpcId" ]
GroupName: !Sub "${SgName}-1"
GroupDescription: !Rain::Constant Test1
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: !FindInMap [ AccountToVpcParams, !Ref "AWS::AccountId", "VpcCidr" ]
SecurityGroup2:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !FindInMap [ AccountToVpcParams, !Ref "AWS::AccountId", "VpcId" ]
GroupName: !Sub "${SgName}-2"
GroupDescription: !Rain::Constant Test2
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: !FindInMap [ AccountToVpcParams, !Ref "AWS::AccountId", "VpcCidr" ]
CloudFormation操作の例
以下に、実際にMakefile
を使ってCloudFormationスタックを操作する例を記します。
テンプレートの検証
sg
のCFNテンプレートを検証するには以下のコマンドを実行します。RAINCMDのデフォルト値をrain_lintにしているので、RAINCMDは省略できます。
なお、!Rain::Include
などは、処理された状態でcfn-lintが実行されます。
make sg
lintエラーの場合は、以下のように表示されます。カレントにワークファイル(下記の例だとsample-sg.tmpl.raintmp.yml
)があるので、それでエラー内容を確認できます。
このワークファイルは、rain pkg
を実行して、!Rain::Include
のようなrainのプロパティを処理したものです。スタック名.tmpl.raintmp.yml
の命名規則でワークファイルが作成されます。
再度、make sg
する前に、make rain_clean
を実行してこのワークファイルを削除してください。
実行例(lintエラー)
$ make sg
make rain_lint
*🌂* rain.mk * Lint the CloudFormation template.
*🌂* rain.mk * print stack name.
sample-sg
*🌂* rain.mk * run rain pkg.
*🌂* rain.mk * run cfn-lint.
E1001 'Resources' is a required property
sample-sg.tmpl.raintmp.yml:1:1
E1001 Additional properties are not allowed ('Resources:' was unexpected. Did you mean 'Resources'?)
sample-sg.tmpl.raintmp.yml:19:1
*☔* rain.mk * Error: cfn-lint failed.
make[1]: *** [../rain.mk:101: rain_lint] エラー 1
make: *** [Makefile:23: sg] エラー 2
lintに成功した場合は、以下のようにフォーマットしたテンプレートとタグ、パラメータを表示します。
表示されるテンプレートは、rain pkg
で生成したものです。ここで表示されたテンプレートを使用してスタックが作成(または更新)されます。
実行例(lint success)
$ make sg
make rain_lint
*🌂* rain.mk * Lint the CloudFormation template.
*🌂* rain.mk * print stack name.
sample-sg
*🌂* rain.mk * run rain pkg.
*🌂* rain.mk * run cfn-lint.
*🌂* rain.mk * print rain config.
Tags:
author: sre
cfn_location: rain_mk/projectA/cfn_sg.yml
orchestrator: rain.mk
Parameters:
SgName: sample
*🌂* rain.mk * run rain.
rain fmt sample-sg.tmpl.raintmp.yml
AWSTemplateFormatVersion: "2010-09-09"
Description: sg
Parameters:
SgName:
Type: String
Mappings:
AccountToVpcParams:
"012345678901":
VpcId: vpc-1234
VpcCidr: 10.0.0.0/16
PrivateSubnetId1: subnet-2345
PrivateSubnetId2: subnet-6789
Resources:
SecurityGroup1:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !FindInMap
- AccountToVpcParams
- !Ref AWS::AccountId
- VpcId
GroupName: !Sub ${SgName}-1
GroupDescription: sample
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: !FindInMap
- AccountToVpcParams
- !Ref AWS::AccountId
- VpcCidr
SecurityGroup2:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !FindInMap
- AccountToVpcParams
- !Ref AWS::AccountId
- VpcId
GroupName: !Sub ${SgName}-2
GroupDescription: sample-comment
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: !FindInMap
- AccountToVpcParams
- !Ref AWS::AccountId
- VpcCidr
rain pkg
には、--no-analytics
をつけています。このオプションをつけないと、以下のようなMETADATAが追加されてdeploy時にエラーになります。(昔は、なかったのに。。。)
Metadata:
AWSToolsMetrics:
Rain: '{"Version":"v1.21.0","Experimental":false,"HasModules":false,"HasRainSection":false}'
スタックのデプロイ
sg
のスタックをデプロイするには以下のコマンドを実行します。
make sg RAINCMD=rain_deploy
これにより、ChangeSetが作成され表示されます。内容を確認して問題なければ、"Y"を入力してデプロイを続行します。
実行例(ChangeSet confirm)
$ make sg RAINCMD=rain_deploy
make rain_deploy
*🌂* rain.mk * Deploy the stack.
*🌂* rain.mk * print stack name.
sample-sg
*🌂* rain.mk * run rain pkg.
*🌂* rain.mk * run cfn-lint.
*🌂* rain.mk * print rain config.
Tags:
author: sre
cfn_location: rain_mk/projectA/cfn_sg.yml
orchestrator: rain.mk
Parameters:
SgName: sample
*🌂* rain.mk * run rain.
rain deploy sample-sg.tmpl.raintmp.yml sample-sg \
--profile sandbox \
--config sample-sg.conf.raintmp.yml
CloudFormation will make the following changes:
Stack sample-sg:
+ AWS::EC2::SecurityGroup SecurityGroup1
+ AWS::EC2::SecurityGroup SecurityGroup2
Do you wish to continue? (Y/n)
続行した場合は、sample-sg
スタックが作成されます。
実行例(deploy success)
$ make sg RAINCMD=rain_deploy
make rain_deploy
*🌂* rain.mk * Deploy the stack.
*🌂* rain.mk * print stack name.
sample-sg
*🌂* rain.mk * run rain pkg.
*🌂* rain.mk * run cfn-lint.
*🌂* rain.mk * print rain config.
Tags:
author: sre
cfn_location: rain_mk/projectA/cfn_sg.yml
orchestrator: rain.mk
Parameters:
SgName: sample
*🌂* rain.mk * run rain.
rain deploy sample-sg.tmpl.raintmp.yml sample-sg \
--profile sandbox \
--config sample-sg.conf.raintmp.yml
CloudFormation will make the following changes:
Stack sample-sg:
+ AWS::EC2::SecurityGroup SecurityGroup1
+ AWS::EC2::SecurityGroup SecurityGroup2
Do you wish to continue? (Y/n) Y
Deploying template 'sample-sg.tmpl.raintmp.yml' as stack 'sample-sg' in us-east-1.
Stack sample-sg: CREATE_COMPLETE
Successfully deployed sample-sg
差分確認
sg
のテンプレートを修正後、デプロイ前に変更点を確認するには以下を実行します。
make sg RAINCMD=rain_diff
これにより、ローカルのテンプレートとデプロイ済みのスタックの内容が比較され、違いが表示されます。
実行例(compare)
$ make sg RAINCMD=rain_diff
make rain_diff
*🌂* rain.mk * Compare local and deployed stack.
*🌂* rain.mk * print stack name.
sample-sg
*🌂* rain.mk * run rain pkg.
*🌂* rain.mk * run cfn-lint.
*🌂* rain.mk * print rain config.
Tags:
author: sre
cfn_location: rain_mk/projectA/cfn_sg.yml
orchestrator: rain.mk
Parameters:
SgName: sample
*🌂* rain.mk * run rain.
rain diff <(rain cat sample-sg --profile sandbox ) \
sample-sg.tmpl.raintmp.yml
(|) Resources:
(|) SecurityGroup1:
(|) Properties:
(>) GroupDescription: sample2
(|) SecurityGroup2:
(|) Properties:
(>) GroupDescription: sample2-comment
スタックの削除
sg
が不要になり、スタックを削除する場合は以下を実行します。
make sg RAINCMD=rain_rm
これにより、スタックを削除するか確認されます。問題なければ、"y"を入力して削除を続行します。
実行例(remove confirm)
$ make sg RAINCMD=rain_rm
make rain_rm
*🌂* rain.mk * Remove the stack.
*🌂* rain.mk * print stack name.
sample-sg
*🌂* rain.mk * run rain.
rain rm sample-sg \
--profile sandbox
Stack sample-sg: CREATE_COMPLETE
Are you sure you want to delete this stack? (y/N)
続行した場合は、sample-sg
スタックが削除されます。
実行例(remove success)
$ make sg RAINCMD=rain_rm
make rain_rm
*🌂* rain.mk * Remove the stack.
*🌂* rain.mk * print stack name.
sample-sg
*🌂* rain.mk * run rain.
rain rm sample-sg \
--profile sandbox
Stack sample-sg: CREATE_COMPLETE
Are you sure you want to delete this stack? (y/N) y
Successfully deleted stack 'sample-sg'
まとめ
rain.mk
とMakefileを使用することで、CloudFormationスタックの操作を効率化できます。テンプレートの検証からスタックのデプロイ、削除、差分確認まで、誰もが簡潔に行えるのがポイントです。
Discussion