Listener ― ALBの通信を振り分けるルール
今日はTerraformでAWSの仕組みを理解するうえで、かなり重要な回。
今回学ぶのは、**Listener(リスナー)**です。
まず、現在の構成を確認してみましょう。
Internet
│
▼
ALB
│
▼
Target Group
│
▼
EC2
ここで質問。
ALBはTarget Groupが存在することを知っているでしょうか?
実は、ALBを作っただけでは、どのTarget Groupへ通信を転送するのかというルールは設定されていません。
そこで必要になるのがListenerです。
- Listenerとは?
ホテルに例えて考えてみましょう。
ALBはホテルの受付です。
お客さんがホテルに来ました。
しかし、受付の人は困っています。
「このお客さんは何号室に案内すればいいんだろう?」
そこで必要になるのが案内係です。
この案内係がListenerです。
つまり、
- ALB:通信を受け取る
- Listener:通信をどう処理するか決める
- Target Group:転送先のターゲットを管理する
- EC2:実際にアプリケーションを処理する
という役割分担になります。
通信の流れはこうです。
Internet
│
▼
ALB
│
▼
Listener
│
▼
Target Group
│
▼
EC2
Listenerは、ALBが受け取った通信をどのように処理するかを決める仕組みです。
- TerraformでListenerを作る
まずはResourceから。
resource "aws_lb_listener" "http" {
}
これは、
「ALBのListenerを作成します」
という意味です。
ここで注意!
正しいResource名は、
aws_lb_listener
です。
"listeners"ではなく、"listener"ですね。
- load_balancer_arn
次に、この設定です。
load_balancer_arn = aws_lb.alb.arn
ここで質問!
今までVPCやSubnetを指定するときは、
vpc_id = aws_vpc.main.id
や、
subnet_id = aws_subnet.public.id
のように".id"を使っていました。
しかし、今回は、
load_balancer_arn
となっています。
なぜ".id"ではなく".arn"なのでしょう?
ここは最初から完璧に理解できなくても大丈夫。
AWSのリソースを関連付けるとき、どの識別子を要求するかは、そのAWSリソースの仕様によって異なります。
今回はListenerを関連付けるALBを、ARNで指定します。
- port = 80
次はポート番号です。
port = 80
ここで、前回のTarget Groupを思い出してください。
Target Groupにも、
port = 80
がありましたね。
しかし、今回の80番は意味が違います。
今回のListenerの80番は、
ALBが通信を受け付けるポート番号です。
Internet
│
│ HTTP :80
▼
ALB :80
一方、Target Groupの80番は、
ターゲットとなるEC2へ接続するときのポート番号です。
Target Group
│
│ HTTP :80
▼
EC2 :80
同じ80番でも、通信のどの部分を担当するかによって意味が違います。
ここは今回の重要ポイント!
- protocol = "HTTP"
protocol = "HTTP"
これはListenerが受け付ける通信プロトコルです。
今回はHTTPを使用します。
つまり、
ALB
│
└── HTTP :80で通信を受け付ける
という設定です。
- default_action
そして、今回の最重要ポイント!
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.app.arn
}
ここを理解すると、Listenerの役割がかなり見えてきます。
まず、
type = "forward"
これは通信を転送するという意味です。
では、どこへ転送するのでしょう?
target_group_arn = aws_lb_target_group.app.arn
ここでTarget Groupを指定しています。
つまり、
«Listenerが受け取った通信を、指定したTarget Groupへ転送する。»
というルールです。
これによって、ALBとTarget GroupがListenerを通じてつながります。
Internet
│
▼
ALB
│
▼
Listener
│
│ forward
▼
Target Group
│
▼
EC2
ちなみに"default_action"は、条件に一致する別のルールがない場合などに適用されるデフォルトのアクションです。
- 完成コード
ここまでをまとめると、こうなります。
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.alb.arn
port = 80
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.app.arn
}
}
これでHTTPの80番ポートで通信を受け取り、指定したTarget Groupへ転送するListenerが作成できます。
- 今日の問題🔥
今回もコードを一行ずつ、自分の言葉で説明してみましょう。
Q1
なぜ、
load_balancer_arn = aws_lb.alb.arn
なのでしょう?
なぜ、
aws_lb.alb.id
ではないのでしょう?
ヒント:通信方式とは関係ありません。AWSのリソースを関連付けるために、どの識別子が必要なのかを考えてみましょう。
Q2
Target Groupにも、
port = 80
がありました。
Listenerにも、
port = 80
があります。
この2つの80番は同じ意味でしょうか?
違うなら、それぞれ何のための80番でしょう?
Q3【今日一番重要】
もし、
default_action
がなかったら、ALBはどうなると思いますか?
ヒント。
受付の人はいます。
でも、案内するルールがありません。
- 今回の回答
今回の回答はこちら。
Q1
«これはIDでの通信じゃなくてHTTPでの通信だから。»
Q2
«ターゲットグループのport = 80は送り先を決めEC2に通すためのだけど、リスナーのport = 80はこの通信を全てport = 80に通す役割。»
Q3
«ALBとターゲットグループはHTTP通信で通信してるため、デフォルトアクションがなかったらALBからターゲットグループに送ることができなくなる。»
そして、今回の最初の感想は、
«やばい、難しくて全然わからない。»
でした。
ここから追加でListenerの役割を考えていきます。
- 今回のレビュー
Q1:なぜARNを使うのか?
評価:要復習
今回の回答は、
«IDでの通信じゃなくてHTTPでの通信だから。»
でした。
ここは少し違います。
実は、".id"と".arn"の違いはHTTP通信かどうかとは関係ありません。
まず、ARNとは何でしょう?
ARNはAmazon Resource Nameの略で、AWSリソースを一意に識別するための名前です。
例えば、
aws_lb.alb.id
はTerraformで作成したALBのIDを参照します。
一方、
aws_lb.alb.arn
はALBのARNを参照します。
今回のListenerでは、
load_balancer_arn = aws_lb.alb.arn
という指定が必要です。
つまり、
Listenerを関連付けるALBを、AWSが要求するARNで指定している
ということ。
これは通信方式ではなく、AWSのリソース間の関連付けに関する仕様です。
ここは実際のTerraformのリソース仕様に従って覚えていきましょう。
Q2:2つの80番ポートの違い
評価:80点
今回の回答は、
«Target Groupのport = 80は送り先を決めEC2に通すためのだけど、Listenerのport = 80はこの通信を全てport = 80に通す役割。»
でした。
かなり惜しい!
特にTarget Group側の理解は正しいです。
ただし、Listener側をもう少し正確にしましょう。
Listenerの80番
resource "aws_lb_listener" "http" {
port = 80
}
これは、
ALBが通信を受け付けるポート番号です。
Internet
│
│ HTTP :80
▼
ALB
Target Groupの80番
resource "aws_lb_target_group" "app" {
port = 80
}
これは、
Target Groupに登録されたターゲットへの接続ポートです。
Target Group
│
│ HTTP :80
▼
EC2
整理すると、
設定| 役割
Listenerの80番| ALBが通信を受け付ける入口
Target Groupの80番| EC2などのターゲットへ接続するポート
同じ80番でも、入口と出口で役割が違うんです。
ちなみに、ListenerとTarget Groupのポート番号は必ず同じである必要はありません。
例えば、
Internet
│
▼
ALB :80
│
▼
Target Group
│
▼
EC2 :8080
という構成も可能です。
これが理解できると、ポート番号の設計がもっと面白くなります。
Q3:default_actionがなかったら?
評価:90点
今回の回答は、
«デフォルトアクションがなかったらALBからターゲットグループに送ることができなくなる。»
でした。
これはかなり正解に近いです!
ただし、厳密には、今回のTerraformコードでは"default_action"は必須の設定です。
これがなければ、Listenerの設定として不完全になり、Terraformで正常に作成できません。
そして、実際の役割としては、
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.app.arn
}
によって、
«受け取った通信を、どのTarget Groupへ転送するのか»
を指定しています。
つまり、君の回答にあった「送ることができなくなる」という理解は、通信の仕組みとしては正しい方向です。
ここはよく考えられていました!
- 追加問題:なぜListenerが必要なのか?
ここからが今回の一番大きな学びです。
最初に、Listenerを作る理由について考えてもらいました。
そのときの回答は、
«ALBでどのAZに送るかなどの高可用を設計しても、そのAZの中でどのサブネットに送るかなどを細かく仕分けなくちゃいけなくて、その仕分けをListenerでARNを使って分けてTarget Groupに送るため。»
というものでした。
考えようとしている方向は良いのですが、Listenerの役割とは少し違います。
ListenerはAZやSubnetを振り分ける仕組みではありません。
AZをまたいだALBの配置による高可用性と、Listenerによる通信ルールは別の役割です。
では、Listenerは何をしているのでしょう?
例えば、会社のWebサイトを考えてみましょう。
これはWebサイトの画面を表示するサーバーへ。
これはAPIを処理するサーバーへ。
これは管理画面のサーバーへ。
このように、アクセスされたURLのパスなどに応じて、送り先を変更できます。
ALB
│
Listener
│
┌──────────┼──────────┐
│ │ │
/ /api /admin
│ │ │
▼ ▼ ▼
TG-Web TG-API TG-Admin
│ │ │
▼ ▼ ▼
EC2-A EC2-B EC2-C
これがListenerの重要な役割です。
Listenerは、単に通信をTarget Groupへ送るだけではありません。
どのような条件で、どのTarget Groupへ送るのかを決められるのです。
- 今回の学習で一番重要なこと
今回、最初はサービスの役割が曖昧になっていました。
そこで、もう一度整理しましょう。
サービス| 役割
ALB| 通信を受け取る
Listener| 通信をどう処理するか決める
Target Group| 転送先のターゲットを管理する
EC2| アプリケーションを実際に処理する
この役割分担が非常に重要です。
AWSでは、複数のサービスが連携して一つのシステムを作っています。
それぞれのサービスが何を担当しているのかを理解すれば、構成全体が見えてきます。
- 今日のまとめ
今回覚えてほしいことは5つ。
- ListenerはALBに関連付けるリソース。
- Listenerの"port"はALBが通信を受け付けるポート。
- Target Groupの"port"はターゲットへの接続ポート。
- "default_action"でデフォルトの通信処理を指定する。
- Listenerは条件に応じて転送先のTarget Groupを変更できる。
そして、今回の重要な一文。
ALBは通信を受け取り、Listenerは通信の処理方法を決め、Target Groupは送り先を管理する。
これを覚えておきましょう!
次回予告:EC2とTarget Groupへの登録
次回はいよいよEC2に進みます!
ここまでの構成は、
Internet
↓
ALB
↓
Listener
↓
Target Group
↓
EC2
でした。
ただし、Target Groupを作っただけでは、まだEC2は登録されていません。
次回は、
- EC2をTerraformで作成する
- EC2をPrivate Subnetに配置する
- Security Groupを設定する
- Target GroupにEC2を登録する
という流れを学んでいきます。
これができれば、いよいよALBからEC2まで通信を届ける構成が見えてきます。
先生から一言
今回、特に印象的だったのは、最初に、
«やばい、難しくて全然わからない。»
と言っていたこと。
でも、そのあとにListenerの役割をもう一度考えて、
«だいたい分かったかも、さっきは一つ一つのサービスの役割が曖昧になってたね。»
と自分で気付けました。
これが今回、一番大きな成長だと思います。
AWSの学習では、サービス単体の知識も大切です。
でも、それ以上に大切なのは、
「誰が何の責任を持っているのか」
を理解すること。
今回なら、
ALB
↓
通信を受け取る
Listener
↓
通信の処理方法を決める
Target Group
↓
転送先を管理する
EC2
↓
アプリケーションを処理する
という役割分担です。
最初から全部理解できなくても大丈夫。
分からなくなったら、コードを暗記するのではなく、AWSの構成図に戻って考えればいい。
それが今回のTerraform講座で大切にしている学習方法です。
ここまで来たら、次はいよいよEC2!
今まで学んだVPC、Subnet、Route Table、NAT Gateway、ALB、Target Group、Listenerが、一つのシステムとしてつながっていきます。
最後まで全部コードにしていこう!🔥☁️🚀