既存のECS(Fargate)にALBを追加してみる

既存のECS(Fargate)にALBを設定する手順を紹介します。マネジメントコンソールからはできないので、AWS CLIを使って設定します。
2023.03.03

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ECS(Fargate)でとりあえずタスクを立ち上げて使えるようにしてみたけど、本当はALBを前段に置いてバランシングしたいんだよねぇ。なんてことはありませんか?

ようするに今タスクIP直アクセスして使ってるやつを、こう変えたいみたいなことです。

マネジメントコンソールから変更しようと思うと、一見できなさそうに見えますが、ドキュメントにAWS CLIまたはSDKを使用してロードバランサーの設定変更できる旨が記載されています。

AWS CLI または SDK を使用して、ロードバランサーの設定を変更します。設定の変更方法の詳細については、「Amazon Elastic Containers サービス API リファレンス」の UpdateService を参照してください。

このロードバランサーの設定変更をやってみたので、その手順を紹介します。

とりあえずCLIコマンド

AWS CLIのコマンドさえ教えてもらえばなんとなくわかるよ。ってかたはこちらをどうぞ。

$ CLUSTER=<<ECS(Fargate)のクラスター名>>
$ SERVICE=<<ECS(Fargate)のサービス名>>
$ TARGET_GROUP_ARN=<<ターゲットグループのARN>>
$ CONTAINER_NAME=<<接続したいタスク定義のコンテナ名>>
$ aws ecs update-service \
  --cluster ${CLUSTER} \
  --service ${SERVICE} \
  --load-balancers targetGroupArn=${TARGET_GROUP_ARN},containerName=${CONTAINER_NAME},containerPort=80

ここから、もうちょっと詳しく説明します。

現状の説明

Fargateの場合、すべてのECSタスクにENI(Elastic Network Interface)が提供されます。パブリックサブネットを使用する場合には、パブリックIPを割り当てることもでき、とりあえず動かしてみたいなんて時にはこんな風にパブリックIPで直接アクセスすることができます。

ただ、このアクセスの方法ではタスクが増えた時にスケールしていかないので前段にALBを置いて各タスクへバランシングしたい、みたいな状況です。

ALBを作成する

まずは、マネジメントコンソールから、ALBを作成します。

ターゲットグループの作成

ALBの接続先設定となるターゲットグループを作成します。

ターゲットタイプは IPアドレス を選択します。ターゲットグループ名は適当につけます。プロトコルは HTTP80 とします。

VPCはFargateを動かしているVPCと同じVPCを選択します。ヘルスチェックは環境に合わせて設定してください。

IPアドレスの設定は不要です。ターゲットグループの作成をしてください。 ECSにALBを設定した時に、自動でタスクのIPアドレスを登録してくれます。

作成したターゲットグループのARNはメモしておいてください。ECSにALBを設定する時に使います。

ALBの作成

ターゲットグループが作成できたらALBを作成します。

ロードバランサー名は適当につけます。スキームを インターネット向け にして、IPアドレスタイプを IPv4 にします。

VPCはFargateを動かしているVPCと同じVPCを選択します。サブネットはパブリックサブネットを指定します。

HTTP接続可能なセキュリティグループをあらかじめ作っておきます。なければ新しいセキュリティグループを作成してください。 リスナーのデフォルトアクションに先程作成したターゲットグループを設定します。

設定できたら概要を確認して、ロードバランサーの作成をしてください。

これでALBの作成は完了です。

ECSサービスのセキュリティグループを更新する

ECSタスクのENIに付与されるセキュリティグループは、ECSサービスで定義されています。 ECSサービスのセキュリティグループを更新して、ALBからアクセスできるようにします。

ECSサービスのセキュリティグループのインバウンドルールを編集して、 ALBに設定したセキュリティグループからHTTPでの接続許可を追加します。

タスク定義のポートマッピングを設定する

タスクのパブリックIPへ直接アクセスしている場合、タスク定義でポートマッピングを設定しなくてもセキュリティグループで許可されていれば接続できます。 ECSにALBを設定する場合は、タスク定義でポートマッピングの設定が必要です。

ちなみに、タスク定義のポートマッピングを設定せずにALBを設定しようとすると、次のようなポートが定義されていませんといったエラーが発生します。

An error occurred (InvalidParameterException) when calling the UpdateService operation: The container web did not have a container port 80 defined.

タスク定義から新しいリビジョンを作成して、ポートマッピングの設定をします。

コンテナのポートに80(HTTP)を追加して保存します。

ECSサービスの更新

タスク定義を新しくしたので、ECSサービスを更新して最新のタスク定義のタスクが実行されるよう、ECSサービスを更新します。

タスク定義のリビジョンを最新にして更新します。

そうすると、最新のタスクが起動してきます。

AWS CLIでECSのALB設定を更新する

ここまで準備ができれば、次のコマンドを実行するとALB設定を更新できます。

$ CLUSTER=<<ECS(Fargate)のクラスター名>>
$ SERVICE=<<ECS(Fargate)のサービス名>>
$ TARGET_GROUP_ARN=<<作成したターゲットグループのARN>>
$ CONTAINER_NAME=<<タスク定義のコンテナ名>>
$ aws ecs update-service \
  --cluster ${CLUSTER} \
  --service ${SERVICE} \
  --load-balancers targetGroupArn=${TARGET_GROUP_ARN},containerName=${CONTAINER_NAME},containerPort=80

実行後、マネジメントコンソールを確認するとECSにALBが登録されていることが確認できます。

ALBのDNS名でもアクセスして、問題なく表示できることも確認できました。

おわりに

マネジメントコンソールからECSのALB追加ができないので、後から変更できないように見えるのですが、AWS CLIを利用することで後から変更することもできます。 ECSクラスター作り直すより早くできると思うので、ぜひご活用ください。