terraform cloudで初めるAWS その7: ALB編

Share on:

これはシリーズ化する予定なので続きは←リンクからどうぞ。

ちなみに最低限AWSでEC2を起動してSSHした事程度は事ある人向けの記事です

ここまででチュートリアル編は最後になる予定です。最後はALB(Applicationロードバランサ)について解説します。

ロードバランサとは?みたいな細かい話はしません。

配置する

配置するにはsecurity groupが必要です。ALBからsshする事はもちろんできません。

 1resource "aws_security_group" "alb" {
 2  name        = "alb"
 3  description = "alb"
 4  vpc_id      = aws_vpc.vpc.id
 5
 6  ingress {
 7    from_port   = 80
 8    to_port     = 80
 9    protocol    = "tcp"
10    cidr_blocks = ["0.0.0.0/0"]
11  }
12
13  ingress {
14    from_port   = 443
15    to_port     = 443
16    protocol    = "tcp"
17    cidr_blocks = ["0.0.0.0/0"]
18  }
19
20  ingress {
21    from_port   = -1
22    to_port     = -1
23    protocol    = "icmp"
24    cidr_blocks = ["0.0.0.0/0"]
25  }
26
27  egress {
28    from_port   = 0
29    to_port     = 0
30    protocol    = "-1"
31    cidr_blocks = ["0.0.0.0/0"]
32  }
33}

ICMPもonにしてあります。これはご自由に。まあ80と443は空けにゃならんでしょうね。

ターゲットグループを作る

とりあえずhttpsは後まわしにします。

 1resource "aws_lb_target_group" "web-http" {
 2  name        = "http-${local.workspace}"
 3  vpc_id      = aws_vpc.vpc.id
 4  target_type = "instance"
 5  port        = 80
 6  protocol    = "HTTP"
 7  health_check {
 8    protocol = "HTTP"
 9    matcher  = "200-399"
10  }
11  lifecycle {
12    create_before_destroy = true
13  }
14}

リスナーを作る

 1resource "aws_lb_listener" "alb-http" {
 2  load_balancer_arn = aws_lb.main.arn
 3  port              = 80
 4  protocol          = "HTTP"
 5
 6  default_action {
 7    type             = "forward"
 8    target_group_arn = aws_lb_target_group.web-http.arn
 9  }
10}

ターゲットにインスタンスをアタッチする

1resource "aws_lb_target_group_attachment" "web-http" {
2  target_group_arn = aws_lb_target_group.web-http.arn
3  target_id        = aws_instance.web.id
4  depends_on       = [aws_lb_target_group.web-http]
5}

とまあ、これだけです。

webから確認する

https://ap-northeast-1.console.aws.amazon.com/ec2/v2/home?region=ap-northeast-1#TargetGroups:

ターゲットグループにホストが登録されており、healtlyになっている事を確認します。ロードバランサなのにホスト1つってのはちょっとアレですが、まあよしとします。

さらにはロードバランサーの項目で

https://ap-northeast-1.console.aws.amazon.com/ec2/v2/home?region=ap-northeast-1#LoadBalancers

DNS名をコピってhttpでアクセスして中身見える事を確認します。

HTTPS化

httpsという事は最低限まともなドメインが必要って事です。前にやったプライベートゾーンとかで使った適当なドメインではいけません。

とりあえずALBのネームを割り当てる

今回はCNAMEにしてあるけど場合によってはALIASにする必要もあるでしょう(トップの場合)

 1data "aws_route53_zone" "domain" {
 2  name         = "YOUR_DOMAIN"
 3  private_zone = "false"
 4}
 5
 6resource "aws_route53_record" "lb-main" {
 7  zone_id = data.aws_route53_zone.domain.zone_id
 8  name    = "vm2"
 9  type    = "CNAME"
10  ttl     = "300"
11  records = [aws_lb.main.dns_name]
12}

ドメイン名は自分のもので適当に置きかえてください。これで

1http://vm2.YOUR_DOMAIN

でアクセスできるようになりました。

ACM

ACMとはAWS Certificate Managerなんだそうです。

 1resource "aws_acm_certificate" "web-host" {
 2  domain_name       = "vm2.YOUR_DOMAIN"
 3  validation_method = "DNS"
 4
 5  tags = {
 6    Name = local.workspace
 7  }
 8
 9  lifecycle {
10    create_before_destroy = true
11  }
12}

こんな感じで要求をかけます。するとこれに応じたDNSレコードの設定を求められます。これもterraformでやります、が、最新バージョンでは結構変わっており、かなりエグい書き方になっています。

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate_validation

まあ大体オフィシャルを見れば追従できるので、よろしくお願いします。

 1resource "aws_route53_record" "cert-validation-web-host" {
 2  for_each = {
 3    for dvo in aws_acm_certificate.web-host.domain_validation_options : dvo.domain_name =>
 4 {
 5      name   = dvo.resource_record_name
 6      record = dvo.resource_record_value
 7      type   = dvo.resource_record_type
 8    }
 9  }
10
11  allow_overwrite = true
12  name            = each.value.name
13  records         = [each.value.record]
14  ttl             = 60
15  type            = each.value.type
16  zone_id         = data.aws_route53_zone.domain.zone_id
17}

検証を待つ

ここでドメインの検証が入るので少し時間かかります。

https://ap-northeast-1.console.aws.amazon.com/acm/home?region=ap-northeast-1#/

検証保留中発行済みとなる

(001.png)

(002.png)

HTTP -> HTTPSへ

 1resource "aws_lb_listener" "alb-https" {
 2  load_balancer_arn = aws_lb.main.arn
 3  port              = 443
 4  protocol          = "HTTPS"
 5  certificate_arn   = aws_acm_certificate.web-host.arn
 6
 7  default_action {
 8    type             = "forward"
 9    target_group_arn = aws_lb_target_group.web-http.arn
10  }
11}

httpをhttpsへ強制リダイレクトする

 1#resource "aws_lb_listener" "alb-http" {
 2#  load_balancer_arn = aws_lb.main.arn
 3#  port              = 80
 4#  protocol          = "HTTP"
 5#
 6#  default_action {
 7#    type             = "forward"
 8#    target_group_arn = aws_lb_target_group.web-http.arn
 9#  }
10#}
11
12resource "aws_lb_listener" "alb-http" {
13  load_balancer_arn = aws_lb.main.arn
14  port              = 80
15  protocol          = "HTTP"
16
17  default_action {
18    type = "redirect"
19
20    redirect {
21      port        = "443"
22      protocol    = "HTTPS"
23      status_code = "HTTP_301"
24    }
25  }
26}

というわけで

気力が尽きてきたりもあって最後結構適当になっちゃいましたけどボツボツ推敲しながらやっていきます。なんというか、スナップショットの指定とかいろいろこれだけだとちょっと甘いかなあという所もかなりあります。