한동안 테라폼에 큰 작업을 하질 못했다.
테라폼 톡방에서 정보를 보던 중 테라폼 구성을 더 편한 방법이 있을지 문의하다가 honglab님께서 도움을 주셔서 이 섹션을 작업할 수 있었다.
기존 구성
- 리소스를 일일이 하나씩 만들고 있었음.
resource "aws_service_discovery_service" "discovery_service_test1" {
name = "test1"
namespace_id = aws_service_discovery_private_dns_namespace.prod.id
dns_config {
namespace_id = aws_service_discovery_private_dns_namespace.prod.id
dns_records {
ttl = 300
type = "A"
}
routing_policy = "MULTIVALUE"
}
health_check_custom_config {
failure_threshold = 1
}
tags = {
Environment = var.env_tag
}
}
resource "aws_service_discovery_service" "discovery_service_test2" {
name = "test2"
namespace_id = aws_service_discovery_private_dns_namespace.prod.id
dns_config {
namespace_id = aws_service_discovery_private_dns_namespace.prod.id
dns_records {
ttl = 300
type = "A"
}
routing_policy = "MULTIVALUE"
}
health_check_custom_config {
failure_threshold = 1
}
tags = {
Environment = var.env_tag
}
}
ECS의 Mesh 구성을 위해서 discovery service를 추가했다.
하지만 내가 넣어야 할 서비스는 총 9개였다.
이걸 다 늘어뜨려 넣자니 귀찮기도 하고 output을 일일이 다 지정해줘야 해서 결론적으로 코딩이 과하게 늘어나는 문제점이 있었다.
이런 반복문제는 이것 뿐만이 아니라 내가 사용하는 여러가지 모듈과 환경에서 복합적으로 발생한다는게 문제였다.
이 부분을 해결하기 위해 두가지를 추가하여 진행하기로 했다.
1. for_each
2. yaml로 환경 변수 분기
1. 일단 환경 변수를 만드는 과정이다.
yaml 파일을 이용해서 배열 데이터를 yaml로 만들어 준다.
위 config.yaml처럼 생성하면 main.tf에서 배열을 읽어서 처리할 수 환경이 된다.
# config.yaml
discovery_service:
test1:
name: "test1"
ttl: 10
type: "A"
routing_policy: "MULTIVALUE"
failure_threshold: 1
test2:
name: "test2"
ttl: 10
type: "A"
routing_policy: "MULTIVALUE"
failure_threshold: 1
2. main.tf에서 변수값을 넣을수 있도록 설정한다.
# main.tf
module "cloudmap" {
source = "../modules/prod/cloudmap"
vpc_id = module.network.vpc_id # network 모듈에서 출력한 VPC ID를 가져옵니다.
env_tag = yamldecode(file("config.yaml"))["env_tag"]
discovery_service = yamldecode(file("config.yaml"))["discovery_service"]
}
3. module에서 사용할수 있게 variables.tf를 설정한다.
variable "discovery_service" {
type = map(object({
name = string
ttl = number
type = string
routing_policy = string
failure_threshold = number
}))
}
4. 이제 for_each를 통해 loop형태로 작성한다.
# discovery_for_each_statement
resource "aws_service_discovery_service" "discovery_service" {
for_each = var.discovery_service
name = each.value.name
namespace_id = aws_service_discovery_private_dns_namespace.prod.id
dns_config {
namespace_id = aws_service_discovery_private_dns_namespace.prod.id
dns_records {
ttl = each.value.ttl
type = each.value.type
}
routing_policy = each.value.routing_policy
}
health_check_custom_config {
failure_threshold = each.value.failure_threshold
}
tags = {
Environment = var.env_tag
}
}
5. 기존의 terraform state를 기존 배열에 들어가도록 mv 한다.
terraform state mv module.cloudmap.aws_service_discovery_service.test1 module.cloudmap.aws_service_discovery_service.discovery_service\[\"test1\"\]
5번의 작업을 무한대로 해주어야 한다.
참고로 이번에 작업한 항목은 다음과 같다.
- acm
- alb target group
- alb listener rule
- cloudwatch log group
- ssm variables
- s3
EC2나 고객사 커스텀 ACM은 양이 좀 많아 바꾸기가 위험해서 아직 작업하진 않았지만, 회사에서 공용으로 사용하는 도메인에 대해선 ACM이 고정되므로 바로 for_each로 묶어버렸다.
이 작업하면서 코딩된 량이 꽤 많이 줄었고 변수하나만 바꿔서 plan 또는 apply를 돌려도 알아서 연관 로직까지 전부 갱신되는 이점이 있어서 손이 많이 줄긴 했다.
적용시 장점
- 생성 코드 재사용 가능
- 획기적으로 코딩량이 감소
- 환경변수만 바꿔도 알아서 관련 모듈이 전부 수정됨
적용시 단점
- 마이그레이션에 엄청나게 시간이 증가함
- 모든 리소스가 mv 되어야 함
아직 남은 작업이 몇개가 있다.
- iam role 기반으로 연동하기
- 환경까지 통합하기
'AWS' 카테고리의 다른 글
ALB -> NGINX -> root domain to www domain proxy (0) | 2024.01.09 |
---|---|
ECS Fargate에서 Cloudshell을 이용하여 shell 접근 (0) | 2023.12.11 |
슬랙에서 Notion API를 통해 문서 검색 (feat. EC2) (0) | 2023.10.17 |
SSM 로그인 세션 관리 (0) | 2023.09.18 |
SSM으로 EC2 ssh 로그인 하기 (0) | 2023.09.18 |