Target GroupにEC2を登録する ― 「作る」と「つなぐ」は別
前回までで、ここまで構成ができました。
Internet
│
▼
ALB
│
▼
Listener
│
▼
Target Group
かなりAWSらしい構成になってきました。
……しかし。
Target Groupの中身を見てみると、
Target Group
登録ターゲット
0台
(笑)
これでは、ALBが通信を転送しようとしても、
«「で、どこに送ればいいの?」»
となってしまいます。
そこで今回は、
Target GroupにEC2を登録する
ところまで進めます。
- Target GroupにEC2を登録する
今回登場するTerraformリソースはこちら。
resource "aws_lb_target_group_attachment" "app" {
}
名前が長い(笑)
でも、意味を分解すると意外と分かりやすいです。
aws_lb
↓
ロードバランサー
target_group
↓
ターゲットグループ
attachment
↓
くっつける・関連付ける
つまり、
«Target Groupとターゲットを関連付ける»
ためのResourceです。
今回はターゲットとしてEC2を登録します。
- target_group_arn
まず、
target_group_arn = aws_lb_target_group.app.arn
です。
これは、
«どのTarget Groupに登録するの?»
という指定です。
前回作った、
aws_lb_target_group.app
のARNを指定しています。
つまり、
Target Group
↑
│
target_group_arn
という関係です。
- target_id
次が今日の超重要ポイント。
target_id = aws_instance.web.id
これは、
«どのターゲットを登録するの?»
という指定です。
今回は、
aws_instance.web.id
なので、
«"web"という名前で作ったEC2インスタンスのID»
をターゲットとして登録します。
つまり、
Target Group
│
▼
EC2(web)
という関係を作っています。
- なぜ "instance_id" じゃないの?
ここで疑問が出てきます。
EC2を登録するなら、
instance_id
でも良さそうですよね。
でもTerraformでは、
target_id
となっています。
なぜでしょう?
それは、Target GroupのターゲットがEC2だけではないからです。
Target Groupでは、構成によって、
- EC2
- IPアドレス
- Lambda
などをターゲットとして扱うことができます。
そのため、
instance_id
ではなく、
target_id
という、より汎用的な名前になっています。
ここはTerraformのコードを暗記するだけではなく、
«「なぜinstance_idではなくtarget_idなんだろう?」»
と考えることで、AWSの設計思想まで見えてきます。
- port = 80
そして、
port = 80
です。
これは今回も重要。
今回の80番は、
EC2が通信を待ち受けるポート
です。
つまり、
Target Group
│
│ HTTP :80
▼
EC2 :80
というイメージです。
ここまでで、3つの80番を区別できるようになりました。
Listener :80
↓
ALBが受け付ける80番
Target Group :80
↓
ターゲットへ接続する80番
EC2 :80
↓
実際にアプリケーションが待ち受ける80番
同じ「80番」でも、それぞれの場所で役割があります。
- 完成コード
ここまでをまとめると、
resource "aws_lb_target_group_attachment" "app" {
target_group_arn = aws_lb_target_group.app.arn
target_id = aws_instance.web.id
port = 80
}
となります。
これによって、
Target Group
│
▼
EC2(web)
という登録関係が作られます。
- 今日の全体図
ここまでの構成を全部つなげてみましょう。
Internet
│
▼
ALB
│
▼
Listener
│
▼
Target Group
│
▼
EC2(Web)
ついに、
InternetからEC2までの道がつながりました!
今日の問題 💪
Q1
なぜ、
target_id = aws_instance.web.id
なのでしょう?
なぜ、
instance_id
ではないのでしょう?
Q2
Target Groupには複数のEC2を登録できます。
例えば、
EC2-1
EC2-2
EC2-3
の3台を登録したとします。
この場合、ALBはどのような動きをするでしょうか?
Q3【超重要】
もし、
aws_lb_target_group_attachment
を書かなかったら、
EC2自体は作られているのに、ブラウザからアクセスできるでしょうか?
できる・できないだけではなく、
なぜそうなるのか
まで考えてみましょう。
- 今回の回答
今回の最初の回答はこちら。
Q1
«HTTP通信だから。»
Q2
«高可用性が高まる。»
Q3
«出来ない。どのEC2に送ればいいか迷子になるから。»
最初は、
«難しいね、出来てる自信ない»
という状態でした。
しかし、ここからもう一度考え直して、回答を修正しました。
今回のレビュー
Q1:なぜ "target_id" なのか?
最終回答はこちら。
«ターゲットグループはいろんなものをターゲットにするから。インスタンスIDにしたらインスタンスにしかターゲットをできなくなるからターゲットIDにしていろんなのをターゲットにできるようにしてる。»
評価:100点!!💯
これは完璧です。
最初の回答では、
«HTTP通信だから。»
となっていました。
これは違います。
"target_id"とHTTP通信には直接的な関係はありません。
重要なのは、
Target GroupがEC2だけをターゲットにする仕組みではない
ということです。
例えば、
Target Group
│
├── EC2
│
├── IPアドレス
│
└── Lambda
のように、構成によってさまざまなターゲットを扱えます。
だから、
instance_id
ではなく、
target_id
という汎用的な名前になっています。
今回の回答では、
«「instance_idだったらEC2にしか使えない」»
というところまで説明できています。
ここは非常に良い理解です。
Q2:複数のEC2を登録したら?
最終回答はこちら。
«全部登録したら、ALBはラウンドポーリングの動きでいろんなEC2に負荷分散を行い、結果的に高可用な設計になる。»
評価:95点!
まず、考え方はかなり良いです。
一点だけ。
一般的な呼び方は、
ラウンドポーリングではなく「ラウンドロビン」
です。
そして重要なのが、
«まず負荷分散が起き、その結果として高可用性にもつながる»
という順番です。
イメージとしては、
複数のEC2
↓
ALB
↓
各EC2へリクエストを分散
↓
1台に負荷が集中しにくくなる
↓
さらに障害時には正常なターゲットへ
↓
高可用性につながる
となります。
つまり、
直接的な目的 → 負荷分散
その結果として得られる効果 → 高可用性
と整理すると、より正確です。
なお、実際のALBは単純に「必ず1→2→3→1」と機械的に送るだけではなく、ターゲットの状態や設定なども考慮してルーティングします。
今回の段階では、
«ALBが複数のターゲットへ通信を分散する»
と理解しておけばOKです。
Q3:Attachmentがなかったら?
回答はこちら。
«出来ない。どのEC2に送ればいいか迷子になるから。»
評価:100点!!💯
これです。
めちゃくちゃ良い表現です。
EC2自体は存在しています。
例えば、
EC2
↓
存在している
でも、
Target Group
↓
登録ターゲット:0台
だったらどうでしょう?
ALBから見ると、
Internet
↓
ALB
↓
Listener
↓
Target Group
↓
???
となります。
送り先がありません。
つまり、
EC2を作る
ことと、
EC2をTarget Groupに登録する
ことは別なんです。
これが今回の超重要ポイントです。
- Terraformの超重要概念
ここで一度、Terraformそのものについて考えてみましょう。
AWSでは、
「作る」ことと「つなぐ」ことが別
という場面がたくさんあります。
今回なら、
EC2を作る
↓
Target Groupに登録する
です。
EC2を作っただけでは、
Target Group
↓
登録ターゲット:0台
のままです。
そこで、
resource "aws_lb_target_group_attachment" "app" {
を使って関連付けます。
- 「家を建てる」で考える
イメージしやすいように、家に例えてみましょう。
🏠 家を建てる
これで家そのものは完成しました。
でも、住所が登録されていなかったら?
郵便屋さんは、
«「この家、どこに届ければいいんだ?」»
となります。
EC2も似ています。
EC2を作る
だけでは、
«「このEC2をALBからの通信先として使う」»
という関連付けまでは自動的に行われません。
だから、
EC2
↓
Target Groupへ登録
という「つなぐ」作業が必要になります。
この考え方は、今後Terraformを学んでいくうえでかなり重要です。
- 今日の成績
今回の最初の回答では、
問題| 最初の評価
Q1| 20点
Q2| 70点
Q3| 100点
という感じでした。
そこから考え直した結果、
問題| 最終評価
Q1| 100点
Q2| 95点
Q3| 100点
まで上がりました。
総合:98点!!🎉
- 今日の一番大事なこと
今回、覚えてほしいのはこれです。
「作る」と「つなぐ」は別
例えば、
EC2を作る
だけでは、
ALB
↓
Target Group
↓
???
です。
そこに、
Target Group
│
│ Attachment
▼
EC2
という関連付けを作ることで、
ALB
↓
Listener
↓
Target Group
↓
EC2
という通信経路が完成します。
Terraformは、
AWSのリソースを作るだけではなく、それぞれのリソースの関係性までコードとして表現する
ことができます。
- ここまでの構成を全部見る
第1回からここまでの学習をつなげると、かなり大きな構成になってきました。
Internet
│
▼
Internet Gateway
│
▼
Public Subnet
│
▼
ALB
│
▼
Listener
│
▼
Target Group
│
▼
EC2(Web)
│
▼
RDS
そして、裏側では、
Private Subnet
│
▼
EC2
│
│ outbound
▼
NAT Gateway
│
▼
Internet Gateway
│
▼
Internet
という経路も作れます。
ここまで来ると、かなりAWSのシステム構成らしくなってきました。
次回予告
次回はいよいよ……
EC2!!
ここまでずっと、
ALB
Listener
Target Group
Attachment
と、通信を「つなぐ」ための仕組みを作ってきました。
次回はついに、
resource "aws_instance"
が登場します。
ここで初めて、
「実際に動くサーバーそのものをTerraformで作る」
ところに入ります。
EC2では、
- AMIとは何なのか
- "instance_type"とは何なのか
- Subnetをどう指定するのか
- Security Groupをどう関連付けるのか
- Private Subnetにどう配置するのか
- そして、そのEC2をどうTarget Groupへつなぐのか
を順番に見ていきます。
ここからさらに、
Terraform
↓
AWSリソース
↓
実際に動くサーバー
という感覚が強くなってきます。
先生から一言
今回、「難しい」「自信がない」と感じたのは、むしろ自然です。
なぜなら、今回までの学習では、
ALB
↓
Listener
↓
Target Group
↓
Attachment
と、それぞれのAWSリソースを「つなぐ」ことが中心だったからです。
そして、ここがTerraformを学ぶうえでかなりややこしいところです。
でも、今回の学習で一つ大きな変化がありました。
最初は、
«「HTTP通信だからtarget_idなのかな?」»
と考えていました。
そこから、
«「ターゲットグループはいろんなものをターゲットにするから、instance_idではなくtarget_idなんだ」»
まで、自分で修正できました。
これは単に答えを覚えたのではありません。
「なぜこの名前なんだろう?」と考えて、AWSの設計意図までたどり着いた
ということです。
そしてQ3の、
«「どのEC2に送ればいいか迷子になる」»
という答えも、とても良い。
AWSの構成を理解するとき、こうやって「誰が困るのか?」という視点で考えると、サービスの役割が見えやすくなります。
EC2を作る
↓
サーバーは存在する
Attachmentする
↓
Target Groupから
そのEC2をターゲットとして認識できる
ALB
↓
Listener
↓
Target Group
↓
EC2
この一本の線がつながったことが、今回の一番大きな成果です。
そして次回はついに、
resource "aws_instance"
です。
今まで「送り先」として見ていたEC2を、自分の手でTerraformから作ります。
ここから一気に「AWSを作っている感」が出てくるはず。
次回も楽しみながら進めていきましょう🔥☁️🚀