32장. ACM — 인증서를 어디에 다는가
이 장에서 말하고자 하는 것
앞 장에서 우리는 HTTPS와 TLS 종료를 다뤘다.
그 모든 곳에 필요한 것이
인증서
다.
이 인증서를 AWS에서 발급 · 갱신 · 배포하는 서비스가
AWS Certificate Manager (ACM)
이다.
이 장에서는 ACM을 어떻게 쓰고
어디에 붙일 수 있는지를 본다.
1. ACM이 하는 일
ACM은 세 가지 역할을 한다.
- 인증서를 무료로 발급한다 (퍼블릭 인증서)
- 자동으로 갱신한다 (DNS 검증을 유지하면)
- AWS 리소스에 직접 붙일 수 있게 한다
요약하면
사람이 만료를 신경 쓰지 않고
HTTPS를 운영할 수 있게 해주는 서비스
다.
2. 인증서 발급 흐름
콘솔에서 발급은 단순하다.
1. 도메인 입력 (예: api.example.com)
2. 검증 방식 선택 (DNS 권장)
3. ACM이 검증용 CNAME을 알려준다
4. 그 CNAME을 Route 53에 추가
5. 검증 완료 → 인증서 발급
DNS 검증을 한 번 걸어두면
ACM이 자동 갱신 시점에 다시 그 CNAME을 확인해
사람이 손대지 않고 갱신이 끝난다.
3. DNS 검증 vs 이메일 검증
ACM은 두 가지 검증 방식을 제공한다.
| 방식 | 동작 | 갱신 |
|---|---|---|
| DNS | 지정된 CNAME을 도메인에 추가 | 자동 |
| 도메인 소유자 이메일로 확인 링크 | 수동 |
운영에서는 사실상 DNS 검증 한 가지 만 쓴다.
4. 와일드카드 인증서
여러 서브도메인을 하나의 인증서로 묶을 수 있다.
*.example.com
이러면 다음이 다 같은 인증서로 처리된다.
api.example.com
shop.example.com
admin.example.com
다만 와일드카드는 한 단계만 커버한다.
*.example.com → 가능
*.api.example.com → 별도 발급 필요
*.*.example.com → 불가
운영에서는 보통
example.com 과 *.example.com 두 개를 함께 발급
해 두는 게 편하다.
5. 리전 제약 — CloudFront는 us-east-1
여기서 많은 사람이 한 번 막힌다.
ACM 인증서는 발급한 리전 안에서만 쓸 수 있다.
서울(ap-northeast-2) 발급 → 서울의 ALB · APIGW 에 사용 가능
그런데 CloudFront는 글로벌 서비스라서 us-east-1 인증서만 받는다.
CloudFront 에 붙일 인증서 → us-east-1 에서 발급
ALB / APIGW 에 붙일 인증서 → 그 리소스의 리전에서 발급
운영에서는 사실상
같은 도메인 인증서를 us-east-1과 서울 양쪽에 발급해 둔다
6. 어디에 붙일 수 있는가
ACM 인증서는 다음 리소스에 직접 붙는다.
- CloudFront
- ALB / NLB (TLS 리스너)
- API Gateway
- App Runner / ECS Service (간접)
EC2에 직접 붙일 수는 없다.
EC2에서 HTTPS를 종료하려면 ACM이 아니라
인증서를 직접 가져와 서버에 설치해야 한다
그래서 운영에서는 보통
EC2/ECS 앞에 ALB를 두고, ACM 인증서는 ALB에 붙인다
7. 우리 서비스에서
척추 그림에서 ACM이 닿는 지점은 두 곳이다.
[사용자]
↓ HTTPS (us-east-1 ACM)
[CloudFront]
↓ HTTPS (서울 ACM)
[ALB]
↓ HTTP (내부 VPC)
[ECS]
같은 도메인 api.example.com 에 대해
인증서를 us-east-1과 서울 양쪽에 발급해 둔다.
8. 직접 확인해보기 — CLI
인증서 발급 요청
aws acm request-certificate \
--domain-name "api.example.com" \
--validation-method DNS \
--region ap-northeast-2
응답에 CertificateArn 이 들어 있다.
검증용 CNAME 보기
aws acm describe-certificate \
--certificate-arn <arn> \
--region ap-northeast-2
응답의 DomainValidationOptions.ResourceRecord 에
Route 53에 추가할 CNAME 정보가 들어 있다.
인증서 만료일 확인
aws acm describe-certificate \
--certificate-arn <arn> \
--query 'Certificate.NotAfter'
9. 코드로는 이렇게 생겼다 — Terraform
DNS 검증까지 자동화한 모양이다.
resource "aws_acm_certificate" "main" {
domain_name = "api.example.com"
validation_method = "DNS"
lifecycle {
create_before_destroy = true
}
}
# 검증용 CNAME을 Route 53에 자동 추가
resource "aws_route53_record" "cert_validation" {
for_each = {
for dvo in aws_acm_certificate.main.domain_validation_options :
dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
}
zone_id = aws_route53_zone.main.zone_id
name = each.value.name
type = each.value.type
ttl = 60
records = [each.value.record]
}
# 검증 완료까지 기다림
resource "aws_acm_certificate_validation" "main" {
certificate_arn = aws_acm_certificate.main.arn
validation_record_fqdns = [for r in aws_route53_record.cert_validation : r.fqdn]
}
이 세 리소스가 묶여서 한 단위처럼 동작한다.
10. 이렇게 쓰면 망한다 — 안티패턴
안티패턴 1. CloudFront 인증서를 서울에서 발급한다
us-east-1이 아닌 곳에서 발급 → CloudFront 에 못 붙는다
콘솔 상단의 리전을 us-east-1으로 바꾸고 발급한다.
안티패턴 2. 검증 CNAME을 삭제한다
발급된 뒤에는 안 보이지만
검증 CNAME은 그대로 두어야 한다.
자동 갱신할 때 ACM이 그 CNAME을 다시 확인한다
삭제하면 갱신 실패 → 만료 → HTTPS 중단
안티패턴 3. EC2에 직접 HTTPS를 박는다
EC2 위에 nginx → 인증서 직접 설치
작동은 하지만
- 갱신을 수동으로 해야 한다
- 서버마다 같은 인증서를 배포해야 한다
- 인증서 키 관리가 어렵다
가능한 한 ALB에 ACM을 붙이는 구조로 간다
안티패턴 4. Email 검증으로 발급한다
자동 갱신이 안 된다.
1년 뒤 사람이 잊는다 → 만료 → 장애
운영에서는 무조건 DNS 검증이다.
11. 한 줄로 정리
ACM은 인증서 발급부터 자동 갱신까지 책임지는 AWS의 인증서 관리 서비스다
12. 이 장의 핵심 정리
- ACM은 무료로 퍼블릭 인증서를 발급한다.
- DNS 검증을 쓰면 자동 갱신이 가능하다.
- CloudFront에 붙일 인증서는 us-east-1에서 발급한다.
- 같은 도메인이라도 리전마다 따로 발급해 둔다.
- ACM은 EC2에 직접 못 붙이므로 ALB를 함께 둔다.
- 검증 CNAME은 발급 후에도 그대로 유지한다.