TerraformでALBを作成する

# はじめに

この記事の続きです。今回はALBを作成します。
[TerraformでEC2、セキュリティグループを作成する](https://qiita.com/gogo-muscle/items/7e3e4b3bf99366a665ee)

以下がディレクトリ構成です。

~~~shell
% tree                                                                                              +[master]
.
├── README.md
├── main.tf
├── modules ＃追記
│   ├── alb
│   │   ├── Create-alb.tf　＃作成
│   │   ├── outputs.tf　　　＃作成
│   │   └── variables.tf　　＃作成
│   ├── ec2
│   │   ├── Create-ec2.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   ├── rds
│   │   ├── Create-rds.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   ├── security_group
│   │   ├── Create-securitygroup.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   └── vpc
│       ├── Create-vpc.tf
│       ├── outputs.tf
│       └── variables.tf
├── outputs.tf
├── terraform.tfstate
├── terraform.tfstate.backup
└── variables.tf
~~~

# コードの作成

## main.tfにモジュールの利用を宣言

main.tfにて、alb用のセキュリティグループの作成、ALBの作成を行います。
セキュリティグループは前回作成したものを再利用。
ALBのパラメータは他モジュールからのinputや変わりそうなパラメータだけ抜き出しています。
`terrarform destroy`で簡単に削除できる様に、`enable_deletion_protection = false`にしています。

~~~~terraform:./main.tf

########以下を追記########

module lb-sg {
  source = "./modules/security_group"

  sg_config = {
    name        = "lb-sg"
    vpc_id      = module.vpc.vpc_id
    protocol    = "tcp"
    port        = [80, 443]
    cidr_blocks = ["0.0.0.0/0"]
  }
}

module lb {
  source = "./modules/alb"

  lb_base_config = {
    public_subnet_id           = module.vpc.public_subnet_id
    sg_id                      = module.lb-sg.sg_id
    NameTag                    = "Terraform"
    enable_deletion_protection = false
  }
  lb_target_config = {
    port        = 80
    protocol    = "HTTP"
    vpc_id      = module.vpc.vpc_id
    path        = "/"
    instance_id = module.ec2.instance_id
  }
}
~~~

## 変数のinput

`module`で定義した変数を読み込みます。
セキュリティグループは前回の記事でinputしているので行う必要は無いです。

~~~terraform:./modules/alb/valiables.tf
variable "lb_base_config" {
  type = object({
    public_subnet_id           = list(string)
    sg_id                      = string
    NameTag                    = string
    enable_deletion_protection = string
  })
}
variable "lb_target_config" {
  type = object({
    port        = string
    protocol    = string
    vpc_id      = string
    path        = string
    instance_id = any
  })
}
~~~


## ALBの作成

health_checkの数値など一部ハードコートされてますが、この辺は変数化するなりすれば良いでしょう。
でも、あんまり変数化しすぎると訳がわからなくなります。。
`aws_lb_target_group_attachment`については、`target_id`がインスタンスIDのリストを受け入れてくれなかったので`count`方式にしています。

~~~terraform./modules/alb/Create-alb.tf
resource "aws_lb" "mylb" {
  name                       = var.lb_base_config.NameTag
  load_balancer_type         = "application"
  internal                   = false
  idle_timeout               = 60
  enable_deletion_protection = var.lb_base_config.enable_deletion_protection

  subnets = var.lb_base_config.public_subnet_id
}

resource "aws_lb_target_group" "myapp" {
  name                 = var.lb_base_config.NameTag
  port                 = var.lb_target_config.port
  protocol             = var.lb_target_config.protocol
  vpc_id               = var.lb_target_config.vpc_id
  deregistration_delay = "10"

  health_check {
    protocol            = var.lb_target_config.protocol
    path                = var.lb_target_config.path
    port                = var.lb_target_config.port
    healthy_threshold   = 5
    unhealthy_threshold = 2
    timeout             = 5
    interval            = 10
    matcher             = 200
  }
}

resource "aws_alb_listener" "myapp-http" {
  load_balancer_arn = aws_lb.mylb.arn
  port              = "80"
  protocol          = "HTTP"

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

resource "aws_lb_target_group_attachment" "myinstance" {
  count = length(var.lb_target_config.instance_id)
  target_group_arn = aws_lb_target_group.myapp.arn
  target_id        = element(var.lb_target_config.instance_id, count.index % length(var.lb_target_config.instance_id))
  port             = 80
}
~~~

## output

あとでわかりやすい様にALBのDNS名をoutputします。

~~~terraform./modules/alb/outputs.tf
output "alb_dns_name" {
  value = aws_lb.mylb.dns_name
}
~~~