CloudFormationのResource Importと変更検知・反映で覚えておきたいTips3つ

# 概要
本記事はCloudFormationのResource Import、および変更検知・反映について覚えておきたいと思った点についてまとめたものです。

# 背景と目的
先日CloudFormationのResource Importを使う機会があったのですが、いくつか興味本位で気になっていて試してみたいことがありました。

また、その際にCloudFormationの変更検知・反映について曖昧になっている部分があり、どうなるんだっけと思いつつも確認できていなかったことがあるため、その復習も兼ねて検証を行い結果をまとめます。

# 前提
Resource Importは既存もしくは新規スタックにWebコンソールやCLIで作成したAWSリソースを取り込むことができる、ClouｄFormationの機能の１つです。

どのように使うのかという詳しい説明は本記事では割愛します。
クラスメソッドさんの記事で詳しく書かれているので、こちらが参考になるかと思います。

[【アップデート】ついに来た！CloudFormationで手動で作成したリソースをStackにインポート可能になりました](https://dev.classmethod.jp/articles/cloudformation-import-existing-resources/)

# 検証
ここからは以下の簡単なテンプレートを使って試していきます。

````yaml
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  VPCCIDR:
    Type: 'String'
    Default: '10.0.0.0/16'

Resources:
  EC2VPCHoge:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: !Ref VPCCIDR
      EnableDnsSupport: true
      EnableDnsHostnames: true
      InstanceTenancy: 'default'
      Tags:
        - Key: 'Name'
          Value: 'hoge-vpc'
```

# 実験
## Q1.インポートする時にリソースの変更はできないが、パラメータの値は変更できるのか
※インポートを行う場合、テンプレート上でインポート対象でないリソースの定義に差分があるとインポートできません。

VPC CIDRのパラメータの値を10.1.0.0/16に変更して試してみます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413013/daf58a9b-b90f-041c-14e4-924f45002c47.png" width="600">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413013/0c4207ae-dc19-6ced-6387-f4a432340199.png" width="600">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413013/18118ed0-2e4c-106b-a0f4-fa89d7b95dcd.png" width="600">


この後正常にインポートが完了し、VPCのCIDRが変わっていないかどうか確認すべく見てみると
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413013/4cd45ee2-a568-fb1c-c58d-2b12cc264a9e.png" width="600">
変更されていませんでした。

テンプレート上の定義と実際の定義が同じでかどうかはチェックされておらず、変更の反映は行われないのだと改めて確認することができました。

## Q2：DeletionPolicy属性の記述がなくてもインポートできるのか

DeletionPolicy属性の指定がない場合は以下のようなエラーになり、インポートできませんでした...
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413013/b8e3c181-1de7-4e31-164b-cbc1e3af3791.png" width="600">

DeletionPolicy属性はスタックを削除する際AWSリソースの扱いを指定するもので、記述がなくてもインポートできるのでは？と思っていたのですが、確かに[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resource-import-existing-stack.html)には
> インポートする各リソースは、テンプレートに DeletionPolicy 属性がある必要があります。

と書かれていました。

以下のAWSのブログを見ると、オペレーションの巻き戻しを安全で簡単に行えるようにするために必要なようです。

[新機能 – CloudFormation スタックへの既存リソースのインポート](https://aws.amazon.com/jp/blogs/news/new-import-existing-resources-into-a-cloudformation-stack/)

※完全に興味本位で行ったことですが、`DELETE`でも問題なくインポートはできました。

## Q3：実際の設定値とテンプレート定義が一致していない状態でスタックを更新すると変更は反映されるのか

これはResouce ImportというよりCloudFormationの変更検知・反映に関する部分ですが、曖昧になっていたので試して確認したかった、というものです。

Q2の実験により、実際のVPCのCIDRは`10.0.0.0/16`でテンプレート上の定義は`10.1.0.0/16`と一致していない状態です。

[CloudFormationのドキュメント](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html)を確認すると`CidrBlock`プロパティは`Update requires: Replacement`なので、この状態でスタックの更新を試して置換されるのかを確認しました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413013/38d467e5-82ed-ea75-36ef-e34cc028fd57.png" width="600">

変更セットを作成するタイミングで上記のエラーになり、変更セット自体を作成できませんでした。

それならばと思い、`EnableDnsHostnames:true`を`false`に変更して同様に更新を試しました。

変更セットとして認識されることを確認し、
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413013/38ff6e50-66dd-9a0b-3d9f-4f2653632f1c.png" width="800">

反映後にVPCIDを確認してみると、変わっていないことが確認できました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413013/68e719f1-9a1e-58a4-1e0b-73de18dcd70f.png" width="800">

CloudFormationは実際の定義はチェックせず、あくまでテンプレートの定義において変更の有無をチェックしているようです。

# まとめ
- DeletionPolicyは必須
- インポートする時にパラメータの値は変更できるが反映はされない
- 実際の設定値とテンプレート定義が一致していない状態でスタックを更新しても変更は反映されない