ALB

ALB Ccomponents

  • Lister: ポートを定義、リクエストを受ける
  • Litener Rule: パスなどのルール
  • Target Group: アクセスを仕分けされるグループ

HTTP用のロードバランサの作成

resource "aws_lb" "example" {
  name                       = "example"
  load_balancer_type         = "application"  <========= "network"を指定して、NLB(Network load balancer)も作れる
  internal                   = false <===== internet向けなのか、VPC内部向けなのかの指定
  idle_timeout               = 60 <==== タイムアウト
  enable_deletion_protection = true <====== 削除保護。本番では有効にスべし。

  subnets = [ <=========== サブネット。複数のAZのサブネットを指定して、クロスゾーン負荷分散ができる
    aws_subnet.public_0.id,
    aws_subnet.public_1.id,
  ]

  access_logs { <================= アクセスログ
    bucket  = aws_s3_bucket.alb_log.id
    enabled = true
  }

  security_groups = [ <================ セキュリティグルー府
    module.http_sg.security_group_id,
    module.https_sg.security_group_id,
    module.http_redirect_sg.security_group_id,
  ]
}

output "alb_dns_name" {
  value = aws_lb.example.dns_name
}

セキュリティーグループ

module "http_sg" {
  source      = "./security_group"
  name        = "http-sg"
  vpc_id      = aws_vpc.example.id
  port        = 80
  cidr_blocks = ["0.0.0.0/0"]
}

module "https_sg" {
  source      = "./security_group"
  name        = "https-sg"
  vpc_id      = aws_vpc.example.id
  port        = 443
  cidr_blocks = ["0.0.0.0/0"]
}

module "http_redirect_sg" {
  source      = "./security_group"
  name        = "http-redirect-sg"
  vpc_id      = aws_vpc.example.id
  port        = 8080
  cidr_blocks = ["0.0.0.0/0"]
}

リスナー

resource "aws_lb_listener" "http" {
  load_balancer_arn = aws_lb.example.arn
  port              = "80" 
  protocol          = "HTTP" <=========== サポートしているのはHTTP/HTTPS

  default_action { <=============== リスナーのルールに合致しない場合のアクション
    type = "fixed-response" <========= 固定のレスポンスを返す

    fixed_response {
      content_type = "text/plain"
      message_body = "This is HTTP"
      status_code  = "200"
    }
  }
}

Route 53

  • ドメイン購入後にやる
  • ホストゾーンの設定
data "aws_route53_zone" "example" {
  name = "example.com"
}

DNSレコード

resource "aws_route53_record" "example" {
  zone_id = data.aws_route53_zone.example.zone_id
  name    = data.aws_route53_zone.example.name
  type    = "A" <========== AWSの独自拡張のALISAレコード(Aレコードと同じ)

  alias {
    name                   = aws_lb.example.dns_name
    zone_id                = aws_lb.example.zone_id
    evaluate_target_health = true
  }
}

ACM (AWS Certificate Manager)

  • SSL Certificateを作成するためのACMの作成
resource "aws_acm_certificate" "example" {
  domain_name               = data.aws_route53_zone.example.name
  subject_alternative_names = []  <========== ここにドメイン名を追加する
  validation_method         = "DNS" <====== ドメインの所有権の検証

  lifecycle { <======== 新しいSSL証明書を作ってから古いSSL証明書と差し替える挙動に変更する
    create_before_destroy = true <===== 基本的にTFはデリートインサートだが、この設定でインサートデリートになる。ダウンタイムを回避できる
  }
}

SSL証明書の検証用DNSレコードの定義

resource "aws_route53_record" "example_certificate" {
  name    = aws_acm_certificate.example.domain_validation_options[0].resource_record_name
  type    = aws_acm_certificate.example.domain_validation_options[0].resource_record_type
  records = [aws_acm_certificate.example.domain_validation_options[0].resource_record_value]
  zone_id = data.aws_route53_zone.example.id
  ttl     = 60
}

 
resource "aws_acm_certificate_validation" "example" {
  certificate_arn         = aws_acm_certificate.example.arn
  validation_record_fqdns = [aws_route53_record.example_certificate.fqdn]
}

HTTPSのリスナー

resource "aws_lb_listener" "https" {
  load_balancer_arn = aws_lb.example.arn
  port              = "443"
  protocol          = "HTTPS"
  certificate_arn   = aws_acm_certificate.example.arn <============= ここでcertificateを指定する
  ssl_policy        = "ELBSecurityPolicy-2016-08" <============= これが推奨されている

  default_action {
    type = "fixed-response"

    fixed_response {
      content_type = "text/plain"
      message_body = "This is HTTPS"
      status_code  = "200"
    }
  }
}

HTTPリダイレクトするListener

resource "aws_lb_listener" "redirect_http_to_https" {
  load_balancer_arn = aws_lb.example.arn
  port              = "8080"
  protocol          = "HTTP"

  default_action {
    type = "redirect" <========= ここにredirectを設定するだけ

    redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301"
    }
  }
}

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

resource "aws_lb_target_group" "example" {
  name                 = "example"
  vpc_id               = aws_vpc.example.id <=== tareget_type==ipの時に必要
  target_type          = "ip" <================== EC2やIPアドレス、Lambda関数などを指定できる, ECS FargateではIPアドレスによるルーティング
  port                 = 80 <=== tareget_type==ipの時に必要
  protocol             = "HTTP" <=== tareget_type==ipの時に必要
  deregistration_delay = 300 <======= ターゲットを登録解除する前にALBが待機する時間, default=300

  health_check {
    path                = "/" <====== ヘルスチェックで使用するパス
    healthy_threshold   = 5 <========= 正常判定を行うまでの経するチェック実行回数
    unhealthy_threshold = 2 <========== 以上判定を行うまでのヘルスチェック実行回数
    timeout             = 5 <======= ヘルスチェックのタイムアウト時間(s)
    interval            = 30 <============ ヘルスチェックのインターバル(s)
    matcher             = 200 <====== 正常判定をするために使用するHTTPステータスコード
    port                = "traffic-port" <======= ヘルスチェックで使用するポート, traffic-portの場合は、上のprotocolが使用される
    protocol            = "HTTP" <======= ヘルスチェックで使用するプロトコル
  }

  depends_on = [aws_lb.example] <====== ECSサービスと同時起動でエラーになるため
}

リスナールールの作成

resource "aws_lb_listener_rule" "example" {
  listener_arn = aws_lb_listener.https.arn
  priority     = 100 <==== リスナールールの優先順位

  action { <===== フォワード先のターゲットグループを指定
    type             = "forward"
    target_group_arn = aws_lb_target_group.example.arn
  }

  condition { <========= これがルール
    field  = "path-pattern"
    values = ["/*"]
  }
}