08참가자 AWS 배포예상 약 40분, 별도 일정
CloudFront·HTTPS·수동 DNS
CF Prefix List → ALB SG → ECS SG 경로와 Host 전달, 도메인을 확인합니다.
참가자 AWS 배포 트랙, 예상 약 40분입니다. 07장의 App 스택과 정적 자산 게시가 완료되어 있어야 합니다. DNS 전파 시간은 별도입니다.
05장에서 고정한 실습 hostname을 본인 CloudFront에 수동 연결합니다. 이 프로젝트의 요청 경로는 다음과 같습니다.
브라우저 HTTPS
→ CloudFront + WAF
→ CloudFront 관리형 origin-facing Prefix List
→ Public ALB SG :443 / origin 검증 헤더
→ ECS SG :8098
→ Private Fargate의 Node API → 같은 태스크의 MuJoCo
1. 실제 출력에서 주소 가져오기
set -euo pipefail
cd "$ROBOT_LAB"
test -f infra/workshop-binding.json
python3 -B scripts/deploy.py status --stack app \
> .local/evidence/app-status.json
export ROBOT_URL="$(python3 -c 'import json; print(json.load(open(".local/evidence/app-status.json"))["outputs"]["PublicUrl"])')"
export ROBOT_CF_URL="$(python3 -c 'import json; print(json.load(open(".local/evidence/app-status.json"))["outputs"]["CloudFrontUrl"])')"
export ROBOT_DOMAIN="${ROBOT_URL#https://}"
printf '공개 주소: %s\nCloudFront 주소: %s\n' "$ROBOT_URL" "$ROBOT_CF_URL"
공개 주소가 robot-lab-<참가자>.<허용된 도메인>인지 확인합니다. 다른 사람의 CloudFront 주소나 운영 예제 값을 넣지 않습니다.
2. 권한 있는 DNS에서 수동 등록
DNS 관리 콘솔에서 실습 hostname 하나의 서비스 CNAME을 등록합니다.
| 필드 | 입력 |
|---|---|
| 이름 | ROBOT_DOMAIN의 정확한 hostname |
| 종류 | CNAME |
| 값 | ROBOT_CF_URL에서 https://를 제외한 호스트 |
| TTL | 진행자가 정한 실습 값 |
존 관리 화면에 레코드가 있어도 그 존이 공개 DNS에서 위임된 권한 서버가 아니면 조회되지 않습니다. 실제 관리 중인 존 이름을 입력하고 NS와 CNAME을 확인합니다.
read -r -p "실제로 위임된 DNS 존 이름: " ROBOT_DNS_ZONE
dig +short NS "$ROBOT_DNS_ZONE"
dig +short CNAME "$ROBOT_DOMAIN"
dig +short A "$ROBOT_DOMAIN"
Route53 API로 레코드를 생성하는 명령은 이 실습에 없습니다. 루트 NS 위임을 바꾸거나 다른 hostname을 수정하지 않습니다. ACM 인증서 검증 CNAME과 서비스 연결 CNAME도 서로 다른 레코드입니다.
3. 원본 DNS와 인증서 이해
CloudFront의 API 원본 DomainName은 ALB가 발급받은 기본 DNS 이름입니다. API origin request policy는 공개 hostname의 Host를 전달합니다. ALB의 서울 인증서는 이 전달된 Host와 일치합니다. 별도의 origin.<도메인> 레코드를 만들 필요가 없습니다.
| 구간 | 인증서·설정 |
|---|---|
| 브라우저 → CloudFront | 본인 hostname을 포함하는 us-east-1 viewer 인증서 |
| CloudFront → ALB | HTTPS-only, 서울 origin 인증서, 공개 Host 전달 |
| 기본 CloudFront 주소 | CloudFront Function이 본인 공개 주소로 308 이동 |
| API 쿠키·CSRF | 쿠키, Origin, Content-Type, X-CSRF-Token을 원본에 전달 |
| ALB 보호 | Prefix List와 별도 origin 검증 헤더를 함께 확인 |
여기서는 VPC origin, Internal ALB, Lambda@Edge를 추가하지 않습니다. AWS 공식 근거는 자원과 코드 매핑의 참고 문서에 있습니다.
4. 리다이렉트와 공개 HTTPS 검사
첫 두 호출은 리다이렉트를 따라가지 않고 상태와 목적지만 표시합니다. 기본 CloudFront 주소에서 308이 나오면 의도한 동작입니다.
curl --silent --show-error --max-time 30 \
--output /dev/null --write-out 'status=%{http_code}\nredirect=%{redirect_url}\n' \
"$ROBOT_CF_URL/"
curl --fail --silent --show-error --max-time 30 "$ROBOT_URL/healthz"
curl --fail --silent --show-error --max-time 30 "$ROBOT_URL/readyz"
python3 .local/tools/verify-aws.py
검증기는 실제 SG 연결, Prefix List, Private Fargate, TLS·Host·origin 헤더, WAF, 캐시, 저장소, 공개 HTTPS를 확인합니다. origin 검증 헤더·쿠키·CSRF 값은 출력하지 않습니다. /api/config 원문을 터미널이나 보고서에 복사하지 않고 필요한 상태만 확인합니다.
python3 - <<'PY'
import json, os, urllib.request
base = os.environ["ROBOT_URL"]
with urllib.request.urlopen(base + "/api/config", timeout=30) as response:
config = json.load(response)
summary = {k: config.get(k) for k in ("planner", "model", "storage", "simulation", "version")}
print(json.dumps(summary, ensure_ascii=False, indent=2))
assert summary["planner"] == "agentcore"
assert summary["storage"] == "aws" and summary["simulation"] == "ready"
PY
5. 캐시와 세션 경계 확인
화면과 GLB 같은 정적 자산은 비공개 S3에서 OAC를 통해 전달합니다. /api/*, /healthz, /readyz는 캐시하지 않습니다. 다른 사용자의 계획·실행 상태가 캐시로 공유되어서는 안 됩니다.
브라우저는 하나의 공개 HTTPS origin을 계속 사용합니다. 기본 CloudFront 주소와 사용자 지정 hostname을 오가며 서로 다른 쿠키를 섞지 않습니다. 직접 ALB 호출은 Prefix List 또는 origin 검증에 막히는 것이 정상이며, 확인을 위해 SG를 전체 인터넷에 열지 않습니다.
실패 시 재개
| 증상 | 구분할 원인 |
|---|---|
DNS NXDOMAIN |
실제 NS 위임, 정확한 CNAME 이름·값, 전파 |
| 정적 화면은 보이나 API 502 | ALB 기본 DNS 해석, origin 인증서·Host 일치, target 상태 |
| API 403 | origin 검증 헤더, WAF, 동일 origin, 쿠키·CSRF |
| API 504 | ALB target와 처리 시간, 플래너/시뮬레이터 제한 시간 |
| “서버 응답을 읽지 못했습니다” | 네트워크 응답 상태·Content-Type을 확인해 CloudFront HTML 오류와 API JSON 오류를 구분 |
| 기본 CF 주소의 308을 도구가 오류로 처리 | 실제 공개 주소를 직접 검사하거나 308을 지원하는 클라이언트 사용 |
| 이전 화면이 남음 | 게시한 release, 자산 게시 결과, Distribution 전파와 invalidation 상태 |
완료 체크리스트
- 권한 있는 DNS에서 실습 CNAME을 수동 등록했습니다.
- CF 기본 주소가 본인 공개 주소로 308 이동합니다.
- 공개 HTTPS와
/readyz가 성공합니다. - Prefix List → ALB SG → ECS SG를 실제 연결값으로 검증했습니다.
-
agentcore·aws·ready상태를 확인했고 비밀값을 기록하지 않았습니다.
AI CLI 카드: 08. HTTPS · 다음: 09. 발표 시나리오
AI CLI 프롬프트 카드
아래 프롬프트를 복사해 실습 EC2에서 선택한 Codex, Kiro CLI, Claude Code의 대화 입력창에 붙여넣습니다. Markdown 카드 다운로드
선택한 AI CLI의 대화 입력창에 붙여넣으세요. 세 도구가 같은 프롬프트를 사용합니다.
Robot Atlas 워크숍 08장의 HTTPS 구성을 확인하세요.
교재는 ROBOT_REPO/workshop/chapters/08-cloudfront-https.md입니다.
ROBOT_LAB의 계정·도메인 바인딩과 App 출력을 먼저 확인하세요.
할 일:
- App의 PublicUrl, CloudFrontUrl을 읽어 본인 CNAME의 정확한 이름과 값을 안내합니다.
- 권한 있는 DNS NS 위임과 현재 조회 결과를 확인합니다. DNS는 수동 등록으로 남깁니다.
- 기본 CF 주소의 308 목적지가 본인 공개 주소인지 확인합니다.
- 공개 hostname의 HTTPS, healthz, readyz, 안전하게 추린 config 상태를 확인합니다.
- reference/resources.md에서 준비한 .local/tools/verify-aws.py로
실제 SG, TLS, Host 전달, WAF, OAC, 캐시와 세션 경계를 검사합니다.
정확한 구성:
CloudFront는 ALB 기본 DNS를 origin DomainName으로 사용하고 공개 Host를 전달합니다.
Viewer 인증서는 us-east-1, ALB origin 인증서는 서울이며 둘 다 본인 hostname을 포함합니다.
API는 캐시하지 않고 쿠키·Origin·Content-Type·X-CSRF-Token을 전달합니다.
Public ALB의 443은 CloudFront Prefix List만, ECS 8098은 ALB SG만 허용합니다.
별도 origin DNS, Lambda@Edge, VPC origin, Internal ALB를 추가하지 마세요.
진단:
정적 화면 정상/API 502이면 원본 DNS·인증서·Host·target을 구분하세요.
403은 WAF·origin 검증·쿠키/CSRF/Origin을 확인하세요.
연결 오류 문구만 보고 프런트 버그로 단정하지 말고 HTTP 상태와 Content-Type을 확인하세요.
기본 CF 주소의 정상 308을 없애거나 SG를 인터넷 전체로 열지 마세요.
운영 루트 배포 스크립트, 다른 참가자, 공유 네트워크/인증서를 변경하지 마세요.
비밀값이 포함된 CloudFront 설정 전체·listener rule·쿠키·CSRF를 출력하지 마세요.
본인 주소와 각 검증 결과, DNS 수동 작업의 완료 여부, 미확인 구간을 보고하세요.
읽기 기록
읽음 표시는 이 브라우저에만 저장됩니다.
실제 실습 결과는 터미널에서 확인하세요.