IaC Principles¶
Every infrastructure change MUST be made through Infrastructure as Code. Direct console, SSH, or manual changes are prohibited and will cause configuration drift.
The Rule¶
CWIQ.IO infrastructure is managed entirely through code. There is one tool for each domain:
| Domain | Tool | Repository |
|---|---|---|
| AWS resources (VPC, EC2, IAM, S3, RDS, Route53) | Terraform | terraform-plan/ |
| Server configuration, application deployment | Ansible | ansible-playbooks/ |
| Database schemas and migrations | SQLAlchemy Alembic | platform/server/ |
| DNS records | Terraform | terraform-plan/ |
| Tailscale ACLs | Terraform Tailscale provider | terraform-plan/ |
No exceptions. If a resource exists in production that is not defined in one of these repositories, it will eventually be overwritten or deleted.
Prohibited Actions¶
Non-DEV Environment Setup — Strictly Ansible Only¶
All orchestrator environments other than DEV (Demo, Staging, Production) MUST be configured entirely through Ansible playbooks.
CRITICAL: Non-DEV Environments
Never use SCP, rsync, or SSH to manually configure non-DEV servers. Never clone source repositories on a server to deploy from. All configuration changes use Ansible playbooks only.
| Prohibited | Correct Alternative |
|---|---|
scp config.yml server:/etc/app/ |
Bundle in Ansible role files/ directory |
ssh server "systemctl restart app" |
Ansible service module in a playbook |
| Clone repo on server to deploy | RPM packages from Nexus, deployed via Ansible |
docker run directly on server |
Ansible role with Docker Compose template |
Application Deployment — Never Manually¶
CRITICAL: Application Deployment
Never install packages, edit config files, or run Docker commands directly on application servers.
| Prohibited | Correct Alternative |
|---|---|
pip install / npm install on server |
CI/CD builds artifacts; Ansible deploys dependencies |
| Edit files directly on remote servers via SSH | Edit in repo, commit, deploy via CI/CD pipeline |
| Modify systemd service files on servers | Update in ansible-playbooks/{service}/, deploy via Ansible |
| Modify nginx configs on servers | Update in ansible-playbooks/, deploy via Ansible |
Run docker commands on application servers |
Use GitLab CI/CD deploy-* jobs |
Ansible Server — Strict Rules¶
CRITICAL: Ansible Server
Only one directory is allowed for running playbooks on the ansible server.
| Prohibited | Correct Alternative |
|---|---|
git clone outside /data/ansible/cwiq-ansible-playbooks/ |
Only use the official playbooks directory |
Run ansible-playbook from /home/ansible/ |
Use ansible-helper function (sets up venv + Vault creds) |
| Checkout a feature branch on the ansible server | Merge to main first, then git pull on ansible server |
The ansible-helper function:
1. cd /data/ansible/cwiq-ansible-playbooks
2. source .venv/bin/activate
3. Logs into Vault and exports ROLE_ID / SECRET_ID
Infrastructure — Never Touch the Console¶
CRITICAL: AWS Resources
Never create or modify AWS resources in the console. Use Terraform.
| Prohibited | Correct Alternative |
|---|---|
| Create EC2 instance in AWS Console | Terraform module in terraform-plan/organization/environments/ |
| Manually edit security groups | Update Terraform, apply via CLI |
| Create DNS records in Route53 Console | Terraform DNS modules |
| Modify Tailscale ACLs in web UI | Terraform Tailscale provider |
Acceptable SSH Usage¶
SSH to servers is permitted for the following read-only and operational purposes only:
| Acceptable Use | Examples |
|---|---|
| Reading logs | journalctl, docker logs, tail |
| Checking status | systemctl status, docker ps |
| Running Ansible FROM the ansible server | ssh ansible@ansible-shared-cwiq-io then ansible-helper |
| Emergency diagnostics | top, df -h, free -m, netstat |
Running Ansible from the ansible server uses the single approved pattern:
ssh ansible@ansible-shared-cwiq-io
ansible-helper
# Now in /data/ansible/cwiq-ansible-playbooks with venv activated and Vault authenticated
git pull origin main
ansible-playbook cwiq-orchestrator/playbooks/deploy-service.yml -v