10참가자 AWS 배포예상 약 30분, 별도 일정
관측·보안·비용 운영
CloudWatch, 이미지 검사, 비밀키와 세션, 사용량 기준을 점검합니다.
참가자 AWS 배포 트랙, 예상 약 30분입니다. 자신의 CloudFront·Fargate·Runtime이 배포되어 있어야 합니다.
서비스 상태, 이미지, 로그, 실행 보존, 과금 항목을 확인합니다. 준비된 템플릿에 없는 관측 기능이 이미 활성화되어 있다고 가정하지 않습니다.
1. 운영 상태의 기준선
set -euo pipefail
cd "$ROBOT_LAB"
test -f infra/workshop-binding.json
export ROBOT_RELEASE="$(cat .local/evidence/release.txt)"
export ROBOT_ARTIFACTS="$ROBOT_LAB/infra/.state/releases/$ROBOT_RELEASE.json"
python3 -B scripts/deploy.py status
python3 -B scripts/deploy.py configure-logs
python3 .local/tools/verify-aws.py
python3 -B scripts/deploy.py scan --artifacts "$ROBOT_ARTIFACTS"
configure-logs는 AWS 로그 보존 설정을 변경합니다. 나머지는 조회이며 verify-aws.py는 모델 호출과 새 물리 실행을 하지 않습니다. 설정·상태가 정상이라는 결과와 실제 모델 계획 성공은 별도로 기록합니다.
2. 로그 이름과 보존 기간 조회
본인 CloudFormation 출력과 Runtime ID로 로그를 찾습니다. 다음 코드는 로그 메시지나 Secret 값을 읽지 않습니다.
python3 - <<'PY'
import json, sys
from pathlib import Path
sys.path.insert(0, "infra")
from deployment import Cloud, read_config
cloud = Cloud(read_config(Path("infra/config.json")))
app = cloud.outputs("app")
runtime = cloud.outputs("agentcore")
logs = cloud.client("logs")
prefixes = [
app["LogGroupName"],
"/aws/bedrock-agentcore/runtimes/" + runtime["AgentRuntimeId"],
]
rows = []
for prefix in prefixes:
for page in logs.get_paginator("describe_log_groups").paginate(logGroupNamePrefix=prefix):
for group in page["logGroups"]:
if prefix == app["LogGroupName"] and group["logGroupName"] != prefix:
continue
rows.append({k: group.get(k) for k in
("logGroupName", "retentionInDays", "storedBytes")})
assert rows, "Owned log groups were not found"
print(json.dumps(rows, indent=2))
Path(".local/evidence/log-retention.json").write_text(json.dumps(rows, indent=2) + "\n")
assert all(r["retentionInDays"] == cloud.config["logRetentionDays"] for r in rows)
PY
장애 조사에서는 해당 로그 그룹과 발생 시간 범위를 좁힙니다. server_listening, api_request_failed, run_state_persist_failed, planner_rejected 같은 이벤트와 오류 코드를 확인합니다. 전체 요청 본문·모델 대화·쿠키·CSRF·origin 검증 헤더를 로그에 추가하지 않습니다.
기본 구성은 애플리케이션 로그와 WAF 지표를 제공합니다. Container Insights, ALB/CloudFront 접근 로그, 종단 분산 추적, 비용 경보가 모두 설치된 구성은 아닙니다. 필요하면 참가자 범위를 정한 별도 변경으로 추가합니다.
3. 세션·저장소·비밀키 확인
| 항목 | 기대 동작 |
|---|---|
| 브라우저 세션 | 서명된 Secure·HttpOnly·SameSite 쿠키 |
| 변경 요청 | 동일 Origin·JSON·해당 세션의 CSRF 필요 |
| 계획 | 서버 보관, 세션 소유, 유효기간 안의 plan ID로 실행 |
| 실행 조회 | 다른 세션의 run ID는 404 |
| 저장 설정 | DynamoDB와 S3를 함께 지정, 오류 시 로컬 저장으로 자동 전환하지 않음 |
| 물리 실패 | failed 기록과 검사 결과를 보존 |
| 취소 | 늦게 도착한 성공 응답이 cancelled를 덮어쓰지 않음 |
SessionSecret은 세션 서명용, OriginSecret은 CloudFront → ALB/API 검증용입니다. ARN으로 참조하고 ECS가 주입합니다. Secret 값을 프롬프트·소스·보고서에 붙여 넣어 맞추지 않습니다. 키를 바꾸면 기존 세션이나 원본 연결에 영향을 줄 수 있으므로 이 장에서 임의 회전하지 않습니다.
DynamoDB TTL 삭제는 즉시 수행된다고 가정하지 않습니다. 앱의 조회 만료 처리, 실제 DynamoDB TTL, S3 현재·이전 버전 lifecycle을 함께 봅니다. 보존 정책은 데이터 삭제 정책과 CloudFormation 스택 삭제 시 Retain 정책으로 나누어 확인합니다.
4. 실패·취소 검사의 근거
cd "$ROBOT_LAB"
npm test
세션 격리, 거짓 계획·추가 필드 거부, 저장 실패, 취소 경합을 확인합니다. 이 테스트가 본인 AWS의 IAM이나 실제 네트워크를 검증하는 것은 아닙니다. 라이브 검증은 11장에서 수행합니다.
429 simulation_busy는 현재 한 건의 물리 실행 제한일 수 있습니다. 참가자가 MAX_ACTIVE_RUNS, desired count, WAF 제한을 올려 우회하지 않습니다. 새 실행을 만들기 전에 기존 실행과 처리 시간을 확인합니다.
5. 비용과 되돌리기 준비
비용 산정표에 실제 조회일·리전·단위 가격·사용량을 기록합니다. 항상 켜진 Fargate·Public ALB와 IPv4, WAF·Secret, 저장소·로그, NAT 처리량, AgentCore, Bedrock 토큰을 포함합니다. 제한된 요청 수는 달러 예산 상한이 아닙니다.
이미지 롤백은 이전에 검사하고 게시한 본인 manifest를 선택해 새 변경 세트를 검토하는 방식입니다. live 태그를 덮어쓰지 않습니다. 아래 명령은 실제 AWS를 변경하므로 롤백이 필요한 경우에만 진행합니다.
read -r -p "복구할 내 이전 release 이름: " ROBOT_PREVIOUS_RELEASE
export ROBOT_PREVIOUS_ARTIFACTS="$ROBOT_LAB/infra/.state/releases/$ROBOT_PREVIOUS_RELEASE.json"
test -f "$ROBOT_PREVIOUS_ARTIFACTS"
python3 -B scripts/deploy.py scan --artifacts "$ROBOT_PREVIOUS_ARTIFACTS"
python3 -B scripts/deploy.py plan agentcore --artifacts "$ROBOT_PREVIOUS_ARTIFACTS"
변경 세트를 확인한 뒤 Runtime을 적용합니다. 이어서 App도 계획과 적용을 구분합니다.
python3 -B scripts/deploy.py apply agentcore
python3 -B scripts/deploy.py plan app --artifacts "$ROBOT_PREVIOUS_ARTIFACTS"
python3 -B scripts/deploy.py apply app
python3 -B scripts/deploy.py assets --artifacts "$ROBOT_PREVIOUS_ARTIFACTS"
python3 -B scripts/deploy.py invalidate
python3 .local/tools/verify-aws.py
이 과정은 이미 실행 중인 물리 계산의 무중단 완료를 보장하지 않습니다. 실행이 없는 시간을 선택하고 새 요청을 재검증합니다. 선택한 이전 manifest의 소스·바인딩 검사에 실패하면 가드를 제거하지 말고 보관된 소스와 릴리스를 확인합니다.
실패 시 재개
| 증상 | 다음 확인 |
|---|---|
| Runtime 로그 없음 | 실제 호출 여부와 Runtime ID, 생성 후 로그 보존 재적용 |
스캔 ACTIVE·발견 0만 표시 |
완료 시각과 전체 페이지 확인 전에는 통과로 간주하지 않음 |
| 재시작 뒤 요청 실패 | plan 유효기간, 세션 서명 키, 진행 중 lease와 실패 전이 |
| 비용이 예상보다 큼 | 가동 시간·배포 중 겹친 태스크·공개 IPv4·NAT·모델 호출량 |
| 보존 기간이 지났는데 객체 존재 | 현재/이전 버전과 비동기 삭제, 버킷 lifecycle 확인 |
완료 체크리스트
- 서비스 상태와 이미지 검사 근거를 기록했습니다.
- 본인 로그 그룹과 보존 기간을 확인했습니다.
- 세션·취소·실패·저장소 검증을 구분했습니다.
- 비용 가정과 종료 예정 시각을 기록했습니다.
- 롤백할 manifest와 실제 수행 여부를 구분했습니다.
AI CLI 카드: 10. 운영 · 다음: 11. 전체 검증
AI CLI 프롬프트 카드
아래 프롬프트를 복사해 실습 EC2에서 선택한 Codex, Kiro CLI, Claude Code의 대화 입력창에 붙여넣습니다. Markdown 카드 다운로드
선택한 AI CLI의 대화 입력창에 붙여넣으세요. 세 도구가 같은 프롬프트를 사용합니다.
Robot Atlas 워크숍 10장을 진행하세요.
ROBOT_REPO/workshop/chapters/10-operations.md와
ROBOT_REPO/workshop/reference/costs.md를 읽고
ROBOT_LAB의 참가자 바인딩과 현재 release를 확인하세요.
할 일:
- 본인 스택 상태와 fresh ECR 검사 결과를 확인합니다.
- 본인 Runtime 로그에 configure-logs를 적용하고 ECS/Runtime 로그 이름·보존 기간을 조회합니다.
- 세션/CSRF/Origin, plan 소유권, 취소 경합, S3/DynamoDB 보존 계약을 설명합니다.
- 요청된 로컬 테스트를 실행하고, 로컬 검증과 실제 AWS 검증의 차이를 기록합니다.
- 현재 가격 조회일·리전·단위와 사용량 가정을 비용 표에 정리합니다.
- 롤백이 요청된 경우에만 이전의 검사된 본인 manifest로 변경 세트를 준비하고 적용합니다.
주의할 판단:
ACTIVE와 발견 0만으로 ECR 검사를 완료로 보지 말고 완료 시각·전체 페이지를 확인하세요.
기본 앱 로그/WAF 지표가 종단 추적·Container Insights·접근 로그·비용 경보를 뜻하지 않습니다.
DynamoDB TTL, S3 lifecycle, CloudFormation Retain은 서로 다른 정책입니다.
Fargate를 중지해도 ALB·IPv4·저장소·Secret 등 비용이 남을 수 있습니다.
과거 가격이나 단일 호출 시간을 현재 보장값으로 쓰지 마세요.
경계:
실제 AWS 변경은 본인 ROBOT_LAB의 준비된 배포 스크립트와 요청 범위로 제한하세요.
자동 스케일링, WAF 제한 해제, Secret 회전, 계정 전체 ECR/Inspector 설정을 임의로 바꾸지 마세요.
자격 증명·Secret 값·모델 원문·쿠키·CSRF·원본 검증 헤더를 읽거나 출력하지 마세요.
진행 중인 물리 작업을 무중단으로 복구했다고 주장하지 마세요.
실행 명령·검증 결과·보존/비용 가정·롤백 수행 여부·남은 항목을 보고하세요.
읽기 기록
읽음 표시는 이 브라우저에만 저장됩니다.
실제 실습 결과는 터미널에서 확인하세요.