Skip to content

Infra SSOT

This document is the operator-facing runtime topology handoff.

Use it with:

The canonical execution noun is runtime asset. Do not reintroduce raw vmid, raw namespace, or connector-local node mappings as product-level control vocabulary.

FractalOps strongly owns only its runtime and execution substrate:

  • portal
  • api
  • worker
  • execution-runtime
  • Temporal
  • DB / Hasura / Supabase Realtime
  • Daytona
  • PlaywrightGrid

Most other systems are integration endpoints.

  • They are described by URL, auth, and health contracts.
  • They may still appear in topology and env generation.
  • That does not make them product-owned child systems.

Current operator SSOT layers:

  • runtime_ssot
    • public URL, internal URL, and local URL defaults
  • principal_defaults
    • CLI/system/audit principal defaults
  • topology + generated env
    • runtime asset selectors and endpoint bindings

Operator documentation and scripts should prefer those boundaries over raw fallback strings.

  • Topology files:
    • ops/infra/topology/lxc-prod.yaml (10.10.10 기준)
    • ops/infra/topology/lxc-pve-lab.yaml (현재 PVE lab 기준)
  • Validator: ops/infra/validate_topology.py

Default profile in Makefile: ops/infra/topology/lxc-pve-lab.yaml

Run:

Terminal window
make infra-validate
make infra-generate-env
make infra-env-check
make infra-apply-ssot

Platform reconciliation is owned by CUE-authored Helm values, Helm charts, and Argo CD GitOps sync. Host scripts remain bootstrap or break-glass tools, not recurring desired-state owners.

  • platform/k8s/environments/lxc-pve-lab/*.cue owns environment values.
  • platform/k8s/cue-generate.sh renders generated Helm values.
  • platform/k8s/apps/* owns chart-local manifests.
  • platform/k8s/argocd/runtime/resources/*.application.yaml owns sync wiring.

Regenerate environment values from the CUE SSOT:

Terminal window
platform/k8s/cue-generate.sh lxc-pve-lab

OpenBao remains the secret authority. Secret scopes and delivery contracts stay in GitOps/controller surfaces; generated values must carry refs, not live secret payloads.

Optional preview and DNS helpers:

Terminal window
make infra-cloudflare-plan
python ops/infra/reconcile_technitium_dns.py ops/infra/topology/lxc-pve-lab.yaml --env-file .env

Profile select:

Terminal window
make infra-validate TOPOLOGY=ops/infra/topology/lxc-pve-lab.yaml

Overlay secret env (optional):

Terminal window
python -m fractalops.cli runtime-contract render-env ops/infra/topology/lxc-pve-lab.yaml \
--template .env.example \
--overlay ops/infra/env/lab.secrets.env \
--output .env.generated

Generated env now carries canonical runtime asset selectors first.

  • FRACTALOPS_RUNTIME_ASSET_ID
  • FRACTALOPS_RUNTIME_ASSET_ROLE

Service- or connector-specific env may still expose binding detail, but it is projection, not doctrine.

Examples:

  • FRACTALOPS_DAYTONA_RUNTIME_ASSET_ID
  • FRACTALOPS_DAYTONA_RUNTIME_ASSET_ROLE
  • FRACTALOPS_LANGBOARD_EXECUTOR_URL
  • FRACTALOPS_LANGBOARD_HOST_HEADER
  • FRACTALOPS_LANGBOARD_VERIFY_TLS

public URL and executor URL are separate contracts. Machine sync must use the executor path when edge security or browser routing would break automation. Local/internal URLs are separate again from both public and executor URLs; they are implementation detail and should come from SSOT helpers rather than ad-hoc literals. Temporal follows the same rule: FRACTALOPS_TEMPORAL_EXECUTOR_ADDRESS is the machine-facing contract, while any cluster-internal service hostname is implementation detail and must not leak into app-layer defaults.

Shared validation rule:

  • integration validation targets managed runtime assets and service endpoints
  • playwrightgrid and solution runtimes are shared execution surfaces, not host-local test daemons
  • local Docker-backed smoke is not the canonical path on this host
  • shared service 5xx should be recorded as skip + report, not bypassed with local fallback

FractalOps main DB runtime:

  • runtime_dependencies.postgres.runtime_type=k8s 가 canonical 기본값이다.
  • env 생성 시 아래 값이 topology에서 자동 파생된다.
    • FRACTALOPS_DATABASE_RUNTIME_TYPE
    • FRACTALOPS_DATABASE_K8S_NAMESPACE
    • FRACTALOPS_DATABASE_K8S_SERVICE
    • FRACTALOPS_DATABASE_USERNAME
    • FRACTALOPS_DATABASE_NAME
    • FRACTALOPS_DATABASE_URL
  • DB credential rotation truth는 OpenBao runtime/postgres scope다.

GitOps bootstrap:

Terminal window
bash platform/k8s/bootstrap_fractalops_postgresql.sh
bash platform/k8s/bootstrap_fractalops_apps.sh

Cloudflare 선택형 검증(토폴로지+env 최종값 확인):

Terminal window
make infra-cloudflare-plan TOPOLOGY=ops/infra/topology/lxc-pve-lab.yaml
# 토큰 유효성까지 함께 확인
make infra-cloudflare-plan-verify TOPOLOGY=ops/infra/topology/lxc-pve-lab.yaml
# 변경 예정 작업 미리보기(dry-run)
make infra-cloudflare-apply-dry-run TOPOLOGY=ops/infra/topology/lxc-pve-lab.yaml
# 실제 반영(write)
make infra-cloudflare-apply TOPOLOGY=ops/infra/topology/lxc-pve-lab.yaml
# env 파일 오버라이드
ENV_FILE=/tmp/fractalops.env.generated make infra-cloudflare-plan TOPOLOGY=ops/infra/topology/lxc-pve-lab.yaml

수동 절차 없이 SSOT 일괄 적용:

Terminal window
# 기본: validate -> env 생성 -> env 검증 -> edge(dry-run)
make infra-apply-ssot TOPOLOGY=ops/infra/topology/lxc-pve-lab.yaml
# edge 단계 제외(로컬/오프라인 점검)
NO_EDGE=1 make infra-apply-ssot TOPOLOGY=ops/infra/topology/lxc-pve-lab.yaml
# 실제 edge 반영(write) + OpenBao 스코프 동기화
WRITE_EDGE=1 OPENBAO_SCOPES=connectors,connectors/daytona make infra-apply-ssot TOPOLOGY=ops/infra/topology/lxc-pve-lab.yaml
# env 평문 민감값/URL을 ref 치환 + OpenBao 동기화까지 일괄 수행
WRITE_EDGE=1 OPENBAO_SCOPES=connectors,connectors/daytona \
make infra-apply-ssot TOPOLOGY=ops/infra/topology/lxc-pve-lab.yaml HARDEN_ENV_REFS=1

민감키 ref 강제 모드:

Terminal window
export FRACTALOPS_SECRET_REQUIRE_REF_FOR_SENSITIVE=true

호스트/LXC/VM 잔존 민감정보 점검:

Terminal window
make infra-sensitive-audit

토폴로지 규칙:

  • identity_plane.session_trust.enabled=false면 Cloudflare 값이 비어도 검증 통과
  • enabled=true + provider=pomerium면 아래 env가 필요
    • FRACTALOPS_POMERIUM_PUBLIC_URL
    • FRACTALOPS_POMERIUM_AUTHENTICATE_SERVICE_URL
    • FRACTALOPS_POMERIUM_ISSUER
    • FRACTALOPS_POMERIUM_JWKS_URL
    • (FRACTALOPS_CF_MANAGE_TUNNEL_INGRESS=true일 때) FRACTALOPS_POMERIUM_EDGE_ORIGIN_URL
  • DNS 자동화까지 켜면 FRACTALOPS_CF_ZONE_ID + FRACTALOPS_CF_TUNNEL_ID가 필수
  • 터널 인그레스까지 켜려면 FRACTALOPS_CF_MANAGE_TUNNEL_INGRESS=true + FRACTALOPS_CF_TUNNEL_ID가 필요
  • internal DNS는 internal_dns.provider=technitium일 때 아래 env/토폴로지 값이 필요
    • FRACTALOPS_INTERNAL_DNS_PROVIDER
    • FRACTALOPS_INTERNAL_DNS_GATEWAY
    • FRACTALOPS_TECHNITIUM_API_URL
    • FRACTALOPS_INTERNAL_DNS_ZONE
    • (--write 시) FRACTALOPS_TECHNITIUM_API_TOKEN

Portal 재현 프로필:

  • service_profiles.portal를 토폴로지에 넣으면 아래 env가 자동 생성된다.
    • FRACTALOPS_PORTAL_PUBLIC_URL
    • FRACTALOPS_PORTAL_ALLOWED_RETURN_HOSTS (portal host 자동 포함)
  • service_profiles.portal.runtime_type=k8sfractalops-portal Deployment/Service가 canonical runtime이다.
  • runtime_type=lxc|ct는 legacy 재현 경로로만 취급한다.
  • identity_plane.session_trust.pomerium.protected_hostsportal 도메인을 포함하면 보호 대상(정책/포털 리다이렉트) SSOT를 단일화할 수 있다.

Infrastructure scripts may still contain transport detail, but application-layer control must stay behind:

  • RuntimeAssetDescriptor
  • RuntimeAssetControlService
  • fractalops runtime-assets ...

If a new operator flow needs raw infra selectors, the topology model is wrong or the adapter boundary is leaking.

  • GH_TOKEN
  • GITHUB_TOKEN
  • 프로비저닝:
Terminal window
make github-runner-ensure TOPOLOGY=ops/infra/topology/lxc-pve-lab.yaml

커넥터 모드 규칙:

  • connector_inventory[].mode는 커넥터의 도메인 분류(예: project, jit)로 유지한다.
  • 실행 연동 모드 오버라이드는 connector_inventory[].connector_mode 또는 integration_mode로만 지정한다.
    • 허용값: scim|scim_projected|poll|jit|ui_only|project|hybrid|runtime_gateway
  • connector_mode=scim이고 scim_base_url이 있으면, 해당 커넥터의 *_EXECUTOR_URL이 SCIM base로 자동 전환된다.
  • connector_mode=runtime_gateway는 CLIProxy처럼 credential/runtime gateway 역할을 하는 커넥터에만 사용한다.
  • Nexus는 추가로 FRACTALOPS_NEXUS_URL, FRACTALOPS_NEXUS_SCIM_BASE_URL을 함께 생성한다.

OpenTofu 옵션 입력 생성:

Terminal window
make infra-tofu-tfvars TOPOLOGY=ops/infra/topology/lxc-pve-lab.yaml

LXC deploy runtime layout:

  • root: /opt/fractalops
  • release: /opt/fractalops/releases/<release-id>
  • runtime symlink: /opt/fractalops/current
  • shared env: /opt/fractalops/shared/.env