手動作成したAWSリソースの差分を既存テンプレートに自動反映する方法

Shigeyukiです。

今回は、IaCで一度環境を構築した後に、マネコン上で検証しながら作成したAWSリソースを自動的に取り込む方法をご紹介したいと思います。

# 従来の方法
従来では、一度IaCで構築した環境に対して、手動で追加したAWSリソースをテンプレートに追加するには以下対応が必要でした。

**その１．CloudFormation Resource Importの利用**
　手動作成したAWSリソースを既存テンプレートに「DeletePolicy」を指定した状態で定義を追加して、CloudFormation Resource Importを利用する。
 
**その２．Former2の利用**
 Former2というWebアプリを利用して,手動作成したAWSリソースをテンプレート生成して、手動で既存テンプレート
 にマージする。

# 今回紹介する方法
CloudFormationnのIaCジェネレーターを利用することで、既存テンプレートに対して、手動追加したAWSリソースを指定することで自動反映してくれます。
以降、実際の手順を踏まえて説明します。

# 実際の手順
以下手順にて手動追加したりAWSリソースを既存テンプレートに反映します。

**１．IaCジェネレーターの動作機能を指定**
既存テンプレートを修正するために、IaCジェネレーターから「テンプレートを作成」ボタンを押下して、テンプレート作成機能をっ指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744312/a81e13c8-5bc1-4dff-a15a-1c3c8f019e82.png)


**２．テンプレートの作成方法を指定**
ここが一番のポイントになりますが、「既存のスタックのテンプレートを更新」を選択して、既存スタックを指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744312/02fe3770-c2d9-4a2f-af1c-9c5958ad8012.png)

テンプレートの詳細は、テンプレート名に任意名前を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744312/6e3c8885-e01e-4085-9fbf-a38308259e74.png)

**3.手動追加したリソースのスキャン**
IaCジェネレーターで追加操作させるには、手動追加したリソースをスキャン認識させます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744312/1bf85f54-8bae-4056-9187-b21d0bb80b8a.png)

「リソースをスキャン」ボタンを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744312/cad8b32d-ec58-4e82-bbe7-f0cd63768cc3.png)

「新しいスキャンを開始」ボタンを押下して、「すべてのリソースをスキャン」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744312/579121c8-c683-4a54-ab6b-3594f1448c90.png)

スキャンしたリソースがリストアップされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744312/3cfea517-fe57-441f-b078-747b0248c282.png)

対象リソースを指定して、選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744312/ac3ee5ed-e1de-43a5-aad2-7698848b937c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744312/123bd4e9-cc3e-48f4-a053-74d1dd49eeec.png)

**4.関連リソースの追加**
今回は関連リソースは必要ないため、指定なしですすめます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744312/80020b29-2683-45fb-a3c1-f70981b01f2a.png)

**5.テンプレートの作成**
「テンプレートを作成」ボタンを押下して、既存テンプレートを更新したものを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744312/8eeb4bb8-b746-4102-b24a-23bd620d4bb3.png)

以下のようにテンプレート作成されます。
テンプレート内の記述内容は、通常の並びとは異なっていますが、記述ルールは間違えていませんが
体裁を整えるには記述前後関係は修正する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744312/256247f9-8100-41c3-b9c8-e37eda3b389b.png)


# 差分追加された内容の確認
体裁を整えて既存テンプレートと差分して比較すると、メタデータの定義と手動追加したリソースのIaC記述が追加されていました。（緑箇所）
```diff_yaml
AWSTemplateFormatVersion: '2010-09-09'
+Metadata:
+ AWSToolsMetrics:
+   IaC_Generator: arn:aws:cloudformation:ap-northeast-1:992382669030:generatedTemplate/80cd29a4-bfc3-4805-9f7a-a84fcfc0ce16
Resources:
  SampleVpc:
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: false
      InstanceTenancy: default
      Tags:
        - Value: drift-cfn-vpc
          Key: Name
    Type: AWS::EC2::VPC
+  EC2VPCEndpoint:
+    UpdateReplacePolicy: Delete
+    Type: AWS::EC2::VPCEndpoint
+    DeletionPolicy: Delete
+    Properties:
+      PrivateDnsEnabled: false
+      IpAddressType: not-specified
+      DnsOptions:
+        PrivateDnsOnlyForInboundResolverEndpoint: NotSpecified
+        DnsRecordIpType: not-specified
+      ResourceConfigurationArn: ''
+      SecurityGroupIds: []
+      SubnetIds: []
+      ServiceNetworkArn: ''
+      VpcId: vpc-0169ff897cf99ae89
+      RouteTableIds: []
+      ServiceName: com.amazonaws.ap-northeast-1.s3
+      PolicyDocument:
+        Version: '2008-10-17'
+        Statement:
+          - Resource: '*'
+            Action: '*'
+            Effect: Allow
+            Principal: '*'
+      VpcEndpointType: Gateway
+      Tags:
+        - Value: sample-vpc-endpoint
+          Key: Name
  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.0.0/24
      VpcId: !Ref SampleVpc
      AvailabilityZone: !Select

＜以下省略＞
```

# オプション
自動生成したテンプレートを利用してCDKモジュールを自動生成させることができます。
先ほどのIaCジェネレーターで生成されたテンプレート画面から「AWS CDK」タブを選択し、ステップ１で自動生成されたテンプレートファイルをローカルにダウンロードします。
ステップ２で指定されたCDKコマンドをローカルで実行することで、CDKモジュールが自動生成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744312/bdbeb18b-3d4a-49be-b1dd-4d380736f3c6.png)


# まとめ
IaCジェネレーターを利用することで、既存テンプレートに追加したリソースを自動反映させることできますので
IaCの差分反映の煩わしさがおおきく削減できるのではないでしょうか。
また、生成したテンプレートからCDKへ変換するコマンドを自動生成してくれるので、幅広いIaCの利用に役立つのではないでしょうか。