【コスト削減】AWS ECS(Fargate) の夜間休日タスク停止

# 1. はじめに
- AWSの各種コスト削減を検討しており、各種開発環境については、夜間・休日は自動で停止するようにしたい。
- ECS(Fargate)は、起動しているタスクのCPU/MEMの量に応じて課金される。これまでタスクを起動させっぱなしにしていたが、スケジューリングにより夜間・休日の停止が可能とのことで、実際に設定し動作を確認する。

# 2. やったこと
- 基本的なFargate環境(ALB経由でhttpサーバのタスクにアクセスできる環境)を作成し、通常時はタスクが2個起動している状態とする。
- タスク数を指定の時刻に自動変更する設定を追加し、想定通りに動作することを確認する。

# 3. 構成図

![fargate構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/fea9f497-7ab7-2652-4cb0-145c34c0ac55.png)



# 4. 手順
## 4.1 事前準備(検証環境作成)
- 検証を行うためのECS(Fargate)実行環境(構成図のもの)を作成する。
- ちょうど「FargateのHello Worldをやろう！」という初心者向けの素晴らしい記事「[【初心者必見】AWS Fargate の使用方法徹底解説](https://qiita.com/tatsuya11bbs/items/a7898275535a766718bf)」があり、その内容を丸々そのまま実施する。
    - Flaskで"Hello World"を表示するコンテナを作成し、タスクにする。
    - 上記をサービスとして定義し、ALB経由で外部からhttpアクセスできるようにする。
- 2023/7時点で少しマネコン画面の変更があるが、設定すべき内容は変わってないないので、ほぼそのまま実施可能。
- サブネットのアドレス設定などは自分の既存VPCを使用したため少し差分あり。
- インターネットからALBのFQDNにhttpアクセスすると、「Hello World」が表示されることを確認する。

![fargate01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/4d71d596-0ba1-b4d0-42e2-b997557a469f.png)

## 4.2 タスク数を自動変更する設定

### 4.2.1 Lambda 関数の作成

- タスク数を変更するLambda関数を作成する。今回やりたいことを既に検証している記事「[【小ネタ】FargateのAutoScallingをスケジュールベースで動かす方法](https://qiita.com/shnagai/items/c74163aa37bfc9d3bb2f)」があり、そのコードをそのまま使わせて頂く。夜間・休日に停止する(＝タスクを0にする)用の関数と、平日の朝にタスクを開始する(＝タスクを2にする)関数の2つを作成する。以下は停止する時のコード。開始する時はdesiredCountの値を2にする。

``` stop.py (上記記事よりそのまま引用)
import boto3
from botocore.exceptions import ClientError

def lambda_handler(event, context):
    try:
        client = boto3.client('ecs')
        service_update_result = client.update_service(
            cluster = 'ECSクラスタ名',
            service = 'ECSサービス名',
            desiredCount = 0
        )
        print(service_update_result)
    except ClientError as e:
        print("exceptin: %s" % e)
```

- 作成した2つのLambda関数に、ECSタスクを操作できるようにするための権限を付与する。権限の内容についてはまた別の記事「[検証環境のFargateのタスクを定期停止・定期起動してみた #Fargate](https://dev.classmethod.jp/articles/fargate-service-task-schedule-stop-start/)」のものをそのまま使わせて頂く。（Lambda関数の実行用IAM Roleに紐づくIAM Policyを以下に設定する。)

``` policy.json (上記記事よりそのまま引用)
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecs:DescribeServices",
                "ecs:UpdateService"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:*:*"
        }
    ]
}
```

### 4.2.2 EventBridge ルールへ登録

- 作成した2つのLambda関数をEventBridge ルールへ登録し、指定の時間に呼び出す。例として、平日9:00AMにstart(タスクを2個)にするLambda関数、平日21:00PMにstop(タスクを0個)にするLambda関数を呼び出す設定とする。

- 平日21:00PMにstop(タスクを0にする)設定を以下のように登録する。(startのルールも同様に作成する。)

![fargate06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/fb5504f1-d69a-cd01-eae3-17e4d1e49f72.png)
![fargate07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/60a7530a-511f-a637-4a75-104eb59cc554.png)
![fargate08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/bcc0667b-a651-3c0f-83ce-9590d3d28ba5.png)

## 4.3 動作確認

### 4.3.1 タスク数 2 -> 0

- タスク数2の状態において、EventBridgeのstopのルールを18:13PMに設定し実行させる。対象のタスクが0になることが確認できる。

![fargate09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/0191e307-25f7-cc1d-6856-1a427ae478bd.png)

- Lambda関数の実行により、タスク数が変更されたことがイベントでも確認可能。

![fargate10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/6ad2aa4a-fd34-d78a-2f1e-840b1e5b1be0.png)

- (当然ながら)ALB経由のアクセスは不可になる。

![fargate11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/d21ce072-6f1f-54c5-5100-a54c9d9362d4.png)

### 4.3.2 タスク数 0 -> 2

- タスク数0の状態において、EventBridgeのstartのルールを18:28PMに設定し実行させる。対象のタスクが2になることが確認できる。

![fargate12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/f44ccaf6-b576-bd67-cfc8-60fe974c5b33.png)

- Lambda関数の実行により、タスク数が変更されたことがイベントでも確認可能。

![fargate13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/c007f615-5bf1-8d5f-383b-da86de525f90.png)

# 5. 所感

- 既に世の中に出ていること以上の何かを発見できたわけではないが、改めてFargate検証環境の作成、タスク数0化の手順確認ができ、自信を持って他者にも説明できるようにはなったのでやった甲斐はあった。