CloudWatchEventsからECS on Fargateのタスクを定期的に実行しつつ環境変数を上書きする方法

# バージョン情報

```
$ terraform version
Terraform v0.14.6
+ provider registry.terraform.io/hashicorp/aws v3.27.0
```


# 結果はこちら

```terraform

resource "aws_cloudwatch_event_rule" "cwevent_rule" {
  name                = ${好きな名前}
  schedule_expression = "cron(%d 21 * * ? *), # JST cron(%d 6 * * ? *)"
  # schedule_expression = "rate(1 minute)"
  is_enabled          = true
}
resource "aws_cloudwatch_event_target" "cwevent_target" {
  arn      = ${ECSクラスターのARN}
  rule     = aws_cloudwatch_event_rule.cwevent_rule.name
  role_arn = aws_iam_role.event_bridge.arn
  input = <<EOL
{
    "containerOverrides": [
      {
        "name": "${上書きしたいコンテナのname}",
        "environment": [
          { "name": "HOGEFUGE", "value": "hogefuge" }
        ]
      }
    ]
  }
EOL
  ecs_target {
    launch_type         = "FARGATE"
    platform_version    = "1.4.0"
    task_count          = 1
    task_definition_arn = ${起動したいtask_definitionのARN}   # リビジョン指定部分をsubstr()とかで削れば常にlatestで動く

    network_configuration {
      assign_public_ip = false
      subnets          = ${タスクを動かしたいサブネットID}
      security_groups  = [${タスクにアタッチしたいSGのID}]
    }
  }
}

data "aws_iam_policy_document" "event_bridge" {
  statement {
    effect = "Allow"
    principals {
      identifiers = ["events.amazonaws.com"]
      type        = "Service"
    }
    actions = ["sts:AssumeRole"]
  }
}
data "aws_iam_policy_document" "event_bridge" {
  statement {
    effect  = "Allow"
    actions = ["ecs:RunTask"]
    resources = ["*"]
  }
  statement {
    effect    = "Allow"
    actions   = ["iam:PassRole"]
    resources = ["*"]
    condition {
      test     = "StringLike"
      variable = "iam:PassedToService"
      values   = ["ecs-tasks.amazonaws.com"]
    }
  }
}
resource "aws_iam_role_policy" "event_bridge" {
  policy = data.aws_iam_policy_document.event_bridge.json
  role   = aws_iam_role.event_bridge.name
}
resource "aws_iam_role" "event_bridge" {
  name               = ${好きな名前}
  assume_role_policy = data.aws_iam_policy_document.event_bridge.json
}

```

# なんでこんなことをしたか

- embulkをECSを利用し定期的に実行したかった
    - ただし、すべてのテーブルを全部同時に動かすと負荷が怖いのでテーブル単位で動かしたかった
- でもテーブルごとにdockerイメージやECSタスクを作るのはめんどくさい
- ECSでコンテナ起動する時に環境変数を注入するがそのときの環境変数をCW Events側で上書きできればECSサービス、ECSタスク、Dockerイメージ、それぞれ１つだけ用意すれば動かせることに気がついた


# 「CloudWatch Events」?「Amazon EventBridge」?

- CW Eventsは名前が変わるっぽいのでドキュメント探すときは注意が必要かも？
- Terraform側はどう対応するのか気になる

https://aws.amazon.com/jp/eventbridge/faqs/
> Q: Amazon EventBridge は CloudWatch Events とどのように関連していますか?
> 
> Amazon EventBridge は、CloudWatch Events をベースに構築された、CloudWatch Events を拡張するサービスです。Amazon EventBridge では、CloudWatch Events と同じサービス API とエンドポイント、同じ基盤となるサービスインフラストラクチャを使用します。これまで CloudWatch Events を使用しているお客様にとっては、何も変わることはありません。これまでと同じ API、CloudFormation テンプレート、コンソールを引き続き使用できます。お客様からの報告によれば、CloudWatch Events はイベント駆動型アーキテクチャを構築するための理想的なサービスです。そのため、AWS ではお客様が独自のアプリケーションとサードパーティーの SaaS アプリケーションからデータを接続できるようにする新しい機能を構築しました。AWS は、この機能を CloudWatch サービス内にとどめておくのではなく、Amazon EventBridge という新しい名前でリリースしました。この機能が、CloudWatch Events が開発された目的であるモニタリングユースケースを超えた拡張であることを示すためです。


# 参考資料

- [Terraform: Resource: aws_cloudwatch_event_target](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target)
- [AWS > Documentation > Amazon Elastic Container Service > API Reference > ContainerOverride](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/APIReference/API_ContainerOverride.html)
- [Amazon ECS で Step Functions または Fargate タスクを管理する](https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/connect-ecs.html)
    - inputに渡せるexampleがあるのでこのページが一番わかり易い