Former2 からCloudFormation を生成してみた

# はじめに
私はCloudFormationを触ったことがなく、IaCの存在だけ知っている状態でした。
既存の環境のCloudFormationを作成する必要が出てきたため、
既存を自動でCloudFormation化できないか調べたところ、`Former2`がヒットしました。
なので、今回は過去に作成した環境と同じものをFormer2を使用して、CloudFormation化してみます。

↓過去に作成したやつ

https://qiita.com/y_inoue15/items/c637dd2e269f7ab50e38

# Former2 とは
Former2 は、AWS アカウント内の既存のリソースをIaC化するWebアプリです。

https://former2.com/

CloudFormationだけでなく、TerraformやTroposphereなど様々な形式でIaC化できます。
なお、今回はWeb上からではなく、ローカルでWebアプリを起動させ、CloudFormationを作成していきます。

# ローカルでの起動方法
Docker-composeを利用することで、簡単に起動させることができます。
以下のリポジトリをクローンし、docker-composeで起動させるだけです。
http://127.0.0.1:80 でアクセスできます。

https://github.com/iann0036/former2

# 実際にCloudFormation化してみた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1240861/7dafb716-eaa5-4a58-465a-39d4951be901.png)

> Install Former2 Helper for Google Chrome

拡張機能をインストールします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1240861/d4af3f36-ea74-202f-4335-4241f75acd74.png)

次に、AWSの認証情報を入力します。

IAMユーザーや、IAMロールの権限で実行できます。
今回はIAMユーザーを入力していきます。
また、今回作成するユーザーはすべてのリソースのRead権限のみを付与したアカウントにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1240861/79c32acb-7ab2-c171-2e09-a7031a44360c.png)

アクセスキーとシークレットアクセスキーを入力したら準備は完了です。
(Parameters、Settingsは特に設定せず、デフォルトのままいきます。)

# 実際の操作

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1240861/b87f91f2-8137-f12d-ac38-765c7722af42.png)

ダッシュボード画面から今回IaC化したいリソースを選択していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1240861/d1db7009-e3c0-b84f-ad70-22b58ce4bf78.png)

確認できたら、チェックボックスにチェックを入れ、`Add Selected`を押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1240861/a8ad343b-1bec-3537-f1cd-bf51b4d101d8.png)

するとGenerateに追加され、CloudFormationで使用できるコードが自動で作成されます。

対象のS3とCloudFrontを選択して、できたCloudFormationがこちら。
いい感じに生成されたものを参照する必要があるものなどは自動で参照されるようになってます。

```awk
AWSTemplateFormatVersion: "2010-09-09"
Metadata:
    Generator: "former2"
Description: ""
Resources:
    S3Bucket:
        Type: "AWS::S3::Bucket"
        Properties:
            BucketName: "former2-s3"
    S3BucketPolicy:
        Type: "AWS::S3::BucketPolicy"
        Properties:
            Bucket: !Ref S3Bucket
            PolicyDocument: 
                Version: "2008-10-17"
                Id: "PolicyForCloudFrontPrivateContent"
                Statement: 
                  - 
                    Sid: "AllowCloudFrontServicePrincipal"
                    Effect: "Allow"
                    Principal: 
                        Service: "cloudfront.amazonaws.com"
                    Action: "s3:GetObject"
                    Resource: !Sub "arn:aws:s3:::${S3Bucket}/*"
                    Condition: 
                        StringEquals: 
                            "AWS:SourceArn": !Sub "arn:aws:cloudfront::${AWS::AccountId}:distribution/${CloudFrontDistribution}"

    CloudFrontDistribution:
        Type: "AWS::CloudFront::Distribution"
        Properties:
            DistributionConfig: 
                Origins: 
                  - 
                    ConnectionAttempts: 3
                    ConnectionTimeout: 10
                    DomainName: !Sub "${S3Bucket}.s3.${AWS::Region}.amazonaws.com"
                    Id: !Sub "${S3Bucket}.s3.${AWS::Region}.amazonaws.com"
                    OriginPath: ""
                    S3OriginConfig: 
                        OriginAccessIdentity: ""
                DefaultCacheBehavior: 
                    AllowedMethods: 
                      - "HEAD"
                      - "GET"
                    CachedMethods: 
                      - "HEAD"
                      - "GET"
                    Compress: true
                    CachePolicyId: "658327ea-f89d-4fab-a63d-7e88639e58f6"
                    SmoothStreaming: false
                    TargetOriginId: !Sub "${S3Bucket}.s3.${AWS::Region}.amazonaws.com"
                    ViewerProtocolPolicy: "allow-all"
                Comment: ""
                PriceClass: "PriceClass_All"
                Enabled: true
                ViewerCertificate: 
                    CloudFrontDefaultCertificate: true
                    MinimumProtocolVersion: "TLSv1"
                    SslSupportMethod: "vip"
                Restrictions: 
                    GeoRestriction: 
                        RestrictionType: "none"
                HttpVersion: "http2"
                DefaultRootObject: ""
                IPV6Enabled: true


```

# 感想

今までコンソールから作成したため、いざ、同じ環境を構築しようとした際に、苦労した経験がありましたが、
Former2を利用することで、CloudFormation化し、すぐに環境が整えられると感じました。
また、試行錯誤したあと、テンプレート化する場合など、なかなか使えると思いました。
ただ、実際に登録されている値がそのまま出力されるため、
CI/CDで汎用的に利用するなど、汎用性が必要な場合は、書き換える必要があると感じました。

# 参考
https://dev.classmethod.jp/articles/former2-locally-and-cloudformation-existing-resources/