ECSタスクでリバースプロキシを利用する

# ECSタスクでリバースプロキシを利用する方法
ECSタスクでリバースプロキシを利用し、後ろに控えるアプリケーションサーバーへトラフィックをルーティングします。

今回構成するのはDockerComposeで書くとこんな構成

```docker:
version: '3.8'

services:
  nginx:
    image: public.ecr.aws/nginx/nginx:1.26
    ports:
      - 80:80
    volumes:
      - type: bind
        source: ./nginx
        target: /etc/nginx/conf.d
    depends_on:
      - app
  app:
    image: app-image:latest
```

参考ページ

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/ContainerInsights-Prometheus-Setup-nginx-ecs.html

## １ー ECRにコンテナイメージを作成
- nginx
必要ない部分を削除し、ポートをアプリケーションサーバーに合わせる
```diff_nginx:nginx.conf
events {
  worker_connections 768;
}

http {
  # Nginx will handle gzip compression of responses from the app server
  gzip on;
  gzip_proxied any;
  gzip_types text/plain application/json;
  gzip_min_length 1000;

-  server{
-    listen 8080;
-    location /stub_status {
-        stub_status   on;
-    }
-  }

  server {
    listen 80;

    # Nginx will reject anything not matching /api
    location /api {
      # Reject requests with unsupported HTTP method
      if ($request_method !~ ^(GET|POST|HEAD|OPTIONS|PUT|DELETE)$) {
        return 405;
      }

      # Only requests matching the whitelist expectations will
      # get sent to the application server
-       proxy_pass http://app:3000;
+       proxy_pass http://app:80/;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection 'upgrade';
      proxy_set_header Host $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_cache_bypass $http_upgrade;
    }
  }
}
```

nginxイメージをECRのパブリックギャラリーから取得するように変更
```diff_docker:Dockerfile
- FROM nginx
+ FROM public.ecr.aws/nginx/nginx:1.26
COPY nginx.conf /etc/nginx/nginx.conf
```

- アプリケーションサーバー
任意のアプリケーションサーバーのコンテナイメージを構築

## ２ータスク定義作成
JSONだとこんな感じ
```json:タスク定義
{
    "taskDefinitionArn": "{タスク定義のARN}",
    "containerDefinitions": [
        {
            "name": "nginx",
            "image": "{アカウントID}.dkr.ecr.{リージョン}.amazonaws.com/nginx:latest",
            "cpu": 0,
            "links": [
                "app"
            ],
            "portMappings": [
                {
                    "name": "nginx-80-tcp",
                    "containerPort": 80,
                    "hostPort": 0,
                    "protocol": "tcp"
                }
            ],
            "essential": true,
            "environment": [],
            "environmentFiles": [],
            "mountPoints": [],
            "volumesFrom": [],
            "ulimits": [],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-create-group": "true",
                    "awslogs-group": "/ecs/{タスク定義名}",
                    "awslogs-region": "{リージョン}",
                    "awslogs-stream-prefix": "ecs"
                },
                "secretOptions": []
            },
            "systemControls": []
        },
        {
            "name": "app",
            "image": "{アカウントID}.dkr.ecr.{リージョン}.amazonaws.com/app:latest",
            "cpu": 0,
            "portMappings": [],
            "essential": false,
            "environment": [],
            "environmentFiles": [],
            "mountPoints": [],
            "volumesFrom": [],
            "systemControls": []
        }
    ],
    "family": "{タスク定義名}",
    "taskRoleArn": "{タスクロールのARN}",
    "executionRoleArn": "{タスク実行ロールのARN}",
    "networkMode": "bridge",
    "revision": 1,
    "volumes": [],
    "status": "ACTIVE",
    "requiresAttributes": [
        {
            "name": "com.amazonaws.ecs.capability.logging-driver.awslogs"
        },
        {
            "name": "ecs.capability.execution-role-awslogs"
        },
        {
            "name": "com.amazonaws.ecs.capability.ecr-auth"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"
        },
        {
            "name": "com.amazonaws.ecs.capability.task-iam-role"
        },
        {
            "name": "ecs.capability.execution-role-ecr-pull"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.29"
        }
    ],
    "placementConstraints": [],
    "compatibilities": [
        "EC2"
    ],
    "requiresCompatibilities": [
        "EC2"
    ],
    "cpu": "1024",
    "memory": "3072",
    "runtimePlatform": {
        "cpuArchitecture": "X86_64",
        "operatingSystemFamily": "LINUX"
    },
    "registeredAt": "",
    "registeredBy": "",
    "tags": []
}
```

- 重要点
    - ネットワークモードはbridge
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1610187/d55fef0f-5855-d7f1-80c9-147301ac1158.png)
    - リンクにコンテナ名を選択
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1610187/7cc13b08-bea1-345a-b869-0fb9cbde603d.png)
手動で作成する場合は`コンテナ - 2`を定義するとリンクにコンテナを選択できるようになります

## ３ークラスター（ECS）を作成し、タスクをデプロイ
クラスターを作成し、タスクをデプロイします。
ALBを作成してルーティングしてもOK