Amazon ECSに対応したAmazon VPC Latticeで自社製品コンテナ（HULFT10）を動かせるのか試してみた

この記事は [セゾンテクノロジー Advent Calendar 2024](https://qiita.com/advent-calendar/2024/saison-tech) シリーズ2　1日目の記事です。
シリーズ2は [HULFT10](https://www.hulft.com/software/hulft-10) のエンジニアによる投稿をお届けします。

# 初めに

先日AWSより以下の発表がありました。

[Amazon VPC Lattice が Amazon Elastic Container Service (Amazon ECS) のサポートを開始](https://aws.amazon.com/jp/about-aws/whats-new/2024/11/amazon-vpc-lattice-elastic-container-service/)

>ECS とのネイティブな統合により、ECS サービスを VPC Lattice ターゲットグループに直接関連付けることができるため、中間の Application Load Balancer (ALB) が不要になります。この合理化された統合により、コスト、運用上のオーバーヘッド、複雑さが軽減されると同時に、ECS と VPC Lattice の両方の完全な機能セットを活用できるようになります。

VPC Latticeを使用することでALBが不要になるということだったので、ALBを利用する前提で開発していたコンテナをALB無しで動かせるか気になったので試してみました。

# 利用するコンテナ

今回検証に使用するのは自社製品として開発している HULFT10 の HULFT10 for Container Services です。
[AWS Marketplace](https://aws.amazon.com/marketplace/pp/prodview-46o6kapgcvvey)で出品させていただいているファイル転送を行うコンテナ製品です。

提供しているCFnで導入した際の構成図は以下のようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/2408b797-0e6b-fe8e-0e45-36dcdebbca9c.png)

ECS on EC2 にアクセスするためのALBが2つ、NLBが１つあり、別VPCのEFSや製品間通信のためにVPC Peeringが行われています。

この構成で導入されているHULFT10をVPC Latticeを使用する形に変更して管理しやすくなるのかを検証します。

# VPC Latticeの導入

VPC Latticeについては右も左もわかりませんが、とりあえずVPC Latticeのページを開き、上から順に設定していってみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/d1693131-893c-ed77-85f0-94cd6a4fb539.png)

:::note warn
ターゲットグループの作成まで進んでから気づいたのですが、公式ブログに詳細な手順が記載されていました。
ECSサービスページからターゲットグループの登録をした後に、VPC Latticeページでサービスの作成、サービスネットワークの作成と進むのが良いようです。
https://aws.amazon.com/jp/blogs/aws/streamline-container-application-networking-with-native-amazon-ecs-support-in-amazon-vpc-lattice/

以下の記事は私がやったこと順で記載しています。ご了承ください。
:::

## サービスネットワークの設定

### 識別子

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/9748f328-6c66-57a4-4cae-def730607040.png)

分かりやすい名前を指定します。

### サービスの関連付け

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/58fd70f0-1751-fbf1-138b-8802103847b8.png)

まだサービスを作成していないので何も選択できません。おそらく後で設定できると思うので空のままにします。

### VPCの関連付け

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/7816be93-a09a-04f5-2f8a-5d15136607b9.png)

VPCの関連付けは、サービスを呼び出せるVPCを設定するようです。呼び出し対象になると思われるHULFT10導入VPCを指定してよいのかは微妙ですが、いったん指定見ることにします。
まだよくわかっていないのでセキュリティグループの設定はいったんそのままにしています。

### ネットワークアクセス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/d508649b-9853-9a4a-2954-057627fb66da.png)

IAM認証による認証を提供する設定を有効にします。
テンプレートから認証されたアクセスのみを許可としています。
ポリシーの記載内容からも、IAM認証さえされていればどのアカウントでも権限関係なくアクセスできそうです。

### Share service netowrk

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/ed3ebdff-ac06-76c6-0f25-728ea7e5caaf.png)

AWS Organizations 単位の共有が可能になるようです。今回は何も設定しません。

### モニタリング

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/88b85905-4fb5-ab11-0a55-8385574df85e.png)
トラフィックログを取得できるようです。今回はCloudWatchに出力する設定にしました。

### 概要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/47ffc23b-1eb2-f3a2-7f82-92b6846539af.png)

以上の内容で作成します。

## サービスの作成

### 識別子

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/12b8f0bf-9e60-7723-243b-18b04152e5a8.png)

### カスタムドメイン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/a728fdaf-5ca1-1463-e345-955dc894b542.png)

自動で生成されるドメインを使用することで、ドメインやACMの管理をせずにTLSを利用することができるようです。

### サービスアクセス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/79fa9a42-82d4-c694-b461-a8b4b2518f40.png)

説明を読むに、サービスネットワークの許可設定に加えて、サービス側でさらに厳しい許可設定を行うことができるようです。

### Share service、モニタリング

サービスネットワークの設定と同様のため省略

## ルーティングを定義

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/46084dcb-4ccd-934f-53c8-c6ae43ad56f9.png)

### リスナールールの追加

#### Rule identifiers

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/22d6fe8f-c68a-ba46-a9ec-e4c3aac5dd2d.png)

#### Rule Conditions

リクエストの割り振りを、メソッド、パス、ヘッダーから決めることができます。
全て一致するリクエストの時にターゲットグループに振り分けられるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/f7225aec-e803-02b8-0eb9-000cf14b2379.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/53dc8c33-4b1b-55ff-4aed-f8e8ca85726f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/b1ed47ea-c53a-3afd-214f-ac0ba2e91a76.png)

まだ選択できるターゲットグループがないので、404固定で保存します。

### リスナーのデフォルトアクション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/a3f67005-bb11-88ca-6a72-1afb9559244a.png)

上記で設定したリスナーのどれにも当てはまらなかった場合に返されるレスポンス。
500固定にします。

### HTTPS リスナー証明書の設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/0074d929-f7e2-b856-b955-9f3e3988848e.png)

サービスで生成されたDNSを利用しているため、証明書を設定する必要はありません。

## ネットワークの関連付けを作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/6d5443f2-2cac-8a7d-7825-63e536290dd2.png)

確認と作成を実施します。

## ターゲットグループの設定（失敗編）

:::note warn
ECSとの統合の場合、ターゲットグループの指定はECS側で行う必要があります。
以下はVPC Lattice側で設定しようとしてうまくいかなかった方法です。
:::

### グループの詳細の指定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/8ed1afdb-af40-40f8-c8a9-3782985c8b13.png)

まだ一つだけ翻訳されていないECS、EKSとの統合についての説明が記載されているIPアドレスタイプを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/5400f003-d00a-b759-7e21-991b812747b6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/6cd5bf3e-1509-b46f-6663-5af16f11bc85.png)


プロトコルはVPC LatticeがTLS終端を行う想定でHTTPです。
VPCにはサービスネットワークとして登録したものと同じVPCを指定します。
ここら辺の設定はALBのターゲットグループと変わりないです。

### ターゲットの登録

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/21fda6a8-b01b-e1c6-62a1-43bb13995b27.png)

想定ではここにECSコンテナのIPが表示されるはずなのですが困りました……
ALBへのターゲットグループ登録の際はALB側ではなくECS側からターゲットグループの設定を行うので、VPC Latticeでも同じように設定を行うものなのかもしれません。

## ターゲットグループの設定（成功編）

ECSから既存サービスの更新画面を開き、VPC Lattice設定のタブを開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/7cd288df-7adb-1d3e-24ee-b99063eb761d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/99bdf259-52d1-90b5-1a4e-c32bd519e937.png)


インフラストラクチャロールがなかったので、新しいインフラストラクチャロールを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/dd0f4192-ac8d-d875-b24f-dfda8636a30d.png)

ユースケースからサービスにECSを選ぶことで、VPC Lattice用の選択肢が表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/f516ace2-b269-79f3-357e-4fd93399f2c3.png)

ポリシーもECSで検索することで、VPC Lattice用のポリシーを見つけることができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/a4306205-7d17-c9ad-01bc-24182162d61e.png)

作成したインフラストラクチャロールをセットし、ターゲットグループの設定を行います。
ポート名の部分はタスク定義で定義されているものが表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/8a196ef4-86fe-5e20-eb77-29ffa1d2ab4a.png)

サービスページの「設定とネットワーク」に VPC Lattice についての項目が増えていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/bb039174-9b3e-4aac-0d86-30b7bb571f9c.png)

VPC Lattice のほうでもターゲットグループが設定されていることを確認できました。

### サービスへのターゲット登録

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/b78697cb-07e2-c493-7825-a4c77a275a00.png)

サービスのリスナールールで先ほど作成したターゲットグループを指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/7b4a938b-2970-75cb-d212-fb38673c21be.png)

ECSのページでも設定されていることを確認できました。

## セキュリティグループの設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/9c634eac-93d5-c31d-211d-aae1deb88cac.png)

ターゲットグループへのヘルスチェックがうまく行えていませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/db941c4a-6a48-3137-7349-65685dd07a28.png)

VPC Lattice からの接続をプレフィックスリストで許可します。
https://docs.aws.amazon.com/ja_jp/vpc-lattice/latest/ug/security-groups.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/18994aad-1fdc-7380-2422-12881fd82e72.png)

ヘルスチェックが正常になったことを確認できました。

## コンテナへの接続

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2997186/e50df2b6-3104-6d79-aa50-b6e7ffd5aa0c.png)

ローカルの端末からインターネット経由で接続できるのか、サービスのドメイン名を名前解決できるか試しましたが、解決することができませんでした。
VPC Latticeはサービスネットワークに登録されたVPCからサービスへの接続を管理するサービスのため、VPC内で使用されるDNSにのみ登録されるようです。
つまり、VPC Latticeの機能のみではパブリックなエンドポイントを作成することはできず、ALBやAPI Gatewayなどを経由する必要があるそうです。

初歩的な部分ですが知らなかったので、勉強になりました。
また、ここでやりたいことができないということが分かったので、今回の検証はここまでとしたいと思います。

## まとめ

VPC Lattice を実際に触ることで、今できること、今後に期待できることを整理することができました。
個人的に良いと思えたところ、まだ使えないと思えたところを以下に記載します。

### 良かったところ

- ドメインを用意しなくとも、サービス側でドメインを用意してくれてHTTPSによる接続を行うことができる
- VPC LatticeのリスナーとECSコンテナのルーティング設定をGUI上で簡単に行うことができた
- VPC Peeringをせずとも、複数VPC間での接続を行うことができる

### まだ使うのが難しいと思えたところ

- パブリックからVPC Lattice内のサービスに接続するためには別途プロキシとなるサービスが必要
    - 規模が大きいシステムに組み込む際は共通のエンドポイントを使用できるようになるためメリットとなるが、単一のシステムとして導入する際にはNLBやALBを使用することになるので、元の構成より冗長になる
- リスナーで対応しているプロトコルがまだ少ない
    - HULFTではWSS(WebSocketSecure)を利用しているため、ALB同様にWSSに対応しないと使用することが難しそうです
- TLS接続をサポートするにはカスタムドメインを利用する必要がある
    - HULFTではNLBによる接続も利用しているため、TLSを使用するリスナーも利用したかったのですが、リスナーでTLSタイプを使用するにはサービス作成時にカスタムドメインを指定する必要があり、メリットとして上げた独自ドメインを用意する必要がないというメリットを受けることができなくなります

### 感想

VPC Latticeというサービスを名前だけ知っている状態であったため、どのようなことができ、どのような設定項目があるのかを今回の検証で学ぶことができ良かったです。
現状では製品構成に組み込むのは難しいという結論になりましたが、AWSのサービスは進化が早いため数年後には現状の懸念点をすべて解決している可能性もあります。今後も継続して情報を追っていきたいと思います。