최근 회사에서 멀티 환경 클라우드 플랫폼을 구성하고 있는데 블로그 글로 남기면 좋을 것 같아서 작성해본다.
회사에서는 주로 AWS를 쓰기 때문에, 본 글은 AWS를 예시로 작성을 해봤다.
1. DNS관리, 보통은 어떻게 하는가
멀티 환경 클라우드 플랫폼을 구성할 때, 자주 부딪히는 문제가 있다. 바로 DNS관리이다.
보통은 각 환경(dev, qa, prod)별로 서로 다른 AWS 계정이 있다. 그럼 ‘그냥 각 환경에서 Route53 파서 Hosted Zone 등록하면 되지 않나?’라고 생각이 든다면… 당신은 클라우드 개발자로서 아직 하수인 것,,,
클라우드 엔지니어는 클라우드에서 개발하는 사람이지만, 비즈니스 관점에서 보자면 돈을 잡아먹는 하마 그 자체이다. 남의 컴퓨터 빌려쓰는건데 땅파서 돈이 나오나 그냥 회삿돈 쓰는거지 뭐 ㅎㅎ;;
그렇다보니 클라우드 엔지니어는 클라우드를 잘 활용하는 것 뿐만 아니라 돈을 얼마나 아끼는, 효율적으로 아키텍쳐를 설계하느냐에 따라 실력이 나뉜다고 할 수 있다.
각설하고, 그럼 Hosted Zone을 각 계정에서 판다는게 왜 하수이냐? 라고 물어본다면 이렇게 답하면 된다. 만들 때마다 비용이 나가기 때문이다
각 클라우드 업체마다 비용은 다르지만, 일단 Hosted Zone을 생성하면 최소 $0.2-0.5가 청구된다. 이게 B2B로 계속 account를 만들어서 세팅해야 한다면? account 개수만큼 이 비용이 나가는 것이다. 물론 작다면 작은 금액이지만, 클라우드 엔지니어는 이 비용조차 줄여야 비로소 실력이 있다는 소리를 들을 수 있다.
그럼 실무에서는 이걸 어떻게 관리하냐, 바로 DNS전용 Account를 따로 생성해서 여기서 모든 dns를 관리한다. 그리고 각 account에서 이 정보를 가져와서 사용하면, 아무리 account가 늘더라도 딱 하나의 Hosted Zone비용을 대기만 하면 된다.
DNS Account
└── Route53: example.com
├── cloud.dev.example.com
├── cloud.prod.example.com
└── cloud.qa.example.com
여기서 문제가 하나 생긴다.
각 환경은 서로 다른 AWS 계정인데, 어떻게 공용 DNS Account의 Route53에 자동으로 접근해서 레코드를 생성할 수 있을까?
즉, 우리는 Cross-Account DNS 접근 문제를 해결해야 한다.
2. 문제: 계정별 권한 관리의 한계
가장 단순한 방법은 DNS Account에 있는 IAM Role(TerraformDNSRole)의 trust policy에 각 환경 계정을 하나씩 추가하는 것이다.
{
"Principal": {
"AWS": [
"arn:aws:iam::111111111111:root",
"arn:aws:iam::222222222222:root"
]
}
}
이 방식은 처음에는 잘 동작한다.
하지만 시간이 지나면 문제가 생긴다:
- 새로운 환경 (ex. staging) 추가
- 고객별 전용 account 생성
- 테스트용 account 생성
그때마다:
- DNS Account에 로그인
- IAM Role 수정
- account ID 추가
이 과정을 반복해야 한다.
즉 자동화는 개뿔 초반 세팅에서 무조건 account에 접속해서 일일이 Role과 policy를 생성해야 한다는 것이다.
3. 해결: AWS Organizations 기반 접근 제어
이 문제를 깔끔하게 해결하는 방법이 있다.
바로 AWS Organizations를 활용하는 것이다.
개별 계정을 나열하는 대신, 아래처럼 설정한다:
{
"Effect": "Allow",
"Principal": { "AWS": "*" },
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"aws:PrincipalOrgID": "o-xxxxxxxxxx"
}
}
}
이 설정의 의미는:
"AWS": "*"→ 누구나 접근 가능해 보이지만aws:PrincipalOrgID조건 → 우리 Organization에 속한 계정만 허용
결과적으로:
- 새로운 AWS 계정을 만들어도
- 자동으로 접근 가능
- 추가 설정 필요 없음
4. Terraform에서 Cross-Account DNS 사용하기
이제 Terraform에서 이 Role을 어떻게 사용할까?
각 환경의 providers.tf에 다음과 같이 설정한다:
provider "aws" {
alias = "dns"
region = "us-east-1"
assume_role {
role_arn = "arn:aws:iam::123456789010:role/TerraformDNSRole"
}
}
그리고 Route53 리소스에서 해당 provider를 사용한다:
resource "aws_route53_record" "program" {
provider = aws.dns
zone_id = var.route53_hosted_zone_id
name = local.domain_name
type = "A"
}
이렇게 하면:
- Terraform은 현재 account에서 실행되지만
- 내부적으로 DNS Account로 Role assume 후
- Hosted Zone에 레코드를 생성한다
5. 그래서 DNS Account에는 뭘 해야 할까
여기까지 보면 이런 생각이 든다.
“그래서 DNS Account에는 뭐 만들어야 하는거지?”
결론부터 말하면 간단하다.
👉 IAM Role 하나만 제대로 만들어두면 끝이다
이 Role 이름이 바로 TerraformDNSRole이다.
이 Role에는 두 가지가 필요하다:
1) Trust Policy
{
"Effect": "Allow",
"Principal": { "AWS": "*" },
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"aws:PrincipalOrgID": "o-xxxxxxxxxx"
}
}
}
2) Permissions Policy
{
"Effect": "Allow",
"Action": [
"route53:ChangeResourceRecordSets",
"route53:GetHostedZone",
"route53:ListResourceRecordSets"
],
"Resource": "arn:aws:route53:::hostedzone/ZXXXXXXXXXXXXX"
}
이후 account가 몇 개가 늘어나든 DNS Account를 다시 건드릴 필요가 없다!
6. 전체 흐름 한 번에 보기
DNS Account
└── Route53 (example.com)
↑
│ (assume role)
│
Dev Account ── Terraform apply
QA Account ── Terraform apply
Prod Account ── Terraform apply