ソースに絡まるエスカルゴ

貧弱プログラマの外部記憶装置です。

【AWS/Terraform】ALBやNLBのポートと証明書の設定について

 ALBやNLBをTerraformで作成する際、ターゲットグループ、アタッチメント、リスナーでポートやプロトコルが複数出てきてどれがどう扱われるのかかなり混乱することがありました。

 なので今回はその辺りのポートやプロトコル、証明書についてまとめた内容になります。


 では、始めます。


1:ALBやNLBのTerraformコード例
 TerraformでALBやNLBを作成するコードを書くと、基本的には以下のようになるかと思います。このまま単体ではデプロイできないのであくまで各設定値がどうなっているかの例として挙げているので注意してください。

# LB本体
resource "aws_lb" "example_lb" {
  name               = "ecample-alb"
  internal           = true
  load_balancer_type = "application" # NLBの場合はnetworkを設定
  security_groups    = [aws_security_group.lb_sg.id]
  subnets            = [aws_subnet.subnet1.id, aws_subnet.subnet2.id]
}

# LBターゲットグループ
resource "aws_lb_target_group" "example_tg" {
  name     = "example-tg"
  port     = 80
  protocol = "HTTP" # ALBの場合はHTTP or HTTPS、NLBの場合はTCP or TLSなどを設定
  vpc_id   = aws_vpc.main.id
}

# LBターゲットグループアタッチメント
resource "aws_lb_target_group_attachment" "example_tg_attachment" {
  target_group_arn = aws_lb_target_group.example_tg.arn
  target_id        = aws_instance.example_ec2.id
  port             = 8000
}

# LBリスナー
resource "aws_lb_listener" "alb_listener" {
  load_balancer_arn = aws_lb.example_lb.arn
  protocol          = "HTTPS" # ALBの場合はHTTP or HTTPS、NLBの場合はTCP or TLSなどを設定
  port              = "443"

  # 証明書が必要な場合は以下を設定
  ssl_policy        = "ELBSecurityPolicy-2016-08"
  certificate_arn   = "arn:aws:iam::123456789:server-certificate/test_cert"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.example_tg.arn
  }
}

 protocolの設定がaws_lb_target_groupにもaws_lb_listenerにもあり、portの設定ではaws_lb_target_groupにもaws_lb_target_group_attachmentにもaws_lb_listenerにもあるのがわかると思います。

 これらについてどう使われるかを次に説明します。
 

2:ALBやNLBのポートと証明書の扱い
 例えば以下のように通信する場合を考えます。

EC2 → ALB → Fargate

 この時、それぞれ以下のようになります。

・ポートの扱い

通信経路 説明
EC2 → ALB リスナーで設定したポートのみ受け付ける。
ALB → Fargate アタッチメントのポートでターゲットに送信。アタッチメントのポートが設定されてない場合はターゲットグループのポートでターゲットに送信。

プロトコルや証明書の扱い

通信経路 説明
EC2 → ALB リスナーで設定したプロトコルで受け付ける。リスナーで設定した証明書を使用。
ALB → Fargate ターゲットグループで設定したプロトコルでターゲットに送信。証明書はターゲット側を使用。

 つまり、リスナーでプロトコルとポートと証明書を設定した場合はそのプロトコルとポート番号とリスナーに設定された証明書でリクエストを受け付けます。そしてターゲットに送信する際にはリスナーに設定した証明書は使わずに「ターゲット側の証明書を使用」して「アタッチメントのポートで上書きされたポート」で送信されるということになります。
 アタッチメントのポートが設定されていない場合は、ターゲットグループのポートで送信されます。

 なので1に挙げた例を考えると、以下のようになります。

  • 受付はポート443のHTTPSでリスナーに設定した証明書を使用
  • 送信はアタッチメントのポート8000が使用され、HTTPで送信される(HTTPなので証明書はなし)

 また1のアタッチメントを削除してターゲットグループのprotocolをHTTPS、portを443とすると以下のようになります。

  • 受付はポート443のHTTPSでリスナーに設定した証明書を使用
  • 送信はターゲットグループのポート443を使用したHTTPSで送信され、ターゲット側の証明書を使用


 以上がAWSにおけるALBやNLBのポートと証明書の設定についてになります。

 わかっている人からすると当然な内容かもしれませんが、インフラにもAWSにも不慣れな自分としてはかなり混乱して何をどう設定すればいいのかがわからない時があったのでまとめた次第です。
 同じように混乱している人の助けになれば幸いです。


・参考資料