AWSで作成した環境をFormer2を使ってリバースでIaCしてみたので公開 #環境構築編

## 初めに
今回は、タイトル通りではあるのですが

https://former2.com/

を使用して既存の環境をリバースでIaCしてみました。
それなりに簡単に環境構築できるはずなので公開します。（エラー吐きまくったらすみません。）
これを足掛かりにいろいろ変えてみてIaCやECS、コンテナとかに触れるきっかけになればなと思います。

環境によってかもですが、former2で設定の抽出は
[こちら](https://former2.com/#section-setup-introduction)から手順通りやっただけなので割愛します。

Former2で出力した元々のファイル公開してどう修正したら動くようになるのかビフォー/アフターで出したかったのですが
思いのほか、公開しちゃいけない値とかが散見されたので、、、
なので修正内容は下記に別記事として羅列していきたいと思います。
 - [AWSで作成した環境をFormer2を使ってリバースでIaCしてみた #エラー解消編](https://qiita.com/toma__/items/73bff82446c83b4ad446)

## 今回の環境
※図とかやりたかったけど時間なかったので部分的に列挙します。（後で時間あったら作ります）
 - AWS
 - プライベートECR
 - ECS
 - S3
 - CloudFront
 - ALB
 - CodeCommit
 - CodePipeline
 - Trivy

このあたり使ってます。そこらへんに興味あったら見てみてください。

## 前提
- ローカルでDockerコマンドが使用できること
- ローカルでGitコマンドが使用できること
- コンソールのログインで使用してるユーザがそれなりに権限高いこと
できればAdministratorAccessついていてくれてると良き

## GitHubからソースをクローン
### 手順
 - https://github.com/toma-ooo/aws-ecs-cicd
上記から適当な場所にクローン

### 構成内容
 - aws-stack：これが今回Former2で出力したファイルをトライアンドエラーで作成したIaCファイルたちです。
 - dist：ビルド資材が入ってきます。本来いらないのですが、無いとビルドでエラーになるので暫定で入れています。
 - src：TypeScriptのコードが入っています。ECSで実行されてAPIとして動作します。
 - Dockerfile：こちらはECSで動くコンテナのイメージを作成するためのファイルです。

## CloudFormationでスタック作成
### 手順
 - [cloudformation画面](https://ap-northeast-1.console.aws.amazon.com/cloudformation/home)からスタックの作成を選択
 - 新しいリソースを使用（標準）を選択
 - テンプレートの指定を選択
 - テンプレートファイルのアップロードを選択
 - ファイルの指定を選択
 - ここでクローンしてきたフォルダの```\aws-stack\00_cloudformation_init.yaml```を選択し次へ
 - 下記に適当な値を設定
   - スタック名：このスタック（環境を識別する値）
   - CloudshellGlobalIp：[クラウドシェル画面](https://ap-northeast-1.console.aws.amazon.com/cloudshell/home)から```curl http://checkip.amazonaws.com/```を実行しその値を入力
   - IamUser：権限周りで使用していたので設定してください。（見直してみるといらないかも？）
   - PJPrefix：各サービスに名前を付けたりタグをつけたりするときに先頭に着ける（長すぎるとエラーになるので文字列10文字前後で設定してください）
 - 成功したらスタックのところが「CREATE_IN_PROGRESS」から「CREATE_COMPLETE」になっているのでそれが確認

### やったこと
Former2にてIaC化した環境をスタックとして実行してCI/CD環境を構築

## コードコミットリポジトリへプッシュ
### 手順
 - [CodeCommitの一覧](https://ap-northeast-1.console.aws.amazon.com/codesuite/codecommit/repositories)から[PJPrefix]-codecommitを選択
 - 「接続のステップ」に従って接続設定を行い、ローカルにクローンする
 - 最初にクローンした「toma-ooo/aws-ecs-cicd」のフォルダの.gitフォルダ以外を先ほどクローンしたフォルダにコピーする。
 - コピー先にてコピーをコミットしてプッシュ
※プッシュの際ユーザとメールアドレス登録して的なメッセージが出るようだったら
　git\configファイルの末尾に下記を追加（名前とメアドは好きなように変えてください）
```
    [user]
    	name = toma
    	email = toma@test.test.jp
```

### やったこと
サンプルのGitHubからCodeCommitの資産をコピーしてプッシュ
そうすることでCodeBuildが動き[ECR](https://ap-northeast-1.console.aws.amazon.com/ecr/repositories?region=ap-northeast-1)に[PJPrefix]-ecr-simpleapiリポジトリにイメージがプッシュされる作成される
また、[パイプライン](https://ap-northeast-1.console.aws.amazon.com/codesuite/codepipeline/pipelines)の名前が[PJPrefix]-codepipeline-devsecopsのパイプラインがありそれを確認すると、SourceとBuildが実行されている。
その中でBuildのAWS CodeBuildというリンクになっている部分があるのでリンクをクリックし
遷移先の画面でビルドの実行でステータス実行中になっているのでビルドの実行のリンクをクリックする。
そうするとビルドログが確認できる。
※このビルドしているときにいろいろ行っているのは別記事で話す予定

## スタックの更新（デプロイ設定の追加）
### 手順
 - 再度[cloudformation画面](https://ap-northeast-1.console.aws.amazon.com/cloudformation/home)を開き作成したスタックを選択する。
 - 更新ボタンが活性化するのでクリック
 - 既存テンプレートを置き換えるを選択
 - テンプレートファイルのアップロードを選択
 - ファイル選択ボタンをクリック
 - \aws-stack\10_cloudformation_add_ecs_s3policy.yamlを選択
 - 次へボタンをクリック
 - 次へボタンをクリック
 - 次へボタンをクリック
 - AWS CloudFormation によって IAM リソースがカスタム名で作成される場合があることを承認します。をチェック
 - 送信ボタンをクリック

### やったこと
ここではデプロイ先のECSのスタックを作っています。
なぜ最初に作っていないというとECSのタスクを作る際にコンテナを指定するため、最初の時点ではECRを設定はしているもののその中にイメージがプッシュされておらずエラーになるため2段更新となってます。
※もしかすると別の書き方で1回でできる方法はありそうな気がしますが、調べる体力が残ってなかったので。。。

## 再ビルド
### 手順
 - ローカルのリポジトリにて\scr\index.tsを開く
 - ```res.end("Hello World!!");```となっている部分のHello World!!を自由に変更する
 - Gitにてコミットする
 - Gitにてプッシュする
 - 「ビルドの実行」手順同様に[パイプライン画面](https://ap-northeast-1.console.aws.amazon.com/codesuite/codepipeline/pipelines)にて[PJPrefix]-codepipeline-devsecopsを選択し、Buildが成功していることを確認
 - もう一度[パイプライン画面](https://ap-northeast-1.console.aws.amazon.com/codesuite/codepipeline/pipelines)にて[PJPrefix]-codepipeline-devsecopsを選択し、Deployが成功していることを確認

### やったこと
ローカルで確認する対象ソースコードを変更して再度プッシュすることで後の動作確認時に自身が変更した結果で動いていることを見るため

## ECSが正しくデプロイされているか確認
### 手順
 - [クラウドシェル画面](https://ap-northeast-1.console.aws.amazon.com/cloudshell/home)から```curl http://checkip.amazonaws.com/```を実行しスタックに登録したIPと変わっていないことを確認
 ※変わっている場合は「スタックの更新（デプロイ設定の追加）」と同じような手順でCloudshellGlobalIpを更新

 - [ロードバラサー画面](https://ap-northeast-1.console.aws.amazon.com/ec2/home?region=ap-northeast-1#LoadBalancers:)にて[PJPrefix]-albを選択
 - 詳細のDNS名をコピーする
 - クラウドシェルに戻り```curl [コピーしたDNS]```を実行する

### やったこと
ここではデプロイされたECSのタスクが正しく動いているかを確認しています。
実態（コンテナ）は[ECSクラスタ一覧画面](https://ap-northeast-1.console.aws.amazon.com/ecs/v2/clusters?region=ap-northeast-1)にて[PJPrefix]-ecsができており、その中のタスクというところで見ることができます。

## Trivyのチェック結果をCloudFrontで確認
### 手順
 - CloudFrontの[ディストリビューション一覧画面](https://us-east-1.console.aws.amazon.com/cloudfront/v3/home?region=ap-northeast-1#/distributions)を表示
 -	オリジンが[PJPrefix]-report.s3.ap-northeast-1.amazonaws.comとなっているディストリビューションのIDリンクを選択
 -	ディストリビューションドメイン名をコピー
 -	コピーしたドメインをブラウザにてアクセスする

### やったこと
ここではビルド時にTrivyにてコンテナの脆弱性をチェックした結果をS3に配置しておりそれを参照するためにCloudFrontを設定しておりそこが正しく表示できるかを確認しています。
※CloudFrontで全体公開するのは微妙なので後で変更したい。
　下記のようにIP制限とかBasic認証とかはしたいですね、今回はそもそも対象のコンテナがプライベートで特定IPからのみしかアクセスできないようになっているので一旦妥協しちゃいました。

https://qiita.com/dayjournal/items/7989da7374050c5d09b1

### スタックの削除について
基本的にはスタックの削除ボタンから削除できます。
ちょっと例外があるのでそこだけ残しておきます。
 - S3は中にオブジェクトがあると削除できないので手動で削除が必要
 - ECRは中にイメージがあると削除できないので手動で削除が必要

あとCloudFrontとECSは削除に時間がかかるので気長に待ってもらえればと思います。

## 終わりに
今回は検証用に立てていた既存環境をFormer2でIaCしてみましたが、0からIaC書くよりは初心者向けではあるかなと思いました。
自分がIaC初心者なので0からだと何を設定しなくちゃいけないのかを調べる足掛かりが無くてフリーズすることがあってやってみました。
中級上級になってきたら逆に設定するべきでは内容の精査や、そもそも出力されていない設定の確認などを行うくらいなら0から作った方が早そうな感じもしました。
今度やるときは0からやってみようかなと思います。

あと、この後はこのIaCのファイルに対して脆弱性チェックかけてみたいなと思ってます（結構NG出てきそう）