Route53 레코드 삭제 + Secrets Manager 초기화 문제
2026-04-10 | Prod 팀원 apply 시 Route53 삭제, Secret 값 초기화 이슈
문제 상황#
- Route53 레코드 삭제: EKS 재기동/축소 후 Route53 레코드가 사라짐
- Secrets Manager 초기화:
terraform apply시 DB/Redis 비밀번호 등이 덮어써짐
원인 1: external-dns policy: sync#
문제#
policy: sync # 레코드 삭제도 허용
policy: sync는 k8s의 Ingress/Service가 삭제되면 해당 Route53 레코드도 삭제.
EKS를 내리거나 축소하면 → Ingress 삭제 → external-dns가 Route53 레코드 삭제.
흐름#
EKS 종료/축소
→ Ingress 리소스 삭제
→ external-dns: "이 Ingress에 연결된 DNS 레코드 삭제해야지" (sync 정책)
→ Route53에서 argocd.playball.one, grafana.playball.one 등 삭제
→ 서비스 접근 불가
수정#
# staging/prod 양쪽
policy: upsert-only # 레코드 생성/갱신만, 삭제 안 함
수정 파일#
| 파일 | 브랜치 |
|---|---|
303-goormgb-k8s-helm/staging/values/infra/values-external-dns.yaml | develop, argocd-sync/staging |
303-goormgb-k8s-helm/prod/values/infra/values-external-dns.yaml | develop, argocd-sync/prod |
upsert-only vs sync#
| sync | upsert-only | |
|---|---|---|
| 레코드 생성 | O | O |
| 레코드 갱신 | O | O |
| 레코드 삭제 | O (위험) | X |
| EKS 재기동 | 레코드 삭제됨 | 레코드 유지 |
참고#
upsert-only에서는 불필요한 레코드가 남을 수 있음 → 수동 정리 필요- 레코드 자동 삭제가 필요하면
--txt-owner-id로 ownership 관리 후sync사용 가능하지만, EKS가 자주 올리고 내리는 환경에서는upsert-only가 안전
원인 2: Secrets Manager secret_version 덮어쓰기#
문제 (Prod)#
# prod/secrets.tf (수정 전)
resource "aws_secretsmanager_secret_version" "discord" {
secret_string = jsonencode(var.common_secrets["prod/monitoring/discord-webhook-alerts"])
# lifecycle ignore_changes 없음 → apply마다 tfvars 값으로 덮어씀
}
terraform apply할 때마다:
var.common_secrets에 값이 있으면 → 그 값으로 덮어씀terraform.tfvars가 없거나 해당 키가 없으면 → 빈 값으로 덮어씀- AWS Console에서 수동 변경한 값이 사라짐
Staging은 왜 괜찮았나#
# staging/secrets.tf (이미 안전)
resource "aws_secretsmanager_secret_version" "kafka" {
secret_string = jsonencode({...})
lifecycle { ignore_changes = [secret_string] } # 이미 있었음
}
Staging은 ignore_changes = [secret_string]이 있어서 최초 생성 후 변경 무시.
Prod에는 이게 없었음.
수정#
# prod/secrets.tf (수정 후)
# 1. secret 자체 삭제 방지
resource "aws_secretsmanager_secret" "this" {
lifecycle {
prevent_destroy = true # 추가
ignore_changes = [description]
}
}
# 2. 수동 설정 secret은 값 변경 무시
resource "aws_secretsmanager_secret_version" "discord" {
secret_string = jsonencode(...)
lifecycle { ignore_changes = [secret_string] } # 추가
}
# 3. 인프라 연동 secret (RDS/Redis endpoint)은 ignore 안 함
# → RDS/Redis 재생성 시 새 endpoint 자동 반영 필요
resource "aws_secretsmanager_secret_version" "ai_postgres" {
secret_string = jsonencode({
host = module.rds.address # 동적
password = module.rds.master_password # 동적
})
# ignore_changes 없음 — 의도적
}
수정 파일#
| 파일 | 변경 |
|---|---|
301-goormgb-terraform/environments/prod/secrets.tf | prevent_destroy + ignore_changes 추가 |
301-goormgb-terraform/environments/prod/main.tf | redis secret에 prevent_destroy 추가 |
301-goormgb-terraform/environments/staging/secrets.tf | prevent_destroy 추가 (ignore_changes는 이미 있었음) |
secret 보호 정책 요약#
| Secret 종류 | prevent_destroy | ignore_changes | 이유 |
|---|---|---|---|
| 수동 설정 (Discord, OAuth, Mail 등) | O | O | Console에서 관리, terraform이 건드리면 안 됨 |
| Kafka defaults | O | O | 초기 설정 후 변경 없음 |
| AI PostgreSQL (host, password) | O | X | RDS 재생성 시 새 값 반영 필요 |
| AI Redis (host, port) | O | X | ElastiCache 재생성 시 새 값 반영 필요 |
| Redis (services/redis) | O | X | ElastiCache endpoint 동적 |
예방 조치#
- external-dns:
upsert-only정책 고정.sync로 바꾸지 말 것 - Secrets Manager: 새 secret 추가 시 반드시
prevent_destroy+ 수동 값은ignore_changes포함 - terraform apply 전:
terraform plan에서destroy또는secret_string변경이 있으면 apply 중단