본 포스트는, Terraform Up & Running 테라폼 - OREILLY를 참고했습니다.
이번 포스트에서는 Terraform을 이용해서 AutoScale group을 만들고, 이를 연결해주는 Application Loadbalancer를 생성하려고 합니다.
이전 단계에서 사용했던 내용보다 조금 더 깊이 들어가서 따라가기 힘드니, 천천히 따라와 주세요.. ( 절대 제가 힘들어서 그런게 아닙니다. )
data
이전에서 var, output을 사용했다면, 이번에는 data 입니다.
data는 기존에 있는 리소스의 정보를 가져온다고 생각하면 됩니다.
data "aws_vpc" "default" {
default = true
}
위와 같이, 설정하면 default로 설정한 vpc의 정보를 가져오게 됩니다.
이를 terraform에 적용해서 terraform으로 생성한 리소스처럼 사용할 수 있게 됩니다.
data "aws_subnet_ids" "default" {
vpc_id = data.aws_vpc.default.id
}
이번 포스트에서는 2개의 data를 사용합니다.
하나는 vpc, 다른 하나는 vpc에 생성되어 있는 subnet정보입니다.
launch_configuration 정의하기
Launch_configuration은 생성될 ec2에 대한 정의입니다.
resource "aws_launch_configuration" "example" {
image_id = "ami-0ea5eb4b05645aa8a"
instance_type = "t3.nano"
security_groups = [aws_security_group.instance.id]
user_data = <<-EOF
#!/bin/bash
echo "Hello, world" > index.html
nohup busybox httpd -f -p 8080 &
EOF
lifecycle {
create_before_destroy = true
}
}
기존에 정의했던 ec2에서 lifecycle이 추가되는데, 이는 lifecycle을 위와 같이 설정하지 않을 경우, 생성되어있는 리소스에 대한 참조가 있기 때문에 리소스를 수정, 삭제 할 수 없습니다.
이를 방지 하기 위해 lifecycle을 설정해서 삭제가능하게 합니다.
autoscaling_group 정의하기
resource "aws_autoscaling_group" "example" {
min_size = 2
max_size = 10
launch_configuration = aws_launch_configuration.example.name
vpc_zone_identifier = data.aws_subnet_ids.default.ids
target_group_arns = [aws_lb_target_group.asg.arn]
health_check_type = "ELB"
tag {
key = "Name"
value = "terraform-asg-example"
propagate_at_launch = true
}
}
위에서 설정한 launch_configuration을 이용해서 autoscaling_group을 생성합니다.
최소 사이즈와 최대 사이즈를 설정하고 data를 통해 받아온 vpc_zone_identifier를 설정합니다.
여기서 vpc의 subnet은 서로 다른 두개의 가용지역으로 구성되어야 합니다. (만약 2개 이상의 subnet이 없다면 생성해주세요)
target_group_arns 이라는게 있는데, 이는 이후에 생성하게 될 loadbalancer의 arn입니다.
arn이란 Amazon Resource Number로, AWS에서 생성되는 리소스에 대한 일련번호라고 이해하시면 됩니다.
Health_check_type의 경우 aws loadbalancer를 칭하는 ELB로 설정했습니다.
Load Balancer 정의하기
이 부분부터 혼동이 많이옵니다…
설정해야 할 내용은 크게 4개입니다.
- aws_lb
- aws_lb_listener
- aws_lb_target_group
- aws_lb_listener_rule
위에서 부터 천천히 진행하도록 합니다.
aws_lb
resource "aws_lb" "example" {
name = "terraform-asg-example"
load_balancer_type = "application"
subnets = data.aws_subnet_ids.default.ids
security_groups = [aws_security_group.alb.id]
}
aws_lb의 경우 어떤 타입의 로드밸런서를 어느 서브넷에 어떤 보안규칙으로 설정할 지 정의합니다.
aws_lb_listener
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.example.arn
port = 80
protocol = "HTTP"
default_action {
type = "fixed-response"
fixed_response {
content_type = "text/plain"
message_body = "404: page not found"
status_code = 404
}
}
}
Lb_listener를 위와 같이 설정하면, 80번 포트를 통해서 수신하고, HTTP 프로토콜을 사용하며, 설정한 내용으로 응답을 보내지 않았을 경우, fixed_response로 설정한 404 메세지를 보내도록 액션을 취합니다.
aws_lb_target_group
resource "aws_lb_target_group" "asg" {
name = "terraform-asg-example"
port = var.server_port
protocol = "HTTP"
vpc_id = data.aws_vpc.default.id
health_check {
path = "/"
protocol = "HTTP"
matcher = "200"
interval = 15
timeout = 3
healthy_threshold = 2
unhealthy_threshold = 2
}
}
target_group의 경우, 어떤 규칙을 이용해서 target을 정하는지를 정의합니다.
여기선 변수로 받을 sever_port를 이용해서 통신하고, HTTP프로토콜을 사용하도록 구성합니다.
이후, data를 통해 받은 vpc_id를 설정합니다.
또한 health_check 규칙이 있는데, 어떤 방법으로 health check를 할지 정의합니다.
aws_lb_listener_rule
resource "aws_lb_listener_rule" "asg" {
listener_arn = aws_lb_listener.http.arn
priority = 100
action {
type = "forward"
target_group_arn = aws_lb_target_group.asg.arn
}
condition {
path_pattern {
values = ["*"]
}
}
}
마지막으로 listener rule을 구성해서 생성한 target_group과 load balancer를 연결해줍니다.
security group
resource "aws_security_group" "alb" {
name = "terraform-example-alb"
ingress {
from_port = 80
protocol = "tcp"
to_port = 80
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
protocol = "-1"
to_port = 0
cidr_blocks = ["0.0.0.0/0"]
}
}
이전에 설정한 security group과 다르게, ingress와 egress를 설정해줘야 합니다.
Health check를 통해 결과를 받아 들여야 하기 때문에, egress를 추가합니다.
여기서 egress는 포트와 상관없이 허용(0)하도록 설계 했습니다.
Output 설정하기
output "alb_dns_name" {
value = aws_lb.example.dns_name
description = "The domain name of the load balancer"
}
이 부분은 필수는 아니지만, 편의를 위해 설정합니다.
정상적으로 alb 및 autoscaling이 완성되면 alb의 dns를 출력합니다.
terraform apply -parallelism=30
모든 리소스 코드가 준비되었다면 apply해줍니다.
여기서 -parallelism값을 설정했는데, 병렬처리처럼 더 빠르게 생성하도록 설정했습니다.
curl http://[alb_dns_name]
완료되었다면, output으로 나온 값을 이용해서 테스트해보세요.
terraform destroy
실습을 마쳤다면 부셔주세요… 과금을 막을 방법입니다.