07참가자 AWS 배포/예상 약 40분, 별도 일정

Private Fargate와 물리 엔진

ARM64 웹·MuJoCo 컨테이너와 보안 그룹, 단일 실행 제한을 구성합니다.

참가자 AWS 배포 · 별도 트랙아직 읽지 않음

참가자 AWS 배포 트랙, 예상 약 40분입니다. Foundation, 검사된 세 이미지와 AgentCore Runtime이 준비되어 있어야 합니다.

Node API와 MuJoCo를 같은 ARM64 Fargate 태스크에 배치합니다. 두 컨테이너는 loopback으로 통신하며 웹 포트만 ALB에서 접근할 수 있습니다. 현재 App 템플릿은 Fargate·ALB·CloudFront·정적 S3를 함께 생성하므로 이 장에서 Edge와 App을 배포하고, 다음 장에서 수동 DNS와 공개 HTTPS를 검증합니다.

1. 배포 전 구성 읽기

터미널bash
VSCode Server 터미널에서 실행
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 lint
python3 -B scripts/deploy.py dry-plan --stack app
python3 -B scripts/deploy.py scan --artifacts "$ROBOT_ARTIFACTS"
항목 이 실습의 설정
ALB 두 Public Subnet의 internet-facing ALB, HTTPS 443
ALB SG AWS 관리형 CloudFront origin-facing Prefix List에서 오는 443만 허용
ECS SG ALB SG에서 오는 웹 8098만 허용
Fargate 두 Private Subnet 중 배치, Public IP 비활성, ARM64, desired count 1
태스크 자원 기본 1 vCPU·2 GiB, web·simulation과 계정 부가 에이전트의 예약량 확인
MuJoCo 같은 태스크의 127.0.0.1:8099, 외부 포트 매핑 없음
저장 실행 메타데이터 DynamoDB, 재생 JSON 비공개 S3
준비 검사 ALB /readyz가 시뮬레이터 연결도 확인

Fargate 웹 컨테이너는 8098을 사용합니다. 01장의 참가자별 로컬 포트는 개발 호스트의 충돌 방지용이며 컨테이너 내부 포트와 다릅니다. 이 MuJoCo 경로에는 GPU가 필요하지 않습니다. Isaac Sim GPU 과정은 교재 목차의 별도 확장 트랙에서 진행합니다.

2. WAF Edge 스택 준비

CloudFront용 WAF 스택은 us-east-1에 생성됩니다. 참가자가 명령마다 리전을 바꾸는 대신 배포기가 스택 종류에 맞춰 선택합니다.

터미널bash
VSCode Server 터미널에서 실행
python3 -B scripts/deploy.py plan edge

변경 세트에서 본인 Web ACL과 규칙을 확인한 뒤 적용합니다.

터미널bash
VSCode Server 터미널에서 실행
python3 -B scripts/deploy.py apply edge
python3 -B scripts/deploy.py status --stack edge

3. App 계획 검토·적용

터미널bash
VSCode Server 터미널에서 실행
python3 -B scripts/deploy.py plan app --artifacts "$ROBOT_ARTIFACTS"

infra/.state/plans/app.json에서 아래 내용을 확인합니다.

  • 새 ALB, ALB/ECS 보안 그룹, Cluster·Service·TaskDefinition, 실행 역할·태스크 역할·로그가 본인 이름입니다.
  • 이미지 URI가 05장의 digest이며, AgentCore와 저장소 입력은 본인 스택 출력입니다.
  • CloudFront Alias와 두 인증서는 05장에 고정한 실습 hostname에 대응합니다.
  • S3 정적 자산은 OAC로 전달하며 실행 기록 버킷은 공개하지 않습니다.
  • Route53 레코드, VPC, Subnet, NAT 생성·변경이 없습니다.
터미널bash
VSCode Server 터미널에서 실행
python3 -B scripts/deploy.py apply app
python3 -B scripts/deploy.py status --stack app \
  > .local/evidence/app-status.json
python3 -m json.tool .local/evidence/app-status.json

첫 생성은 CREATE_COMPLETE, 이후 갱신은 UPDATE_COMPLETE를 확인합니다. 스택 작업은 CLI가 종료되어도 AWS에서 이어질 수 있으므로 실패나 중단 뒤에는 상태를 먼저 조회합니다.

4. 실제 Fargate와 target 확인

다음 조회는 본인 스택 출력을 사용합니다. 환경 변수 전체나 Secret 값을 출력하지 않습니다.

터미널bash
VSCode Server 터미널에서 실행
cd "$ROBOT_LAB"
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")))
out = cloud.outputs("app")
service = cloud.client("ecs").describe_services(
    cluster=out["ClusterName"], services=[out["ServiceName"]])["services"][0]
network = service["networkConfiguration"]["awsvpcConfiguration"]
task = cloud.client("ecs").describe_task_definition(
    taskDefinition=service["taskDefinition"])["taskDefinition"]
targets = cloud.client("elbv2").describe_target_health(
    TargetGroupArn=out["TargetGroupArn"])["TargetHealthDescriptions"]
evidence = {
    "desired": service["desiredCount"], "running": service["runningCount"],
    "pending": service["pendingCount"], "network": network,
    "architecture": task["runtimePlatform"]["cpuArchitecture"],
    "containers": [{"name": c["name"], "ports": c.get("portMappings", [])}
                   for c in task["containerDefinitions"]],
    "targets": [t["TargetHealth"] for t in targets],
}
print(json.dumps(evidence, indent=2))
assert (evidence["desired"], evidence["running"], evidence["pending"]) == (1, 1, 0)
assert network["assignPublicIp"] == "DISABLED"
assert set(network["subnets"]) == set(cloud.config["privateSubnetIds"])
assert evidence["architecture"] == "ARM64"
assert targets and all(t["TargetHealth"]["State"] == "healthy" for t in targets)
PY

안정화 중에는 pending이나 initial 상태가 보일 수 있습니다. 상태를 다시 조회하고, 완료되지 않은 배포를 성공으로 기록하지 않습니다.

5. 같은 release의 화면 공개

터미널bash
VSCode Server 터미널에서 실행
python3 -B scripts/deploy.py assets --artifacts "$ROBOT_ARTIFACTS"
python3 -B scripts/deploy.py invalidate
python3 -B scripts/deploy.py configure-logs
python3 .local/tools/verify-aws.py --skip-http

assets는 빌드한 web 이미지에서 배포 파일을 꺼내 본인의 정적 버킷에 게시합니다. invalidate는 본인의 Distribution에만 캐시 무효화를 요청합니다.

--skip-http는 AWS 구성을 조회하지만 공개 DNS나 브라우저 동작을 확인하지 않습니다. 다음 장의 공개 HTTPS 검증은 별도로 수행해야 합니다.

동시 실행과 장애의 의미

애플리케이션은 동시에 물리 실행 한 건을 허용합니다. 계획은 웹 프로세스에 보관하고, 실행 입장 제한은 DynamoDB lease로 관리합니다. MuJoCo sidecar도 한 번에 한 요청을 처리합니다. desired count만 늘리거나 제한을 2로 바꾸는 확장은 이 실습 범위에 포함하지 않습니다.

실행 취소는 메타데이터에 먼저 반영됩니다. 이미 진행 중인 물리 계산이 끝나거나 제한 시간에 도달할 때까지 용량이 즉시 반환되지 않을 수 있습니다. 배포로 태스크가 교체되면 진행 중 실행은 실패할 수 있으며, 저장된 완료 기록과 세션 소유권은 유지되어야 합니다.

실패 시 재개

증상 확인할 근거
CannotPullContainerError digest·ARM64, ECR 실행 역할, Private Subnet의 NAT/endpoint 경로
ResourceInitializationError 이미지·Secret·로그 접근 경로와 실행 역할
target unhealthy /readyz, simulation 시작, loopback URL, 웹 8098
pendingCount가 줄지 않음 Fargate 할당량, Subnet IP, 태스크 이벤트
429 simulation_busy 다른 실행 종료를 기다린 뒤 제한적으로 재시도
Secret 조회 권한 오류 ECS 실행 역할과 본인 Secret ARN. 값 복사로 우회하지 않음

완료 체크리스트

  • Edge·App 스택이 완료 상태입니다.
  • Private ARM64 Fargate 1개와 healthy target을 확인했습니다.
  • MuJoCo의 외부 포트 매핑이 없습니다.
  • 같은 release의 이미지와 정적 자산을 게시했습니다.
  • AWS 구성 검증과 아직 남은 DNS·모델·브라우저 검증을 구분했습니다.

AI CLI 카드: 07. Fargate · 다음: 08. CloudFront·HTTPS

AI CLI 프롬프트 카드

아래 프롬프트를 복사해 실습 EC2에서 선택한 Codex, Kiro CLI, Claude Code의 대화 입력창에 붙여넣습니다. Markdown 카드 다운로드

Codex프롬프트 입력

선택한 AI CLI의 대화 입력창에 붙여넣으세요. 세 도구가 같은 프롬프트를 사용합니다.

Robot Atlas 워크숍 07장의 참가자 배포를 도와주세요.
ROBOT_REPO/workshop/chapters/07-fargate.md를 읽고 ROBOT_LAB의 바인딩·manifest를 확인하세요.

할 일:
1. 준비된 App 템플릿이 Fargate, ALB, CloudFront, 정적 S3를 함께 생성하는 의존성을 설명합니다.
2. 본인 Edge 스택을 계획·검토·적용한 뒤 App도 같은 순서로 진행합니다.
3. 이미지 digest, Foundation/Runtime 출력이 모두 본인 자원인지 확인합니다.
4. 실제 태스크 수·ARM64·Private Subnet·Public IP 비활성·healthy target을 조회합니다.
5. 동일 release의 정적 자산을 게시하고, 본인 Distribution만 무효화합니다.
6. reference/resources.md에서 준비한 .local/tools/verify-aws.py --skip-http 결과와
   아직 남은 공개 DNS/HTTPS 검증을 구분합니다.

유지할 구조:
CloudFront → AWS 관리형 origin-facing Prefix List → Public ALB SG 443
→ ECS SG 8098 → Private Fargate의 Node API.
MuJoCo는 같은 태스크의 loopback 8099이며 외부 포트 매핑이 없습니다.
VPC origin이나 Internal ALB로 변경하지 마세요.
현재는 단일 태스크·단일 물리 실행입니다. 제한이나 desired count를 올려 오류를 우회하지 마세요.
이 MuJoCo 경로는 GPU 없이 동작하며 Isaac Sim/EKS는 별도 트랙입니다.

경계:
변경은 본인 ROBOT_LAB에 한정하고 실제 클라우드 작업은 그 app의 scripts/deploy.py만 사용하세요.
기존 네트워크·인증서·DNS·운영 서비스·다른 참가자 자원을 변경하지 마세요.
Secret 값과 전체 컨테이너 환경·CloudFront 원본 헤더를 출력하지 마세요.
CREATE_IN_PROGRESS나 unhealthy를 완료로 기록하지 마세요.

실행 명령·종료 상태·소유 자원·상태 검증·미검증 항목과 다음 재개 위치를 보고하세요.

읽기 기록

읽음 표시는 이 브라우저에만 저장됩니다.
실제 실습 결과는 터미널에서 확인하세요.