Infra SSOT
Infra SSOT
Section titled “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.
Endpoint-First Operator Rule
Section titled “Endpoint-First Operator Rule”FractalOps strongly owns only its runtime and execution substrate:
portalapiworkerexecution-runtimeTemporal- DB /
Hasura/Supabase Realtime DaytonaPlaywrightGrid
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.
Recent SSOT Boundaries
Section titled “Recent SSOT Boundaries”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.
Canonical Inputs
Section titled “Canonical Inputs”- 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
Canonical Operator Sequence
Section titled “Canonical Operator Sequence”Run:
make infra-validatemake infra-generate-envmake infra-env-checkmake infra-apply-ssotCUE/Helm GitOps Platform Contract
Section titled “CUE/Helm GitOps Platform Contract”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/*.cueowns environment values.platform/k8s/cue-generate.shrenders generated Helm values.platform/k8s/apps/*owns chart-local manifests.platform/k8s/argocd/runtime/resources/*.application.yamlowns sync wiring.
Regenerate environment values from the CUE SSOT:
platform/k8s/cue-generate.sh lxc-pve-labOpenBao 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:
make infra-cloudflare-planpython ops/infra/reconcile_technitium_dns.py ops/infra/topology/lxc-pve-lab.yaml --env-file .envProfile select:
make infra-validate TOPOLOGY=ops/infra/topology/lxc-pve-lab.yamlOverlay secret env (optional):
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.generatedRuntime Asset Outputs
Section titled “Runtime Asset Outputs”Generated env now carries canonical runtime asset selectors first.
FRACTALOPS_RUNTIME_ASSET_IDFRACTALOPS_RUNTIME_ASSET_ROLE
Service- or connector-specific env may still expose binding detail, but it is projection, not doctrine.
Examples:
FRACTALOPS_DAYTONA_RUNTIME_ASSET_IDFRACTALOPS_DAYTONA_RUNTIME_ASSET_ROLEFRACTALOPS_LANGBOARD_EXECUTOR_URLFRACTALOPS_LANGBOARD_HOST_HEADERFRACTALOPS_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
playwrightgridand 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
5xxshould be recorded asskip + report, not bypassed with local fallback
FractalOps main DB runtime:
runtime_dependencies.postgres.runtime_type=k8s가 canonical 기본값이다.- env 생성 시 아래 값이 topology에서 자동 파생된다.
FRACTALOPS_DATABASE_RUNTIME_TYPEFRACTALOPS_DATABASE_K8S_NAMESPACEFRACTALOPS_DATABASE_K8S_SERVICEFRACTALOPS_DATABASE_USERNAMEFRACTALOPS_DATABASE_NAMEFRACTALOPS_DATABASE_URL
- DB credential rotation truth는 OpenBao
runtime/postgresscope다.
GitOps bootstrap:
bash platform/k8s/bootstrap_fractalops_postgresql.shbash platform/k8s/bootstrap_fractalops_apps.shCloudflare 선택형 검증(토폴로지+env 최종값 확인):
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 일괄 적용:
# 기본: 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 강제 모드:
export FRACTALOPS_SECRET_REQUIRE_REF_FOR_SENSITIVE=true호스트/LXC/VM 잔존 민감정보 점검:
make infra-sensitive-audit토폴로지 규칙:
identity_plane.session_trust.enabled=false면 Cloudflare 값이 비어도 검증 통과enabled=true+provider=pomerium면 아래 env가 필요FRACTALOPS_POMERIUM_PUBLIC_URLFRACTALOPS_POMERIUM_AUTHENTICATE_SERVICE_URLFRACTALOPS_POMERIUM_ISSUERFRACTALOPS_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_PROVIDERFRACTALOPS_INTERNAL_DNS_GATEWAYFRACTALOPS_TECHNITIUM_API_URLFRACTALOPS_INTERNAL_DNS_ZONE- (
--write시)FRACTALOPS_TECHNITIUM_API_TOKEN
Portal 재현 프로필:
service_profiles.portal를 토폴로지에 넣으면 아래 env가 자동 생성된다.FRACTALOPS_PORTAL_PUBLIC_URLFRACTALOPS_PORTAL_ALLOWED_RETURN_HOSTS(portal host 자동 포함)
service_profiles.portal.runtime_type=k8s면fractalops-portalDeployment/Service가 canonical runtime이다.runtime_type=lxc|ct는 legacy 재현 경로로만 취급한다.identity_plane.session_trust.pomerium.protected_hosts에portal도메인을 포함하면 보호 대상(정책/포털 리다이렉트) SSOT를 단일화할 수 있다.
Runtime Asset Rule
Section titled “Runtime Asset Rule”Infrastructure scripts may still contain transport detail, but application-layer control must stay behind:
RuntimeAssetDescriptorRuntimeAssetControlServicefractalops runtime-assets ...
If a new operator flow needs raw infra selectors, the topology model is wrong or the adapter boundary is leaking.
GH_TOKENGITHUB_TOKEN- 프로비저닝:
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 옵션 입력 생성:
make infra-tofu-tfvars TOPOLOGY=ops/infra/topology/lxc-pve-lab.yamlLXC deploy runtime layout:
- root:
/opt/fractalops - release:
/opt/fractalops/releases/<release-id> - runtime symlink:
/opt/fractalops/current - shared env:
/opt/fractalops/shared/.env