Fargate動作確認の備忘録

## はじめに
これまではチュートリアルなどを通して何となくFargateを触っていたが、今回はFargateを利用して実際にサーバーレスの仕組みを実装したく、その際に真面目に動作確認を実施したので備忘録として残す。内容はごく初心者向け。

以下の順序でFargateの動作確認までを実施した。
1. Fargate実行用のVPCを作成。
1. Amazon ECSからClusterを作成。
1. 動作確認用のDockerイメージをCloud9に用意する。
1. Amazon ECRを作成。
1. Cloud9にあるDockerイメージをECRにプッシュ。
1. 実際に動作させるTask定義を作成。
1. Taskを実行する（デプロイする）。
1. Task実行エラーを解決。
1. 再度Taskを実行し動作確認完了。

## Fargate実行用のVPCの作成
VPCコンソールからシンプルに作成していく。今回は今後の検証幅も広めたいのでMaltiAZ構成とした。一旦NAT GatewayとVPCエンドポイントは無しで作成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/33a8a87b-5076-28d6-d75b-9e1622d3d66f.png)

## Clusterの作成
いきなりClusterという用語が出てきた。参考記事に載ってある図込みの説明がわかりやすい。文字だけ載せておくと、Clusterとは
>ECSを使う際のサービス単位。
クラスターの中にコンテナを立ち上げていく。

ということである。
ECSのコンソール画面から作成していく。今回のコンテナはとりあえずPublic Subnetの中で起動するようにしておく（ゆくゆくはPrivate Subnetでの動作も確認したい。）先ほど作成したVPCとサブネットを選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/a9477b02-86ec-f120-0b1e-2b765a09dece.png)

一旦これだけでClusterは作成できた。この時点ではまだClusterとは何ぞや、、の状態だがそのまま次に進む。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/a70b001e-a2a0-6608-792c-c2cbe2bee7b4.png)

## Docker Imageの用意
今回はCloud9をローカルと見立てDockerのイメージを用意する。ひとまず軽量の`alpine`イメージをpullして、これを使うこととする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/1adac67c-cb6a-8ac6-b520-7339555eb208.png)

`docker images`とすると、ローカルにDockerイメージが用意されたことが分かる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/4b468910-3a2e-47e0-a14e-b8ce15de2a37.png)

## ECRの作成
Dockerイメージを保管・管理するためのリモートリポジトリをECRの画面から作成する。なんとなくGitリポジトリ（CodeCommitのリポジトリなど）と同じような感じだろうと思っている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/9f7c9fa5-d255-3f6b-457f-214e911b9e84.png)

## ECRにDockerイメージをプッシュ
さて、リポジトリが作成されたので先ほどpullしたDockerイメージをプッシュしていきたい。ECRのコンソール画面からリポジトリへプッシュする際のコマンド手順が確認できるので、こちらに沿って実施していく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/7dee8388-cb36-d704-1fe8-1440d2bf3a4a.png)

まずはECRへの接続認証（1番目の手順）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/80f3f75d-ae6e-8642-1ccd-05b89f452020.png)

2番目の手順（ビルド）は今回pullしたイメージでは不要（ビルド済）なのでスキップし、3番目の手順を実施する。ビルドしたイメージにタグ付けをしている。タグ付けコマンドの後に`docker images`とすると`latest`のタグ付けされたイメージが確認できる。（イメージが追加されている）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/cb5947e1-7b8c-639e-e772-a051ada1b031.png)

最後に`docker push タグ付けされたDockerイメージ`としてECRのリポジトリにイメージをプッシュ（4番目の手順）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/c29d5316-465e-9262-f1ae-bc01e7a8720e.png)

ECR側の画面でも、プッシュされたイメージが確認できた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/1932f6ef-8f65-a47e-6a7e-366750097b76.png)

## Task定義の作成
Task定義とは、、とまた新しい概念が出てきた。またまた参考サイトから引用させてもらうと、タスクとは
>ECSにおけるタスクとは、起動するコンテナの情報を定義したもの。
１つのタスクに対し、複数のコンテナを記述できる。

ということらしい。つまりどんなコンテナ（EC2 or Fargate）で実行するかであるとか、とのコンテナのスペック（メモリやCPU）を定義する設定らしい。Task定義 = Taskの定義というイメージよりは、Task定義 = Task実行環境の定義、みたいなイメージだろうか。

今回はFargateを選択し、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/492c7338-c10b-3a14-f897-ab083561c94f.png)

OSはLinuxを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/e9f3ec37-bedd-19f7-a6fc-731531699c7f.png)

Taskサイズは最小値を設定。
ん？ここで`Add container`のボタンがある。コンテナの追加？どういうこっちゃ？と思いながらボタンを押して進めてみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/b359ab66-6d40-69b7-ee52-4309ff985fbc.png)

### Containerの追加
（なぜかここ以降は「ですます調」になっています。（笑））
Task定義で「起動するコンテナ情報」を定義していますが、実際に「起動するコンテナ自体」を追加する必要があるということでしょうか。たしかに、「Dockerサービス」＝「コンテナサービス」のイメージがあるので、コンテナを追加するということは、実行するDockerを追加する、というようなイメージを持てばすこししっくりきます。
Add Containerの画面では、利用するイメージを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/ca8434b3-4a20-122c-7647-ab606f5b8fd0.png)

ひとまず実行したかどうかをすぐに確認したいので、`Command`の部分に`date`とだけセットしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/03618a39-890c-a4e4-ac6f-0692e0404662.png)

CloudWatch Logsにログも出力しておきたいので、`Log configuration`にもチェック。最後に`Add`ボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/69306e74-1a04-879e-5d32-f171813245fb.png)

Task定義の画面で作成を完了すると、どうやらTask定義が作成されたっぽい画面が表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/f588cc52-6045-562b-5e04-abc7e1e68e52.png)

## Taskを実行する
ではTaskを実行してみます。Task定義の画面から`Run Task`とすることでTaskを実行できそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/6c969921-2411-752a-c327-552ae1c8bc0f.png)

とここでAWS側の新しいUI`New Experience`があることに気が付いたので、今後はこちらの画面で進めていきます。同じようにタスク定義の画面からタスク実行できますが、新UIの方ではタスクのRunを`Deploy`という概念で表しているみたいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/b2a31b6e-b2e7-0719-c9eb-a7732e5d4d71.png)

Taskを実行するコンピュートオプションで`Launch type`を選択します。もう一つの選択肢のCapacity provider strategyについては参考サイトの内容が分かりやすかったので、興味のある方はそちらを参照してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/5b2fed66-5839-99ee-4606-3859a7a4a367.png)

以下はデフォルトのままにして
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/a3d9bec3-b783-3b79-52b4-95e773fcf193.png)

`Networking`の項目では、作成したVPCとpublic subnetを選択します。セキュリティグループもデフォルトで選択されているPublic Subnet用のSGをそのまま利用しています。（クラスターを作成したときにもVPCやSubnetを選択しているのに、またここで選択。。なぜ？Clusterの概念がわかりづらい。Fargateだからでしょうか。クラスターを選択するような感じならまだわかりやすい気もするのですが。。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/8ec79c1d-1c2b-ed5e-6fd0-0543464b6d59.png)

### Run
Runしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/b67f3708-23f3-e6ad-50ee-e5c25dbebf46.png)

エラーがでました。どうやらECS（Fargate）とECR間でのやりとりがうまく行っていない様子です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/bb9bf293-1f22-3f06-f05e-24ee284a90a8.png)

参考記事に記載されている二つの修正内容を実施します。一つ目は`ecsTaskExecutionRole`に`AmazonEC2ContainerRegistryReadOnly`ポリシーをアタッチ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/1ac2653e-ac0d-2458-b177-15a6ef741419.png)

そしてFargateのVersionを1.3に設定。（この方法は根本的な解決にはなっていませんが、今回は動作確認が目的なので一旦これで回避）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/8d8cec18-16c8-0d08-e161-d265c29cd61b.png)

再度Runすると、無事に`date`コマンドのログが確認できました。これで動作確認は完了しましたが、以外とステップが多く、所々理解に悩む概念などもありました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/7d5331b4-1dfe-2cc6-f64e-ad18686e2d00.png)

## おわりに
クラスター、コンテナー、タスク定義、タスク、サービス、ECR、イメージなど、ECSを使い始める場合には少なからずキャッチアップが必要な概念があるので、参考記事の内容であったり今後の検証を通して、自分の中で腹落ちできるように理解を進めていきます。

## 参考記事
https://zenn.dev/umatoma/articles/5862ee6cc1e7c4

https://dev.classmethod.jp/articles/fargate-my-first-step/#toc-5

https://dev.classmethod.jp/articles/regrwoth-capacity-provider/

https://note.com/shift_tech/n/nf456dd5900df