Ssoon
[7주차] 프로덕션 수준의 테라폼 코드 본문
CloudNet@ 팀의 가시다님이 진행하는 Terraform 101 Study 07주차 정리입니다.
✅ 프로덕션 수준 인프라 구축에는 많은 시간이 필요합니다.
💠 데브 옵스 산업은 아직 초기 단게입니다. 이러한 기술들은 아직 충분히 성숙하지 않았습니다.
💠 원래 하고 싶엇던 작업을 수행하기 전 해야 하는 많은 작업들에 취약합니다.
💠 프로덕션 인프라를 준비하기 위해 수행해야 하는 작업의 체크 리스트가 너무 길기 때문입니다.
✅ 프로덕션 수준 인프라 모듈
💠 소형 모듈
✔ 각각 한 가지 일을 하는 소형 모듈로 코드를 작성합니다.
✔ 각각 하나의 작업을 수행하는 여러 개의 독립형 module 로 리팩토링하는 것이 좋은 방법입니다.
리팩터링(refactoring)은 소프트웨어 공학에서 '결과의 변경 없이 코드의 구조를 재조정함'을 뜻한다. 주로 가독성을 높이고 유지보수를 편하게 한다.
✅ 소형 module 3개로 리팩토링
💠 오토스케일링 그룹 (ASG)
⛔ modules/cluster/asg-rolling-deploy/main.tf
- aws_launch_configuration
- aws_autoscaling_group
- aws_autoscaling_schedule
- aws_security_group
- aws_security_group_rule
- aws_cloudwatch_metric_alarm
⛔ modules/cluster/asg-rolling-deploy/variables.tf
- cluster_name
- ami
- instance_type
- min_size
- max_size
- enable_autoscaling
- custom_tags
- server_port
💠 애플리케이션 로드 밸런서 (ALB)
⛔ modules/networking/alb/mian.tf
- aws_lb
- aws_lb_listener
- aws_security_group
- aws_security_group_rule
⛔ modules/networking/alb/variables.tf
- alb_name
- subnet_ids
✅ 합성 가능한 module
💠 외부에서 상태를 읽는 대신 입력 매개 변수를 통해 전달하고, 외부에 상태를 쓰는 대신 출력 매개 변수를 통해 게산 결과를 반환합니다.
💠 모든 것을 입력 변수를 통해 전달하고 모든 것을 출력 변수를 통해 반환하며 간단한 module 들을 조합해 더 복잡한 module 을 만들 수 있습니다.
💠 새로운 입력 변수 4개 추가
⛔ modules/cluster/asg-rolling-deploy/variables.tf
- subnet_ids
- asg-rolling-deploy module을 배포할 서브넷으로 지정합니다.
- webserver-cluster 모듈은 기본 vpc 및 subnet에 배포하도록 하드 코딩
- subnet_ids 변수를 노출해 어떤 vpc 나 subnet에서도 사용할 수 있게 허용
- target_group_arns
- health_check_type
- asg 를 로드 밸런서와 통합하는 방식을 구성합니다.
- webserver_cluster 모듈에는 alb가 내장되어 있지만 asg-rolling-deploy 모듈은 일반 모듈이므로 로드 밸런서 설정을 입력 변수로 노출하면 다양한 상황에서 ASG 를 사용할 수 있습니다.
- user_data
- 사용자 데이터 스크립트를 전달하기 위한 것입니다.
- webserver-cluster 모듈에 하드 코딩된 사용자 데이터 스크립트는 hello,world 앱 배포에만 사용
- 사용자 데이터 스크립트를 입력 변수로 사용하면 asg-rolling-deploy 모듈은 ASG 전체에 배포할 수 있습니다.
⛔ modules/cluster/asg-rolling-deploy/main.tf
- subnet_ids / target_group_arns / health_check_type 3가지 입력변수를 aws_autoscaling_group 리소스에 전달합니다
- ALB 같은 이전에 하드 코딩된 리소스 및 데이터 소스를 참조하는 설정으로 대체합니다.
resource "aws_autoscaling_group" "example" {
name = "${var.cluster_name}-${aws_launch_configuration.example.name}"
launch_configuration = aws_launch_configuration.example.name
vpc_zone_identifier = var.subnet_ids
target_group_arns = var.target_group_arns
health_check_type = var.health_check_type
- user_data 변수를 aws_launch_configuration 리소스로 전달합니다.
- asg-rollig-deploy 모듈에 복사하지 않은 template_file 데이터 소스에 대한 참조를 대체합니다.
resource "aws_launch_configuration" "example" {
image_id = var.ami
instance_type = var.instance_type
security_groups = [aws_security_group.instance.id]
user_data = var.user_data
💠 출력 변수 추가
⛔ modules/cluster/asg-rolling-deploy/outputs.tf
- 출력 변수를 추가합니다.
- 이 데이터를 출력하면 모듈의 소비자가이러한 출력을 사용하여 보안 그룹에 사용자 정의 규칙을 추가하는 등 새로운 동작을 추가할 수 있습니다. > 모듈의 재사용성을 높입니다.
output "asg_name" {
value = aws_autoscaling_group.example.name
description = "The name of the Auto Scaling Group"
}
output "instance_security_group_id" {
value = aws_security_group.instance.id
description = "The ID of the EC2 Instance Security Group"
}
⛔ modules/cluster/asg-rolling-deploy/outputs.tf
- 동일하게 출력 변수를 추가합니다.
output "alb_dns_name" {
value = aws_lb.example.dns_name
description = "The domain name of the load balancer"
}
output "alb_http_listener_arn" {
value = aws_lb_listener.http.arn
description = "The ARN of the HTTP listener"
}
output "alb_security_group_id" {
value = aws_security_group.alb.id
description = "The ALB Security Group ID"
}
💠 모듈 생성
asg-rolling-deploy 및 alb 모듈을 사용하여 'Hello,World!"앱을 배포할 수 있는 hello-world-app module 을 생성합니다.
⛔ modules/services/hello-world-app/main.tf
앞에서 생성한 asg-rolling-deploy module 을 hello-world-app 모듈에 추가합니다.
module "asg" {
source = "../../cluster/asg-rolling-deploy"
cluster_name = "hello-world-${var.environment}"
ami = var.ami
user_data = data.template_file.user_data.rendered
instance_type = var.instance_type
min_size = var.min_size
max_size = var.max_size
enable_autoscaling = var.enable_autoscaling
subnet_ids = data.aws_subnet_ids.default.ids
target_group_arns = [aws_lb_target_group.asg.arn]
health_check_type = "ELB"
custom_tags = var.custom_tags
}
앞에서 생성한 alb module 을 hello-world-app 모듈에 추가합니다.
module "alb" {
source = "../../networking/alb"
alb_name = "hello-world-${var.environment}"
subnet_ids = data.aws_subnet_ids.default.ids
}
💠 ALB 대상 그룹 및 리스너 규칙 구성
⛔ modules/services/hello-world-app/main.tf
name 에서 enviroment 입력 변수를 사용하도록 설정합니다.
cluster_name = "hello-world-${var.environment}"
module "asg" {
source = "../../cluster/asg-rolling-deploy"
cluster_name = "hello-world-${var.environment}"
ami = var.ami
user_data = data.template_file.user_data.rendered
instance_type = var.instance_type
...
aws_lb_listener_rule 리소스의 listener_arn 매개 변수가 alb module 의 alb_http_listener_arn 출력을 가르키도록 설정합니다.
listener_arn = module.alb.alb_http_listener_arn
resource "aws_lb_listener_rule" "asg" {
listener_arn = module.alb.alb_http_listener_arn
priority = 100
condition {
path_pattern {
values = ["*"]
}
}
...
💠 출력 변수 추가
⛔ modules/services/hello-world-app/outputs.tf
output "alb_dns_name" {
value = module.alb.alb_dns_name
description = "The domain name of the load balancer"
}
output "asg_name" {
value = module.asg.asg_name
description = "The name of the Auto Scaling Group"
}
output "instance_security_group_id" {
value = module.asg.instance_security_group_id
description = "The ID of the EC2 Instance Security Group"
}
✅ module 세분화 패턴
💠 일반 모듈
✔ asg-rolling-deploy 및 alb 같은 모듈은 코드의 기본 구성 요소이며 다양하게 재사용이 가능합니다.
💠 사용 사례별 모듈
✔ hello-world-app 과 같은 모듈은 여러 개의 일반 모듈을 결합하여 특정 사례에 사용할 수 있습니다.
'Terraform 101 Study' 카테고리의 다른 글
[6주차] 06 Terraform으로 Secret 관리 - Resources & Data Sources (0) | 2022.11.27 |
---|---|
[6주차] 06 Terraform으로 Secret 관리 - Terraform과 함께 Secret 관리 도구 사용 (0) | 2022.11.22 |
[6주차] 06 Terraform으로 Secret 관리 - Basic/Tools (0) | 2022.11.22 |
[5주차] 05 테라폼의 팁과 요령 (2) 조건문 - count (0) | 2022.11.19 |
[5주차] 05 테라폼의 팁과 요령 (1) 반복문 - String Directive (0) | 2022.11.17 |