Version
required_providers {
aws = {
source = "hashicorp/aws"
version = "4.59.0"
}
}
ALBにはAvailability Zoneが2つ必要
ALBにはAvailability Zoneが2つ必要である。
Availability Zoneを1つにしてALBを作ろうとすると次のようなエラーが出る。
│ Error: creating ELBv2 application Load Balancer (alb-qiita-production-alb): ValidationError: At least two subnets in two different Availability Zones must be specified
│ status code: 400, request id: 94fc711b-2ad0-4161-a15b-f0e65488f099
│
│ with aws_lb.application_load_balancer,
│ on alb.tf line 1, in resource "aws_lb" "application_load_balancer":
│ 1: resource "aws_lb" "application_load_balancer" {
しかし、可用性が低くても問題にならないサービスでは、Availability Zoneもサブネットも1つで運用したいときがある。
そのようなときには、ALBに何も存在しないダミーサブネットを設定すればよい。
VPCなど
variablesなど省略している部分がある。
resource "aws_vpc" "aws_vpc" {
cidr_block = "10.10.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "${var.product_name}-vpc"
Environment = var.app_environment
}
}
resource "aws_internet_gateway" "aws_igw" {
vpc_id = aws_vpc.aws_vpc.id
tags = {
Name = "${var.product_name}-igw"
Environment = var.app_environment
}
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.aws_vpc.id
cidr_block = var.public_subnet
availability_zone = var.availability_zone
map_public_ip_on_launch = true
tags = {
Name = "${var.product_name}-public-subnet"
Environment = var.app_environment
}
}
# ダミーサブネットを定義
resource "aws_subnet" "public_dummy" {
vpc_id = aws_vpc.aws_vpc.id
cidr_block = var.public_dummy_subnet
availability_zone = var.availability_zone_dummy
map_public_ip_on_launch = true
tags = {
Name = "${var.product_name}-public-dummy-subnet"
Environment = var.app_environment
}
}
resource "aws_route_table" "public" {
vpc_id = aws_vpc.aws_vpc.id
tags = {
Name = "${var.product_name}-routing-table-public"
Environment = var.app_environment
}
}
resource "aws_route" "public" {
route_table_id = aws_route_table.public.id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.aws_igw.id
}
resource "aws_route_table_association" "public" {
subnet_id = aws_subnet.public.id
route_table_id = aws_route_table.public.id
}
# 必ずダミーサブネットもinternet gatewayに接続!!
resource "aws_route_table_association" "public_dummy" {
subnet_id = aws_subnet.public_dummy.id
route_table_id = aws_route_table.public.id
}
ALB
variablesなど省略している部分がある。
resource "aws_lb" "application_load_balancer" {
name = "${var.product_name}-${var.app_environment}-alb"
internal = false
load_balancer_type = "application"
# サブネットにサービスのあるパブリックサブネットとダミーサブネットを指定
subnets = [aws_subnet.public.id, aws_subnet.public_dummy.id]
security_groups = [aws_security_group.load_balancer_security_group.id]
tags = {
Name = "${var.product_name}-alb"
Environment = var.app_environment
}
}
resource "aws_security_group" "load_balancer_security_group" {
vpc_id = aws_vpc.aws_vpc.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Name = "${var.product_name}-sg"
Environment = var.app_environment
}
}
resource "aws_lb_target_group" "target_group" {
name = "${var.product_name}-${var.app_environment}-tg"
port = 8080
protocol = "HTTP"
target_type = "ip"
vpc_id = aws_vpc.aws_vpc.id
health_check {
interval = 30
path = "/health"
port = 8080
protocol = "HTTP"
timeout = 5
unhealthy_threshold = 2
matcher = 200
}
tags = {
Name = "${var.product_name}-lb-tg"
Environment = var.app_environment
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_lb_listener" "listener" {
load_balancer_arn = aws_lb.application_load_balancer.id
port = "80"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.target_group.id
}
}
詰まりやすいところ
ここで重要なのは、ALBに設定するサブネットは2つともパブリックサブネットでなければならないという点である。
google chrome - AWS Elastic Load Balancing: Seeing extremely long initial connection time - Stack Overflow
つまり、何も存在しないサブネットだとしても、ダミーサブネットはinternet gatewayに接続されていなければならない。
必ずダミーサブネットにもaws_route_table_association
を指定しよう。
これをしなければInitial Connect
に1分から2分程度かかることになる。