【データ基盤構築/AWS】CloudFormationを使って構築済の既存リソースをコードで管理する

# 今回の課題
既存のリソースをCloudFormationを使って、コードで管理できるようにしたい。

これまで、下記の記事の投稿したようにデータ基盤の構築に挑戦した。
次は、AWSのインフラをコードで管理するということに挑戦してみる。


**◼︎これまで実装してきたインフラやデータ基盤など**
・RDSのスナップショットをlambdaでS3にエクスポート
・S3のデータをSnowflakeにロード
・SnowflakeのデータをRedashで可視化

https://qiita.com/Ayumu-y/items/523f700960129c57e3b3

https://qiita.com/Ayumu-y/items/d6713e09b0a409d1bd25

https://qiita.com/Ayumu-y/items/cfd5f1ffdfdfe24d31d3

# [追記]簡単に既存リソースをコード化する方法があった
https://dev.classmethod.jp/articles/former2/

## なぜCloudFormationを使うのか
CloudFormation(IaC)を使うメリットを調べてみた。
これまでAWSのインフラをGUIで構築してしまっていたので、
今後はCloudFormationを使用して構築するようにしようと思う。
* **作業の効率化ができる**
コードでインフラの環境の構築や管理を自動化することで、手作業よりも工数を削減できて作業効率が上がる。
また、同じ構成のサーバーを複数用意したい場合、１から構築する手間が省ける。

* **人的ミスを削減できるため**
コードに基づいて自動的にインフラが構築されるので人的ミスを避けることができる。
上記でも記述した、同じ構成のサーバーを複数用意したい場合に、ミスが発生することを避けたりできる。

* **Gitなどでコードのバージョン管理ができるため**
コード履歴を保存することができるので、管理やメンテナンスがしやすくなる。


## 進めた手順：既存VPCをCloudFormationのスタックにインポートしてみる
これまで、AWSのリソースをGUIで構築してしまっていたので、
既存VPCをCloudFormationのスタックにインポートしてみることにした。

### 1)テンプレートファイルを用意する
既存リソースをインポートする場合、
**事前にリソースに合ったテンプレートファイルを用意しなければいけない**ようだった。
なので、まずはymlで既存VPCのテンプレートファイルを用意することにした。

※vscodeでテンプレートファイルを用意する場合は、[こちら](https://marketplace.visualstudio.com/items?itemName=aws-scripting-guy.cform)を併せて使うと便利。


https://maasaablog.com/infrastructure/aws/cloud-formation/2693/

##### ◼︎用意したテンプレート(VPCを構築する用)


```yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Existing VPC Stack

Resources:
  VPC:
    Type: AWS::EC2::VPC
    DeletionPolicy: Retain 
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: Rails-EC2-RDS-20230327-vpc
    
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    DeletionPolicy: Retain
    Properties:
      Tags:
        - Key: Name
          Value: Rails-EC2-RDS-20230327-igw
     
  PublicSubnet1:
    Type: AWS::EC2::Subnet
    DeletionPolicy: Retain
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: ca-central-1
      CidrBlock: 10.0.0.0/20
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: Rails-EC2-RDS-20230327-subnet-public1-ca-central-1a

  PublicSubnet2:
    Type: AWS::EC2::Subnet
    DeletionPolicy: Retain
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: ca-central-1
      CidrBlock: 10.0.16.0/20
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: Rails-EC2-RDS-20230327-subnet-public2-ca-central-1b
            
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    DeletionPolicy: Retain
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: Rails-EC2-RDS-20230327-rtb-public

  SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    DeletionPolicy: Retain
    Properties:
      GroupDescription: "Security group with no ingress rule"
      VpcId: !Ref VPC
```

### 2)作成したテンプレートをCloudFormationのスタックにインポートする
#### 2)-1.作成したテンプレートをインポートする
CloudFormationのコンソールの、`スタックの作成`>`既存のリソースを使用(リソースをインポート)`からステップ2の`テンプレートの指定`まで飛ぶ。
下記の`テンプレート指定`のページにて、`1)`で作成したテンプレートを選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/ca786fbb-8aa9-2327-e2b1-c8f06308aa9c.png)

#### 2)-2.リソースを識別するためのIDを入力する
次に`リソースを識別`ページに飛ぶので、
ここでCloudFormationで管理したい既存リソースのIDを一つ一つ埋めていく。
入力が終わったら`次へ`をクリックする。

<font color="Red">※こちらをきちんと入力できていなくてエラーに苦しんだので、既存リソースのIDの入力に間違いがないかは、きちんと確認するようにする</font>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/625c1ef7-263f-10d9-31c4-7774015411ec.png)

#### 2)-3.あとは`スタック名`を設定すればOK
ステップ4の`スタックの詳細を指定`ページに飛び、パラメータを変更する。
`次へ`をクリックし、ステップ5の`レビュー`ページで`スタック名`を設定して登録完了。


# まとめ
以上で、既存VPCをコードで管理することができるようになった。



#### 参考記事
いろいろな記事を見て、CloudFormationについて勉強しながら、
今回の記事の内容の実装に挑戦した。

https://dev.classmethod.jp/articles/aws-cloudformation-rain/

https://dev.classmethod.jp/articles/aws-all-iac/


https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/CHAP_TemplateQuickRef.html

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/best-practices.html

https://dev.classmethod.jp/articles/learn-from-aws-cloudformation-template/

https://qiita.com/y-ohgi/items/89f07e866713185799f5

https://www.ragate.co.jp/blog/articles/10628

https://dev.classmethod.jp/articles/cfn-import-deletionpolicy-not-retain/