Terraform에서 Launch Template, 오토 스케일링 설정하기
이번 글에서는 테라폼에서 EC2를 생성할 때 ALB를 연동하려면 필수적으로 launch template과 auto scaling이 필요하다. 각 모듈에 대해서 살펴보자.
1. ECS를 EC2 기반으로 구축할 때 ALB 연동하는 경우와 연동하지 않는 경우의 차이
AWS ECS(Elastic Container Service)를 EC2 기반으로 구축할 때, ALB(Application Load Balancer)를 연동하는 경우와 그렇지 않은 경우의 차이를 고려해야 한다. 테라폼을 사용하여 이를 구성하는 과정을 살펴보겠다.
ALB 미연동 EC2
이 경우에는 간단한 EC2 인스턴스를 만들어주는 걸로 충분하다. ALB와 연동하지 않으므로, Load Balancer 관련 설정은 필요하지 않다. ECS 클러스터와 연결하여 컨테이너를 실행할 수 있다.
ALB 연동 EC2
이 경우에는 더 많은 구성 요소가 필요하다.
- Launch Template: EC2 인스턴스를 생성할 때 사용할 템플릿이다. 인스턴스 유형, AMI, 시작 스크립트 등을 정의한다.
- Auto Scaling Group (ASG): 트래픽에 따라 EC2 인스턴스의 수를 자동으로 조정한다. ASG는 Launch Template을 사용하여 인스턴스를 생성한다.
- ALB: ASG에서 생성된 인스턴스들에 대한 트래픽을 분산시킨다. ECS 서비스와 연결하여 컨테이너에 트래픽을 전달한다.
Launch Template
가장 먼저 생성해야 한다. 런치 템플릿은 EC2 인스턴스의 세부 사항(AMI, 인스턴스 유형 등)을 정의한다. 필요한 경우 사용자 데이터(User Data)를 포함하여 ECS 에이전트와 통합을 위한 설정을 할 수 있다.
Auto Scaling Group
Launch Template이 정의된 후에 생성된다. 최소, 최대, 원하는 인스턴스 수를 정의한다. 필요한 경우 스케일링 정책을 설정하여 트래픽 변동에 따라 인스턴스 수를 조정한다.
ALB
ASG 설정이 완료된 후에 생성된다. 리스너와 타깃 그룹을 설정하여 트래픽을 관리한다.
Launch Template과 Auto Scaling에 대해 더 자세히 설명해 보겠다. 이 두 가지는 AWS에서 EC2 인스턴스를 관리하는 데 중요한 역할을 한다.
Launch Template이란?
Launch Template은 EC2 인스턴스를 생성할 때 필요한 설정을 미리 정의해 두는 템플릿이다. 이 템플릿에는 다음과 같은 정보들이 포함될 수 있다:
- AMI (Amazon Machine Image): 사용할 인스턴스의 OS 및 소프트웨어 구성을 포함한 이미지
- 인스턴스 유형: 예를 들어 t2.micro, m5.large 같은 EC2 인스턴스의 사양
- 보안 그룹: 인스턴스에 적용할 네트워크 접근 규칙
- 키 페어: 인스턴스에 접근하기 위한 SSH 키
- 블록 스토리지 설정: 인스턴스에 연결될 추가 스토리지 옵션 등
Launch Template을 사용하면, 인스턴스 생성 시 일관된 설정을 적용할 수 있다. 특히, 대규모로 EC2 인스턴스를 배포할 때 이러한 표준화된 설정이 매우 유용하다.
Auto Scaling이란?
Auto Scaling은 트래픽이나 사용량에 따라 자동으로 EC2 인스턴스의 수를 조절하는 기능이다. 이를 통해 트래픽이 많을 때는 자동으로 인스턴스를 추가하고, 트래픽이 줄었을 때는 인스턴스를 줄여서 비용을 절약할 수 있다.
Launch Template과 Auto Scaling의 관계
Launch Template은 Auto Scaling 그룹에서 새로운 인스턴스를 생성할 때 사용되는 설정을 제공한다. 즉, Auto Scaling 그룹이 새 인스턴스를 필요로 할 때마다, Launch Template에 정의된 설정에 따라 인스턴스를 자동으로 생성하게 된다.
애플리케이션을 생성할 때 Auto Scaling의 필요성
애플리케이션을 운영할 때 항상 Auto Scaling이 필요한 건 아니다. 특정 애플리케이션의 경우, 트래픽 변동에 따른 자동 확장이 필요하지 않을 수 있다. 이런 경우에는 Auto Scaling을 설정하지 않고, 필요한 만큼의 인스턴스만 수동으로 운영할 수 있다.
또한 EC2 인스턴스를 실행하는 데 Auto Scaling이 필수적은 아니다. 단일 인스턴스 또는 고정된 수의 인스턴스만 필요한 경우, 런치 템플릿(Launch Template)을 사용하지 않고 단순히 EC2 인스턴스만 생성해도 되며, 런치 템플릿을 사용해서 생성하는 것도 가능하다.
결론
Launch Template은 EC2 인스턴스 생성에 필요한 설정을 표준화하고 재사용하기 위한 템플릿이고 Auto Scaling은 트래픽 변동에 따라 EC2 인스턴스 수를 자동으로 조절하는 기능이다. 둘 다 필수적이지는 않으며, 애플리케이션의 요구사항과 환경에 따라 선택적으로 사용될 수 있다.
(예시 코드)
# Launch Template 생성
resource "aws_launch_template" "example" {
name_prefix = "example-lt-"
image_id = "ami-xxxxxxx"
instance_type = "t2.micro"
# ... 기타 설정 ...
}
# Auto Scaling Group 생성
resource "aws_autoscaling_group" "example" {
launch_template {
id = aws_launch_template.example.id
version = "$Latest"
}
# ... 기타 설정 ...
}
# ALB 생성
resource "aws_lb" "example" {
name = "example-lb"
internal = false
load_balancer_type = "application"
# ... 기타 설정 ...
}
- Launch Template: AMI와 인스턴스 타입 등을 정의한다. ECS에 통합하기 위한 사용자 데이터를 포함할 수 있다.
- Auto Scaling Group: Launch Template을 기반으로 인스턴스를 자동으로 조정한다. 최소, 최대, 원하는 인스턴스 수를 정의한다.
- ALB: 애플리케이션 로드 밸런서를 생성하고 트래픽 관리를 위한 설정을 한다.
이 예시는 가장 기초직인 구성으로 이루어져 있다. 실제 환경에서는 보안 그룹, 네트워크 설정, IAM 역할 등 추가적인 구성 요소들이 필요할 수 있다.
이제 우리 프로젝트에서 적용한 launch template 모듈을 살펴보자
2. launch template 모듈
각 모듈에는 main.tf, outputs.tf, variables.tf, user_data.sh라는 파일이 있다고 가정한다.
main.tf 파일은 테라폼 모듈의 핵심이며, AWS EC2 런치 템플릿을 정의하는 데 사용된다.
resource "aws_launch_template" "launch_template" {
name_prefix = var.name_prefix # 런치 템플릿의 이름 접두사
image_id = var.image_id # 사용할 AMI ID
instance_type = var.instance_type # 인스턴스 타입 (예: t2.micro)
key_name = var.key_name # EC2에 할당할 키 이름
vpc_security_group_ids = var.vpc_security_group_ids # 보안 그룹 ID 목록
iam_instance_profile {
name = var.iam_instance_profile # IAM 인스턴스 프로파일 이름
}
block_device_mappings {
device_name = "/dev/xvda" # EBS 볼륨 장치 이름
ebs {
volume_size = 30 # 볼륨 크기 (GB)
volume_type = "gp2" # 볼륨 타입
}
}
tag_specifications {
resource_type = "instance" # 태그 할당 리소스 유형
tags = {
Name = var.ec2_instance_name # EC2 인스턴스 이름
}
}
user_data = filebase64("${path.module}/${var.user_data_file}") # 사용자 데이터 파일
}
resource "aws_launch_template" "launch_template"
이 섹션은 AWS에서 EC2 런치 템플릿을 생성한다. aws_launch_template는 테라폼의 AWS 프로바이더에 속한 리소스 유형이다. (즉, 예약어다)
- name_prefix: 런치 템플릿의 이름 접두사다. 예를 들어, "my-launch-template-"를 사용하면 실제 템플릿 이름은 "my-launch-template-xxxxxx"와 같은 형식으로 생성된다. 여기서 "xxxxxx"는 자동으로 생성되는 고유 식별자다.
- image_id: AMI ID는 EC2 인스턴스를 시작할 때 사용할 Amazon Machine Image를 식별한다. 예를 들어, "ami-0abcdef1234567890"와 같은 형태다. 이 ID는 AWS Management Console에서 찾을 수 있다.
아래 이미지는 AWS Management Console에서 EC2를 생성할 때 AMI를 선택하는 화면에서 확인할 수 있는 ami 아이디값이다.
- instance_type: EC2 인스턴스의 유형을 지정한다. 예를 들어, "t2.micro", "m5.large"와 같은 값이 들어간다. 이는 인스턴스의 성능과 비용을 결정한다.
- key_name: EC2 인스턴스에 접근하기 위한 SSH 키 페어의 이름이다. AWS Management Console에서 생성한 키 페어의 이름을 사용한다. 예를 들어, "my-key-pair"와 같은 값다.
- vpc_security_group_ids: 인스턴스가 속할 VPC 보안 그룹 ID의 목록이다. 예를 들어, ["sg-01a2b3c4d5e6f7890", "sg-0987f6e5d4c3b2a1"]와 같이 하나 이상의 보안 그룹 ID를 포함할 수 있다.
- iam_instance_profile: EC2 인스턴스에 할당할 IAM 역할의 이름이다. 예를 들어, "my-iam-role"와 같은 값이 들어간다. 이 역할은 AWS Management Console에서 생성하고 관리한다.
- block_device_mappings: 인스턴스에 연결할 EBS 볼륨의 설정을 정의한다. volume_size는 볼륨의 크기를 GB 단위로 지정하며, volume_type은 볼륨 타입을 지정한다. 예를 들어, volume_size = 30와 volume_type = "gp2"는 30GB 크기의 일반 SSD 볼륨을 생성한다.
- tag_specifications: 인스턴스에 적용할 태그를 정의한다. resource_type = "instance"는 태그가 EC2 인스턴스에 적용됨을 나타낸다. tags는 키-값 쌍으로 구성되며, 예를 들어, Name = "my-ec2-instance"는 인스턴스에 "Name": "my-ec2-instance"라는 태그를 추가한다.
- user_data: 인스턴스 시작 시 실행될 스크립트의 내용이다. 이 값은 스크립트 파일을 base64로 인코딩하여 제공한다. 예를 들어, "${path.module}/user-data.sh" 파일의 내용이 base64로 인코딩 되어 이 필드에 포함된다.
💡 ${path.module} 문법
main.tf 파일에서 사용되는 ${path.module} 문법은 Terraform의 내장 함수 중 하나이다. 이 함수는 현재 Terraform 모듈의 파일 시스템 경로를 반환한다. 즉, Terraform 구성 파일이 위치한 디렉토리의 경로를 참조하는 데 사용된다.
예를 들어, user_data 설정에서 "${path.module}/user-data.sh"라고 작성하면, Terraform은 현재 모듈의 경로에 user-data.sh 파일이 있다고 가정하고 이 파일의 경로를 찾는다. 이 경로는 Terraform이 실행되는 위치에 따라 달라질 수 있다.
user_data 필드에서 이 방식을 사용하면, 사용자 정의 스크립트를 인스턴스 시작 시 자동으로 실행할 수 있다. user-data.sh 파일은 EC2 인스턴스가 처음 시작될 때 실행되는 스크립트를 포함하며, 이 파일의 내용은 base64로 인코딩 되어 EC2 인스턴스에 전달된다.
예를 들어, user-data.sh 파일에는 인스턴스 설정, 소프트웨어 설치, 시스템 업데이트 등을 자동화하는 명령어들이 포함될 수 있다. 이렇게 하면 EC2 인스턴스가 시작될 때 필요한 설정이나 소프트웨어 설치가 자동으로 이루어진다.
outputs.tf 파일은 테라폼 모듈의 출력 값을 정의한다.
output "launch_template_id" {
value = aws_launch_template.launch_template.id # 생성된 런치 템플릿의 ID 출력
}
- output "launch_template_id": 이 섹션은 생성된 런치 템플릿의 ID를 출력한다. 이 ID는 다른 테라폼 구성에서 참조될 수 있다.
variables.tf 파일은 테라폼 모듈에 전달될 입력 변수들을 정의한다.
variable "name_prefix" {
description = "Prefix of the launch template name"
}
variable "image_id" {
description = "AMI ID to be used in the launch template"
}
variable "instance_type" {
description = "Instance type to be used in the launch template"
}
variable "key_name" {
description = "Key name to be used in the launch template"
}
variable "ec2_instance_name" {
description = "EC2 instance name"
}
variable "vpc_security_group_ids" {
description = "List of security group IDs to be used in the launch template"
type = list(string)
}
variable "iam_instance_profile" {
description = "IAM instance profile to be used in the launch template"
}
variable "user_data_file" {
description = "Path to the user data file"
}
각 variable 선언은 모듈 외부에서 제공될 수 있는 값을 정의한다. 예를 들어, name_prefix, image_id, instance_type 등의 변수가 정의된다. 이 변수들은 main.tf에서 런치 템플릿을 생성할 때 사용된다.
각 변수에는 설명(description)이 포함되어 있어, 변수의 용도를 이해하는 데 도움이 된다.
user_data.sh 파일은 EC2 인스턴스가 처음 시작될 때 실행되는 쉘 스크립트다.
#!/bin/bash
echo ECS_CLUSTER=example-ecs-cluster >> /etc/ecs/ecs.config
이 스크립트는 /etc/ecs/ecs.config 파일에 ECS_CLUSTER 환경 변수를 설정하여, 해당 EC2 인스턴스가 특정 ECS 클러스터에 참여하도록 한다.
- #!/bin/bash: 스크립트가 bash 쉘에서 실행되어야 함을 나타낸다.
- echo ECS_CLUSTER=example-ecs-cluster >> /etc/ecs/ecs.config: ECS 클러스터 이름을 ecs.config 파일에 추가한다.
💡 #! shebang 사용법
#!/bin/bash 라인은 주석이 아다. 이것은 "shebang" 또는 "hashbang"이라고 불리는 특별한 표기법이다. 스크립트 파일의 맨 처음에 위치하여, 해당 스크립트가 어떤 해석기(interpreter)를 사용하여 실행되어야 하는지를 운영 체제에 알려준다.
#!/bin/bash의 경우:
- #과 ! 기호는 합쳐져 shebang을 형성한다.
- /bin/bash는 이 스크립트를 실행하기 위해 사용할 쉘의 경로를 지정한다. 여기서는 bash 쉘이 사용된다.
이 shebang 라인이 포함된 스크립트는 실행될 때 /bin/bash 쉘에 의해 해석되고 실행된다. 스크립트 파일이 실행 가능한 상태로 설정되어 있다면 (예: chmod +x user_data.sh 명령어를 사용하여 실행 권한을 부여한 경우), 스크립트 파일을 직접 실행할 수 있으며, 이때 /bin/bash 쉘이 자동으로 해당 스크립트를 해석하고 실행한다.
따라서, #!/bin/bash 라인은 스크립트의 나머지 부분이 bash 쉘에서 실행되어야 함을 명시하는 중요한 지시사항이다.
💡 echo 명령어 사용법
echo 명령어는 일반적으로 터미널이나 콘솔에 텍스트를 출력하는 데 사용된다. 그러나 리눅스 쉘 스크립트에서 echo 명령어는 파일에 텍스트를 추가하는 데도 사용할 수 있다.
예시 코드에서 echo ECS_CLUSTER=example-ecs-cluster >> /etc/ecs/ecs.config라는 명령어는 실제로 ECS 클러스터 설정을 /etc/ecs/ecs.config 파일에 추가하는 데 사용된다. 여기서 >> 연산자는 리다이렉션을 의미하며, echo 명령어로 생성된 출력을 지정된 파일의 끝에 추가한다.
- echo [내용]: 터미널이나 콘솔에 [내용]을 출력한다.
- echo [내용] >> [파일 경로]: [내용]을 [파일 경로]에 위치한 파일의 끝에 추가한다.
따라서 이 스크립트는 ECS 클러스터 이름을 ecs.config 파일에 추가하여, EC2 인스턴스가 시작될 때 해당 클러스터와 연동되도록 설정하는 역할을 해 준다. 이는 AWS ECS 환경에서 EC2 인스턴스를 클러스터에 자동으로 등록하기 위한 표준 절차 중 하나이다.
3. autoscaling group 모듈
이 모듈은 AWS에서 자동으로 EC2 인스턴스의 수를 조절하기 위해 사용된다.
AWS 오토 스케일링 그룹 리소스를 선언한다.
# AWS Auto Scaling 그룹 리소스를 선언
resource "aws_autoscaling_group" "asg" {
vpc_zone_identifier = var.vpc_subnets
desired_capacity = 1
max_size = 1
min_size = 1
name = "${var.name_prefix}-asg" # 이름에 접두사 추가
launch_template {
id = var.launch_template_id
version = "$Latest"
}
tag {
key = "AmazonECSManaged"
value = true
propagate_at_launch = true
}
}
- vpc_zone_identifier: 오토 스케일링 그룹이 배치될 VPC 서브넷을 정의한다. 이것은 오토 스케일링 그룹이 동작할 네트워크 영역을 지정한다.
- desired_capacity, max_size, min_size: 이들은 오토 스케일링 그룹에서 관리할 EC2 인스턴스의 수를 설정한다. 'desired_capacity'는 원하는 인스턴스 수, 'max_size'는 최대 인스턴스 수, 'min_size'는 최소 인스턴스 수를 의미한다. (여기서 값이 전부 1인 이유는 일단 예상치 못한 비용을 방지하고자 인스턴스는 하나만 띄우기로 결정했고 추후 수정할 예정이다.)
- name: 오토 스케일링 그룹의 이름을 설정한다. 여기서는 사용자가 제공한 접두사를 이름에 추가한다.
- launch_template: 오토 스케일링 그룹에 사용될 EC2 인스턴스를 시작하기 위한 설정을 포함한 템플릿을 지정한다.
- version = "$Latest": 오토 스케일링 그룹에서 사용할 런치 템플릿의 버전을 지정하는 것이다. 구체적으로 "$Latest"는 항상 최신 버전의 런치 템플릿을 사용하도록 지시한다.
- tag: 오토 스케일링 그룹에 태그를 추가한다. 이 태그는 관리나 식별을 용이하게 하는 데 사용된다.
생성된 오토 스케일링 그룹의 ARN(Amazon Resource Name)을 출력한다.
output "asg_arn" {
description = "ARN of the Auto Scaling Group."
value = aws_autoscaling_group.asg.arn
}
- asg_arn: 생성된 오토 스케일링 그룹의 ARN(Amazon Resource Name)을 출력한다. 이 ARN은 다른 테라폼 구성에서 참조될 수 있다. 예를 들어, 이 ARN을 사용하여 오토 스케일링 그룹을 다른 AWS 리소스와 연결할 수 있다.
모듈에 전달될 입력 변수들을 정의한다.
variable "vpc_subnets" {
description = "VPC subnets for the Auto Scaling Group."
type = list(string)
}
variable "launch_template_id" {
description = "ID of the launch template to use for the Auto Scaling Group."
type = string
}
variable "name_prefix" {
description = "Prefix to be added to the name of the Auto Scaling Group."
type = string
}
- vpc_subnets: 오토 스케일링 그룹이 사용할 VPC 서브넷의 목록을 정의한다. 이는 오토 스케일링 그룹이 어느 네트워크 영역에서 작동할지 결정한다.
- launch_template_id: 오토 스케일링 그룹에 사용될 런치 템플릿의 ID를 지정한다. 이 템플릿은 EC2 인스턴스를 시작할 때 필요한 설정을 포함한다.
- name_prefix: 오토 스케일링 그룹의 이름에 추가될 접두사를 지정한다. 이 접두사는 그룹을 쉽게 식별할 수 있게 해준다.
4. 모듈을 사용하는 main.tf
# EC2 런치 템플릿 설정 - 테스트용
module "test_launch_template" {
source = "./ec2_launch_template"
name_prefix = "test-ec2"
image_id = "ami-0abcdef1234567890"
instance_type = "t2.micro"
key_name = "test-keypair"
vpc_security_group_ids = ["sg-0123456789abcdef0"]
iam_instance_profile = "testInstanceRole"
ec2_instance_name = "ec2_test"
user_data_file = "test_user_data.sh"
}
# 테스트용 오토 스케일링 그룹 생성
module "test_asg" {
source = "./autoscaling_group"
vpc_subnets = ["subnet-12345678", "subnet-87654321", "subnet-12348765"]
launch_template_id = module.test_launch_template.launch_template_id
name_prefix = "test"
}
오토 스케일링 그룹 설정에서 module.test_launch_template.launch_template_id는 런치 템플릿 모듈의 outputs.tf 파일에서 선언된 출력값을 참조한다. 이렇게 함으로써, 오토 스케일링 그룹이 런치 템플릿 모듈에서 정의된 EC2 인스턴스 설정을 사용할 수 있다.
이 코드는 먼저 EC2 런치 템플릿 모듈을 사용하여 EC2 인스턴스 구성을 정의하고, 그 후에 이 런치 템플릿을 사용하는 오토 스케일링 그룹 모듈을 설정하는 내용이다. 이렇게 함으로써, 오토 스케일링 그룹은 런치 템플릿에 정의된 설정에 따라 EC2 인스턴스를 자동으로 시작하고 관리한다.
아직 시작 단계인 luanch template와 auto scaling group을 설정하는 과정을 살펴봤다. 이제 다음에는 ECS를 생성하는데 필요한 ECS 용량 공급자를 모듈화 하는 과정을 알아보자.
이 포스트는 Team chillwave에서 사이드 프로젝트 중 적용했던 부분을 다시 공부하며 기록한 것입니다.
시간이 괜찮다면 팀원 '개발자의 서랍'님의 블로그도 한번 봐주세요 :)
'테라폼(Terraform)' 카테고리의 다른 글
엉금엉금 테라폼 적용하기 (6) - Dynamic 블록으로 AWS 서비스와 태스크 정의하기 (0) | 2023.12.13 |
---|---|
엉금엉금 테라폼 적용하기 (5) - 테라폼으로 ECS Cluster를 생성할때 사용되는 용량 공급자(capacity provider) 이해하고 적용하기 (1) | 2023.12.11 |
엉금엉금 테라폼 적용하기 (3) - Terraform AWS Provider 및 VPC, Subnet 설정 (0) | 2023.12.08 |
엉금엉금 테라폼 적용하기 (2) - MacOS에서 테라폼 설치 및 terraform 명령어 사용법 (0) | 2023.12.08 |
엉금엉금 테라폼 적용하기 (1) - 비용 절감을 위한 테라폼 알아보기 (0) | 2023.12.06 |