AWS Multi-Account Overview¶
CWIQ.IO uses a three-account AWS Organization structure: management (never touch), shared-services (central tools), and dev (application workloads).
Account Summary¶
| Account | ID | CLI Profile | Purpose |
|---|---|---|---|
| Management | 921838417607 |
(default — see warning) | AWS Organization root, billing, SCPs |
| Shared-Services | 308188966547 |
shared-services |
GitLab, Vault, Nexus, Authentik, observability, Tailscale routers, Route53 zones |
| Dev | 686123185567 |
dev |
Orchestrator app, LangFuse, Demo, EKS cluster, CI/CD runners |
NEVER use the default AWS profile
The default AWS CLI profile (921838417607) is the management/root account. It contains orphaned duplicate Route53 zones and IAM resources. Any operation run against this account is likely wrong and may modify stale resources.
Always specify an explicit profile:
Verification Before Any AWS Operation¶
Run this before every terraform plan, terraform apply, or AWS CLI sequence:
# Shared-services operations
aws sts get-caller-identity --profile shared-services
# Expected: Account = 308188966547
# Dev operations
aws sts get-caller-identity --profile dev
# Expected: Account = 686123185567
Account Purposes in Detail¶
Shared-Services (308188966547)¶
Central infrastructure shared across all environments:
- GitLab (
gitlab.shared.cwiq.io) — source of truth, CI/CD, container registry - Vault (
vault.shared.cwiq.io) — secrets management for all environments - Nexus (
nexus.shared.cwiq.io) — artifact repository (Docker, RPM, PyPI, npm) - Authentik (
sso.shared.cwiq.io) — SSO identity provider (HA, 2 instances) - Observability stack — Grafana, Prometheus, Loki, Alertmanager
- Ansible server (
ansible-shared-cwiq-io) — Ansible playbook execution - Icinga (
icinga.shared.cwiq.io) — health check master - SonarQube (
sonarqube.shared.cwiq.io) — code quality - DefectDojo (
defectdojo.shared.cwiq.io) — security findings - Route53 zones —
shared.cwiq.io(public + private),cwiq.io(root) - Tailscale subnet router — bridges shared VPC (
10.0.0.0/16) to the mesh
Dev Account (686123185567)¶
Application workloads for the development environment:
- Orchestrator DEV (
orchestrator-dev-cwiq-io) — main platform server - Orchestrator Demo (
orchestrator-demo-cwiq-io) — demo environment server - LangFuse (
langfuse-dev-cwiq-io) — LLM observability - Identity-DB (
identity-db-dev-cwiq-io) — sssd-db-identity PostgreSQL backend - EKS cluster (
cwiq-dev-eks-cluster) — GitLab Kubernetes runners (K8s 1.31, Karpenter v1.1.1) - Route53 zones —
dev.cwiq.io(public + private) - Tailscale subnet router — bridges dev VPC (
10.1.0.0/16) to the mesh
VPC Peering¶
The two VPCs are connected via VPC peering for lower-level, non-Tailscale connectivity (e.g., EKS pods reaching Shared services over VPC private IPs):
| Attribute | Value |
|---|---|
| Peering ID | pcx-0535aabbb2629e915 |
| Shared VPC | 10.0.0.0/16 |
| Dev VPC | 10.1.0.0/16 |
| Direction | Bidirectional routes |
Tailscale vs VPC Peering
Most cross-account access uses Tailscale (servers, SSH, observability). VPC peering is used for EKS runner pods and services that cannot run Tailscale. See Cross-VPC Connectivity for the decision guide.
Terraform Profile Configuration¶
All Terraform modules specify the AWS profile in their provider.tf. Do not run Terraform without verifying the profile first.
# Example provider.tf — shared-services module
provider "aws" {
region = "us-west-2"
profile = "shared-services"
}
If a module's provider.tf is missing the profile attribute, stop and ask before proceeding — never fall back to the default profile.
Related Pages¶
- Multi-Account Setup — Organization structure and IAM cross-account roles
- VPC & Networking — Subnet design, CIDR allocations
- Route53 DNS — Zone structure, split-horizon DNS
- Cost Management — Instance pricing, Savings Plans