Skip to content

operations data dashboard

JJong-03 edited this page Jun 18, 2026 · 5 revisions

운영 — Data Dashboard

Dashboard는 DNS, permanent, runtime 세 Terraform root로 분리한다. 일반적인 비용 절감 삭제는 runtime만 대상으로 한다.

Root와 소유권

Root Backend key 주요 리소스 일반 삭제
infra/data-dashboard-dns data-dashboard-dns/terraform.tfstate Route53 hosted zone 금지
infra/data-dashboard-permanent data-dashboard-permanent/terraform.tfstate Cognito, ECR, web S3, CloudFront, report DDB, OIDC roles 금지
infra/data-dashboard data-dashboard/terraform.tfstate VPC, ALB, ECS, RDS, Redis, notifier, runtime secrets/API DNS 허용

세 root 모두 kjw-aegis-terraform-state S3 backend와 lockfile을 사용한다. DNS와 permanent 주요 리소스에는 prevent_destroy가 설정돼 있다.

각 root에서 terraform init, terraform state list, refresh-only/normal plan으로 소유권과 예상 변경을 확인하기 전에는 apply/destroy하지 않는다.

최초 Build 순서

build-all.sh --data-dashboard는 runtime만 만든다. 최초 구축 또는 영구 계층 복구는 다음 순서를 지킨다.

terraform -chdir=infra/data-dashboard-dns init
terraform -chdir=infra/data-dashboard-dns plan
terraform -chdir=infra/data-dashboard-dns apply

# Registrar에서 출력된 NS를 위임하고 전파를 확인한다.

terraform -chdir=infra/data-dashboard-permanent init
terraform -chdir=infra/data-dashboard-permanent plan
terraform -chdir=infra/data-dashboard-permanent apply

scripts/build/build-data-dashboard.sh

이미 구축된 환경에서는 DNS/permanent plan이 No changes인지 확인하고 runtime script만 실행한다.

runtime build는 pending deletion 상태의 RDS/Redis secret 이름을 정리한 뒤 fmt -check, validate, saved plan, apply 순서로 실행한다.

최신 배포 기준선

2026-06-09 운영 기록 기준 Dashboard Backend는 immutable image tag sha-b029977로 배포됐고 ECS task definition revision 45에서 desired/running 2가 유지됐다. 배포 후 /healthz, /readyz, /chat/query 비인증 401, Dashboard /chat route 200을 확인했다.

이 기준선에는 /chat/query LLM Resolve 경로, S3 report linkage, /image-snapshots API/화면, backend task role의 S3 image_snapshot/ read 권한이 포함된다. 단, 실제 저장된 이미지 데이터를 Dashboard 화면에서 수기로 여는 검증은 Image Snapshot 운영의 별도 확인 항목으로 남긴다.

CI/CD

Backend workflow:

  • apps/dashboard-backend/** 변경 시 test
  • main push에서 OIDC role로 ECR 로그인
  • sha-<short-sha>latest tag push
  • 필요한 secret: AWS_OIDC_DASHBOARD_ROLE_ARN
  • Terraform의 backend image tag를 새 immutable tag로 갱신하고 runtime apply해야 ECS가 rollout된다.

Web workflow:

  • lint/test/build
  • OIDC role로 S3 sync
  • CloudFront /* invalidation
  • 필요한 secret: AWS_OIDC_DASHBOARD_WEB_ROLE_ARN
  • 필요한 variables: API/WS URL, Cognito authority/domain/client/redirect/logout, web bucket, CloudFront distribution ID

secret 값과 Cognito 사용자 식별자는 문서나 Terraform state에 기록하지 않는다.

Backend 이미지 Rollout

backend 코드가 main에 push되면 dashboard-backend workflow가 테스트 후 ECR에 sha-<7자리 git sha>latest 두 태그를 push한다. 운영 ECS 배포에는 재현 가능한 sha-* 태그만 사용하고 latest는 쓰지 않는다.

배포할 이미지 태그를 고른 뒤 운영 스크립트로 반영한다.

scripts/ops/deploy-dashboard-backend.sh sha-<git-sha>

스크립트가 보장하는 순서:

  1. ECR에 해당 sha-* 태그가 존재하는지 확인
  2. infra/data-dashboard Terraform validate
  3. backend_container_image=<ECR sha tag>로 apply → 새 task definition revision 생성
  4. ECS service rolling update 후 services-stable 대기
  5. running task image/health, ALB target health 확인
  6. /healthz, /readyz, 비인증 엔드포인트 401(/chat/query 포함), Dashboard SPA route(/chat 포함) 200 확인
  7. 동일 image override 기준 post-apply plan이 No changes인지 확인

Terraform state의 backend image tag를 immutable sha-*로 고정해 두므로, 코드 push만으로는 ECS가 자동 rollout되지 않는다. 항상 위 스크립트(=Terraform apply)를 거쳐야 새 이미지가 반영된다.

RBAC 사용자 관리

공장별 접근 제어는 네 계층이 함께 강제한다.

계층 역할
Cognito User Pool 로그인, MFA, 임시 비밀번호, 세션
RDS PostgreSQL app_user / factory / user_factory_access / audit_log
FastAPI Backend Cognito JWT sub → RDS app_user 조회 → 공장별 인가
Dashboard Web /admin/users 사용자 관리 화면

서버가 강제하는 접근 제어:

API 권한 기준
GET /factories 접근 가능한 공장만 반환
GET /factories/{id} · /history 권한 없으면 403
GET /reports · /reports/{date}/{id} 접근 가능한 공장만 / 권한 없으면 403
GET /ws/factories/{id} 구독 전 권한 검증, 없으면 close 4003
/admin/users super_admin / org_admin

초기 관리자 부트스트랩(1회):

  1. 운영자가 Cognito Hosted UI에서 로그인할 사용자를 준비하고 그 sub를 확인한다.
  2. Terraform variable rbac_bootstrap_super_admin_subs에 해당 sub임시로 설정하고 infra/data-dashboard apply 후 backend를 재배포한다.
  3. Dashboard /admin/users에서 실제 본사 관리자 계정/권한을 설정한다.
  4. rbac_bootstrap_super_admin_subs를 빈 값으로 되돌리고 다시 apply/deploy한다.

운영 주의:

  • Cognito sub는 개인 식별자이므로 문서·state에 남기지 않는다.
  • 비밀번호는 Cognito 임시 비밀번호/초기 설정 흐름으로만 다루고 RDS에는 저장하지 않는다.
  • DELETE /admin/users/{id}는 Cognito AdminDeleteUser와 RDS app_user row 삭제를 함께 수행한다. 과거 soft-delete로 남은 disabled row가 있으면 같은 email 재생성 시 Backend가 stale Cognito/RDS 정보를 정리한 뒤 신규 사용자를 만든다.
  • backend startup은 DATABASE_AUTO_CREATE_METADATA=true일 때 RBAC metadata table을 idempotent하게 생성하고 DASHBOARD_FACTORY_IDSfactory table에 동기화한다.

History 조회 경로와 알려진 이슈

/history 다중 공장 동시 조회에서 cascade 504가 발생했던 이력이 있어(2026-05-28), window 구간별로 조회 대상 read model을 분리했다(ADR — 다해상도 History 저장 구현 완료, 2026-05-29).

window 조회 read model 최대 아이템
1h HISTORY#STATE# (max_items=500 cap, ScanIndexForward=False) 500
6h GRAPH#5M# ~72
12h GRAPH#5M# ~144
24h GRAPH#5M# ~288

현행 한계(기준일 2026-05-29):

  • HISTORY#STATE TTL은 목표 2h이나 현재 48h. HISTORY_TTL_HOURS=2로 data-pipeline 재배포 + 기존 아이템 자연 만료가 필요하다. TTL이 48h인 동안은 max_items=500 cap을 유지한다.
  • window=1h에서 500개를 초과하는 스파이크 구간은 유실될 수 있다.
  • 해당 공장에 GRAPH#5M 데이터가 없으면 빈 배열을 반환하므로 차트가 빈 상태로 표시된다.

Health와 Ready

curl -fsS https://api.aegis-pi.cloud/healthz
curl -fsS https://api.aegis-pi.cloud/readyz
curl -fsSI https://dashboard.aegis-pi.cloud/
  • /healthz: 프로세스 생존과 ALB health check
  • /readyz: DynamoDB, Redis, RDS metadata 의존성 확인
  • web: CloudFront/S3 SPA HTTP 200

/healthz만 성공하고 /readyz가 실패하면 ECS를 재시작하기 전에 RDS/Redis/DynamoDB와 security group, secret 주입을 확인한다.

ECS/RDS/Redis 검증

ECS_CLUSTER="$(terraform -chdir=infra/data-dashboard output -raw ecs_cluster_name)"
ECS_SERVICE="$(terraform -chdir=infra/data-dashboard output -raw ecs_service_name)"

aws ecs describe-services \
  --cluster "${ECS_CLUSTER}" \
  --services "${ECS_SERVICE}" \
  --region ap-south-1

aws rds describe-db-instances \
  --db-instance-identifier kjw-aegis-data-pg \
  --region ap-south-1

aws elasticache describe-replication-groups \
  --replication-group-id kjw-aegis-data-redis \
  --region ap-south-1

정상 기준:

  • ECS desired/running 일치, deployment rollout 완료
  • ALB target healthy
  • RDS available
  • Redis replication group available
  • /readyzdynamodb, redis, rds_metadataok

Runtime Destroy

scripts/destroy/destroy-data-dashboard.sh --yes

이 스크립트는 infra/data-dashboard에 대해 destroy plan을 저장하고 apply한다. --yes 없이는 거부한다. 현재 스크립트에는 plan-only 옵션이 없으므로 실행 전에 별도로 아래 plan을 검토하는 것이 필수다.

terraform -chdir=infra/data-dashboard init
terraform -chdir=infra/data-dashboard plan -destroy \
  -var="dashboard_domain_name=aegis-pi.cloud"

삭제 대상은 VPC/NAT/ALB/ECS/RDS/Redis/notifier/runtime secrets/API DNS다. RDS는 final snapshot을 만들며 runtime secret은 즉시 삭제될 수 있다.

보존 대상:

  • Dashboard DNS hosted zone과 registrar NS 위임
  • Cognito users/configuration
  • backend ECR images
  • web S3 objects와 CloudFront
  • report 관련 permanent 리소스와 S3 reports/daily/ 산출물
  • Foundation S3/DynamoDB 및 data/report/image objects

terraform destroy를 permanent/DNS root에서 직접 실행하지 않는다. 해당 계층 삭제는 별도 데이터 이관, registrar 변경, state backup과 승인 절차가 필요한 영구 폐기 작업이다.

관련 문서: 통합 Build/Destroy, Dashboard 아키텍처

Aegis-Pi Wiki

· 대표 문서 목록은 홈의 문서 탐색 표 참조

시작하기

요구사항

핵심 개념

아키텍처

컴포넌트 (Edge → Cloud → Dashboard)

Dashboard & 운영

시나리오 · 사례 · 참조

Clone this wiki locally