手動で作成したAWSリソースをCloudFormation管理下に置く

# はじめに
IaCの有用性については様々なところで言われてはいるものの、手動で作成したリソースがすでにあると中途半端にIaCをしてもなぁ……と敬遠されがちなところがあるかと思います。
そう思って、既存のリソースをコード管理する方法がないかを調べていたところ、CloudFormationのインポート機能を使えば、既存リソースもコード管理下に置けることがわかりました。
この記事はCloudFormationのインポート機能をテストしたときの備忘録になります。

# ０. 準備
まずはAWSコンソール上で手動でリソースを作成します。
今回は、Security Groupを作成しました。
設定としてはこんな感じです。

![スクリーンショット 2021-06-17 16.10.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213467/3f9dbfa1-a2f8-cb24-59f7-9280ceacdf07.png)

# １. 作成したSecurity Groupと同じ内容のテンプレートを作成する
`test.yaml`を作成して以下を記述して保存します。

```
AWSTemplateFormatVersion: "2010-09-09"

Resources:
    SecurityGroup:
        Type: "AWS::EC2::SecurityGroup"
        Properties:
            GroupDescription: "test"
            GroupName: "test"
            VpcId: sg-hoge # 実際のVPCを記述してください。
            SecurityGroupIngress: 
              -
                CidrIp: "0.0.0.0/0"
                FromPort: 80
                IpProtocol: "tcp"
                ToPort: 80
        UpdateReplacePolicy: Retain
        DeletionPolicy: Retain
```
インポート機能を使用する際には、必ず`DeletionPolicy`を「Retain」にしないといけないので注意してください。
また、`UpdateReplacePolicy`も未設定の場合は、CloudFormationの設定に上書きされる可能性があるので、安全のため「Retain」を設定することをオススメします。

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-attribute-updatereplacepolicy.html


## Former2のススメ
なお、作成したテンプレートと実際のリソースが同じかどうかは、[Former2](https://former2.com/)を使用して確認するのがいいです。
Former2を用いると、AWS上に実際に展開されているリソースをCloudFormationやTerraformなどのインフラコードに変換してくれます。

# ２. Securiy Groupをインポート
### `test.yaml`を用いて、CloudFormationにインポートする 
CloudFormationコンソールから「既存のリソースを使用(リソースをインポート)」をクリック
![スクリーンショット 2021-06-17 16.40.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213467/47d90c30-044b-fd8d-cf38-2b999f295ad3.png)

「次へ」ボタンをクリック
![スクリーンショット 2021-06-17 16.28.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213467/c0ec1456-b6e8-7722-854a-cf02b625cc25.png)

「テンプレートファイルのアップロード」を選択し、`test.yaml`をアップロードする。
終わったら「次へ」ボタンをクリック
![スクリーンショット 2021-06-17 16.30.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213467/a7e64b71-6dde-8f08-9dfc-b48a3b814bae.png)

「識別子の値」に今回作成したSecurityGroupのIDを入力する
完了したら「次へ」ボタンをクリック
![スクリーンショット 2021-06-17 16.35.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213467/293eb33b-b480-2ba6-afd1-e0040c1b11b8.png)


スタックの名前を入力。
「次へ」ボタンをクリック。
![スクリーンショット 2021-06-17 16.37.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213467/59de0463-f2dd-938a-f052-b639bf8eb5ac.png)

一番下の「変更」で、アクションが「Import」になっていることを確認してください。
問題がなければ「リソースをインポート」をクリックします。
![スクリーンショット 2021-06-17 16.47.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213467/a799711d-3ede-a611-659f-06b4624687b4.png)

実行したスタックを見て、ステータスが「IMPORT_COMPLETE」になれば完了です。
![スクリーンショット 2021-06-17 17.07.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213467/b3304be0-a724-4925-bbdb-fa0cfb7fe125.png)

# ３. インポートしたSecurity GroupをCloudFormationを用いて更新する。

作成した`test.yaml`を以下のように修正します。

```
AWSTemplateFormatVersion: "2010-09-09"

Resources:
    SecurityGroup:
        Type: "AWS::EC2::SecurityGroup"
        Properties:
            GroupDescription: "test"
            GroupName: "test"
            VpcId: sg-hoge # 実際のVPCを記述してください。
            SecurityGroupIngress: 
              -
                CidrIp: "0.0.0.0/0"
                FromPort: 80
                IpProtocol: "tcp"
                ToPort: 80
              -
                CidrIp: "0.0.0.0/0"
                FromPort: 443
                IpProtocol: "tcp"
                ToPort: 443
        UpdateReplacePolicy: Delete
        DeletionPolicy: Retain
```

セキュリティグループのインバウンドに新たにHTTPSを追加しています。
`UpdateReplacePolicy`が「Retain」のままだと更新が適応されないので注意してください。

CloudFormationコンソールから先ほど実行したスタックを更新します。
![スクリーンショット 2021-06-18 15.31.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213467/9250d444-1f5d-9d3c-c915-95d5812f4cb6.png)

「既存テンプレートを置き換える」を選択し、「テンプレートファイルのアップロード」で修正した`test.yaml`をアップロードします。
完了したら「次へ」ボタンをクリックします。
![スクリーンショット 2021-06-18 15.10.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213467/0df98f6c-a24d-7407-b038-1cd787627837.png)

「次へ」ボタンをクリックします。
![スクリーンショット 2021-06-18 15.11.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213467/5d103a6c-ba77-0d9d-dd31-49acffa3bc82.png)

「次へ」ボタンをクリックします。
![スクリーンショット 2021-06-18 15.11.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213467/17d1556b-dbd2-6277-f229-0e8f59f9d8f9.png)

変更セットのプレビューで、セキュリティグループのアクションが「Modify」になっていることを確認します。
確認して問題がなければ「スタックの更新」をクリックします。
![ap-northeast-1.console.aws.amazon.com_cloudformation_home_region=ap-northeast-1 (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213467/85d23b93-d219-cec6-17b1-a6a92f2d2e9e.png)

実行したスタックを見て、ステータスが「UPDATE_COMPLETE」になれば更新は完了しています。
![スクリーンショット 2021-06-18 15.38.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213467/9c55986c-268f-255d-51ca-9bdd6a1a41d2.png)

更新したセキュリティグループをAWSコンソール上から確認します。
インバウンドルールが追加されていれば、確認完了です。
![スクリーンショット 2021-06-18 15.39.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213467/102e212c-7fe3-25d3-c10c-4633c6894288.png)


# 注意点
インポート機能については一部のリソースについてはサポートしていません。
例えばApplication Load Balancer のターゲットグループは2021年6月時点ではサポートされていません。

サポートされているリソースについては以下を参考にしてください。

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resource-import-supported-resources.html