sorta kinda...

主にAWS関連ですが、これに限らずいろいろ勉強したことや思ったことを書いていきます。

1 つのテンプレートだけで DeletionPolicy を切り替えたい(希望)

気温が下がって寒くなって、若干調子が悪い気がします。那須です。

さて、CloudFormation を使って AWS リソースを作ると便利ですが、「あ、間違えてた!」ってなるとまたスタックを削除して再作成する流れになりますよね。 開発や検証環境だとあまり意識しないですが本番環境ではそのリソースを削除されては困るので、DeletionPolicy をテンプレートの中に書いてスタックを間違えて消したとしても環境自体には影響がないようにしている人は多いと思います。

でも開発、検証、本番のそれぞれの環境で CloudFormation で作成するリソースは同じです。 開発や検証では用が済んだらリソースを削除します。 作成するリソースはすべての環境で同じなので、テンプレートは開発&検証と本番とで分けたくないですよね? というわけで、1 つのテンプレートで DeletionPolicy が切り替えられるのかどうか、調べつつやってみました。

DeletionPolicy がどういうものかは、こちらのドキュメントに書いてあります。

docs.aws.amazon.com

 

まずはテンプレートで DeletionPolicy 選択できるように

VPC を作成するテンプレートに DeletionPolicy を Ref 関数で指定してみます。

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Parameters": {
        "DeletionPolicyParam": {
            "Type": "String",
            "Default": "Delete",
            "AllowedValues": [
                "Delete",
                "Retain"
            ]
        }
    },
    "Resources": {
        "Vpc": {
            "Type": "AWS::EC2::VPC",
            "Properties": {
                "CidrBlock": "192.168.255.0/24"
            },
            "DeletionPolicy": {
                "Ref": "DeletionPolicyParam"
            }
        }
    }
}

ではスタックを作成してみましょう。

f:id:nasrinjp1:20181023084554p:plain

Template format error: Every DeletionPolicy member must be a string.

なにやらつらいエラーメッセージが出てきました… もしかして DeletionPolicy には関数が使えないのか。

 

どうにもならないらしい 2018.10.23現在

AWS Forum に私と同じ悩みを持った人たちが投稿していました。 どうやら今のところは String で指定しないとダメらしいです。
https://forums.aws.amazon.com/message.jspa?messageID=560586

 

で、結局どうにかなるの?

AWS Forum にもコメントがありましたが、1 つのテンプレートでどうにかなるのはなるのですが、スマートなやり方ではないので現時点ではテンプレートを分割した方がいいですね。 やり方としては、Conditions セクションで本番かそうでないかを判別できるようにして、本番ならこのリソースを作成、それ以外ならもうひとつのリソースを作成、という形です。 先ほどのVPCを作成するテンプレートの場合だと、こんな形になります。

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Parameters": {
        "DeletionPolicyParam": {
            "Type": "String",
            "Default": "Delete",
            "AllowedValues": [
                "Delete",
                "Retain"
            ]
        }
    },
    "Conditions": {
        "ForProduction": {
            "Fn::Equals": [
                {
                    "Ref": "DeletionPolicyParam"
                },
                "Retain"
            ]
        },
        "ForDevTest": {
            "Fn::Equals": [
                {
                    "Ref": "DeletionPolicyParam"
                },
                "Delete"
            ]
        }
    },
    "Resources": {
        "VpcProd": {
            "Type": "AWS::EC2::VPC",
            "Condition": "ForProduction",
            "Properties": {
                "CidrBlock": "192.168.255.0/24"
            },
            "DeletionPolicy": "Retain"
        },
        "VpcDevTest": {
            "Type": "AWS::EC2::VPC",
            "Condition": "ForDevTest",
            "Properties": {
                "CidrBlock": "192.168.255.0/24"
            }
        }
    }
}

このテンプレートでスタックを作成すると、DeletionPolicyParam パラメータが Delete ならスタック削除とともにリソースも削除、DeletionPolicyParam がRetain ならスタック削除してもリソースはそのまま残る、という流れになります。

 

最後に

以前に CloudFormation のスタック更新や削除の制御方法についての記事を書きました。

nasrinjp1.hatenablog.com

今のところは↑の記事にもまとめたように、スタックポリシーや削除保護でリソースの削除/保持を制限するのもよさそうです。 root でログインして作業する、なんてことをしなければきっと大丈夫ですね。 さらに IAM の権限がガバガバじゃなかったらきっと大丈夫ですね。

 

一応解決しました 2018.10.24追記

nasrinjp1.hatenablog.com