SparkleFormationはAWS CloudFormationのテンプレートをrubyの形式で記述できる。
Stack Policiesもテンプレート中に記述できるが癖があったのでメモしておく。
以下の環境で確認。
- sfn (3.0.18)
- sparkle_formation (3.0.10)
SparkleFormationでのStack Policy適用方法
テンプレート中にポリシーを記述
SparkleFormation.new(:test, provider: :aws) do
AWSTemplateFormatVersion '2010-09-09'
dynamic!(:ec2_vpc, :test) do
properties do
cidr_block "10.0.0.0/16"
tags!("Name" => "vpc-test")
end
policy.deny "Replace"
end
end
上記のpolicy.deny "Replace"のようにテンプレート中にStack Policyを記述する。
詳細はSparkleFormation: Stack Policies参照
Configファイルにcallback設定追加
Configuration.new do
callbacks do
default ['stack_policy']
end
end
sfn initで作成された.sfnファイルに上記の内容を記述した。
これでsfn createやupdateした時にポリシーが適用されたりするようになる。
(これをしておかないと不要な要素があるということでsfn validateなどで怒られる。)
詳細はSparkleFormation: Callbacks参照
Stack Policy適用時のコマンド実行について
上記のcallbackを設定すると以下のように一部のsfnコマンド(print、validate、graphなど)でエラーになる。
$ bundle exec sfn print --file test
[Sfn]: Callback template stack_policy: starting
ERROR: NoMethodError: undefined method `to_sym' for nil:NilClass
Did you mean? to_s
コードを斜め読みしてみるとどうやらスタック名が不要なコマンドでもスタック名必須になっている感じ。
なので以下のようにダミーのスタック名(hoge)を設定するととりあえずエラーなしで実行可能。
$ bundle exec sfn print hoge --file test
リソースへのStack Policyの一括適用方法
CloudFormationでは*を使って一括ですべてのリソースに適用するようなPolicyを記述できる。
しかし、SparkleFormationでは各リソース中にしかpolicy要素を記述できない。
このため、以下のようなコードにすることで各リソースで一括でUpdate:Replaceを禁止できる。
SparkleFormation.new(:test, provider: :aws) do
# ...(略)
resources do
keys!.each do |resource|
set!(resource) do
policy.deny "Replace" # すべてのリソースに対してpolicy.denyの要素を追加
end
end
end
end
適用方法の調査メモ
SparkleFormationの公式文書を探したが自分が定義したリソース一覧を取ってくるようなmethodが見当たらなかった。
SparkleFormation: SparkleFormation DSLのdata!はやりたいことに近い気がしたが微妙に違った。
しょうがないのでsperkle_formation.rbのinitializeから追っていくと以下の2つあたりで利用出来る関数が定義されていることがわかった。
AttributeStructの方でkeys!メソッドが定義されていたので利用したらいけた。