---
name: avizmarlon/iac-first-commit
source: https://app.decimal.ai/s/avizmarlon-iac-first-commit@1/SKILL.md
source_sha256: 8036d95e04ba
---

## Infrastructure-as-Code (IaC) from First Commit

**Core principle:** Every new project, from its first commit, must be **fully rebuildable from zero** using only `git clone` + a single, documented bootstrap command. All infrastructure state is declarative, version-controlled, and reproducible without tribal knowledge or manual steps.

### Why this matters

- **Reproducibility:** A new team member (or the original author months later) can spin up the entire environment deterministically.
- **Reliability:** Infrastructure changes are reviewed in pull requests, tested in CI, and rollback-safe.
- **Disaster recovery:** Loss of a server or credential requires only re-running the bootstrap process.
- **Onboarding:** No "run these commands manually" instructions; no "remember to configure this first."

### Mental test before scaffolding any project

*"If another person or an AI agent needed to rebuild this project from zero right now, would `git clone <repo> && ./bootstrap.sh` be sufficient? Or are there undocumented, manual steps?"*

If the answer is "there are manual steps," the project lacks proper IaC coverage.

### Tool selection by context

Use the IaC tool native to your infrastructure platform. There is no one-size-fits-all tool — the platform dictates the choice:

| Context | Native IaC Tool | Example |
|---|---|---|
| VPS / Linux server | Ansible (configuration) + Terraform (if cloud provisioning) | `ansible-playbook site.yml` |
| Frontend SaaS (Next.js, Vite, etc.) | Platform config-as-code + GitHub Actions | Vercel/Netlify/Cloudflare Pages deployment config |
| Serverless APIs (AWS Lambda, Cloudflare Workers) | SST / SAM / CDK / Wrangler | `sst deploy` or `wrangler deploy` |
| Mobile (iOS, Android, Expo) | Fastlane + EAS/Code Push config | `fastlane build` + `eas build` |
| Kubernetes | ArgoCD / Flux + Helm charts | GitOps with declarative manifests in git |
| ML / data pipelines | DVC + MLflow + Airflow DAGs | Reproducible training/inference pipelines |
| Browser extension / desktop app | Build manifest + bundler config + CI/CD | GitHub Actions release workflow |
| Static docs / sites | GitHub Actions + hosting provider config | Build → upload → serve, automated |

**Key principle:** Choose based on the infrastructure platform, not on what the team prefers. The tool should map 1:1 to the target platform's native declarative model.

### Minimum directory structure for any new project

Adapt this template to your context, but all elements should exist by first commit:

```
project-root/
├── infra/                    # Declarative infrastructure code
│   ├── main.tf              # (Terraform) or
│   ├── site.yml             # (Ansible) or
│   ├── sst.config.ts        # (SST) or equivalent
│   └── secrets.sops.yaml    # encrypted secrets (NEVER plaintext)
├── .github/workflows/        # CI/CD pipelines
│   ├── deploy.yml
│   └── test.yml
├── scripts/
│   └── bootstrap.sh          # Single command to rebuild from zero
├── docs/
│   ├── architecture.md       # System design, deployment diagram, key decisions
│   ├── decisions.md          # Architecture Decision Records (ADRs)
│   └── runbooks/             # Operations: "how to X" (restart service, add user, etc.)
│       ├── deploy.md
│       ├── troubleshoot.md
│       └── backup-restore.md
├── README.md                 # Top section: "How to bootstrap from zero"
├── CHANGELOG.md              # Version history and deployed changes
└── [project files]
```

### Bootstrap script — the single point of entry

Your `scripts/bootstrap.sh` (or equivalent for your language/OS) should be **the only documentation users need** to get from zero to running.

**Requirements:**
- Idempotent: safe to run multiple times (e.g., `mkdir -p` not `mkdir`)
- Self-documenting: comments explain what each section does
- Fail-fast: exit on first error (`set -e` in bash)
- Secrets handling: load from environment variables or secure vaults, never commit plaintext
- Validation: verify prerequisites (Go version, Docker running, credentials available) before proceeding

**Example structure:**

```bash
#!/bin/bash
set -e

echo "Bootstrap: project-name"

# 1. Check prerequisites
if ! command -v docker &> /dev/null; then
  echo "ERROR: docker not found. Install Docker and try again."
  exit 1
fi

# 2. Fetch dependencies
go mod download
npm ci

# 3. Set up infrastructure
terraform -chdir=infra/ init
terraform -chdir=infra/ apply -auto-approve

# 4. Configure database
./scripts/migrate-db.sh

# 5. Load secrets from vault (not committed)
source <(sops -d secrets.sops.yaml | envsubst)

# 6. Start services
docker-compose up -d

echo "✓ Bootstrap complete. Services running at http://localhost:8080"
```

### Secrets management

- **Never commit plaintext credentials** to git — not even in `.env.example`.
- Use encrypted files (sops + age, Sealed Secrets, HashiCorp Vault, AWS Secrets Manager).
- Store encryption keys in a secure vault (Bitwarden, 1Password, GitHub Environments).
- Document in bootstrap how to obtain/inject secrets: `source <(vault kv get --json secret/data | envsubst)`.
- Test bootstrap against a clean environment to ensure it doesn't silently assume pre-configured credentials.

### Documentation requirements

1. **README.md** — "How to bootstrap from zero" is the **first section**, not buried.
2. **docs/architecture.md** — System design, key components, deployment topology, why you made certain choices.
3. **docs/decisions.md** or **docs/adrs/** — Why was tool X chosen over Y? Why this database? Decisions should be reviewable in git history.
4. **docs/runbooks/** — Common operational tasks ("restart the service," "add a user," "inspect logs," "backup the database").
5. **CHANGELOG.md** — Changes by version; helps the team track what shipped when.

### Anti-patterns — forbidden

- ✗ "I configured it by hand and I remember what I did" — if you remember, write it down as IaC.
- ✗ README that says "see wiki" or "ask in Slack" for bootstrap steps.
- ✗ Architecture decisions buried in chat history or git commit messages (use an ADR document).
- ✗ Running `npm install` or `pip install` without pinning versions in lockfiles.
- ✗ Mixing secrets plaintext with code; using `.env` files committed to git.
- ✗ A bootstrap that works "most of the time" but sometimes requires manual fixes — make it deterministic.
- ✗ Test bootstrap only on "the developer's machine" — test it fresh against a clean environment in CI.

### How to test your IaC

1. **Clean-room test:** Spin up a fresh VM, clone your repo, run bootstrap, verify everything works.
2. **CI integration:** Add bootstrap to your CI pipeline so it runs on every commit — catches regressions early.
3. **Idempotence test:** Run bootstrap twice in a row; the second run should be a no-op or safely re-apply the same state.
4. **Disaster recovery:** Simulate failure of a key component (database, service) and verify recovery procedures are documented and work.

### Applying this skill to different project types

**Web application (Next.js → Vercel):**
- `infra/`: Vercel project config (environment variables, domains, build settings) as infrastructure-as-code.
- `scripts/bootstrap.sh`: Clone repo, `npm ci`, deploy via Vercel CLI or GitHub Actions.
- `docs/deployment.md`: How to promote from staging to production.

**Backend service (Go API → Kubernetes):**
- `infra/`: Helm chart, kustomize overlays, or plain YAML manifests; stored in git.
- `scripts/bootstrap.sh`: Install kubectl/Helm, apply manifests, wait for rollout, run migrations.
- `docs/runbooks/scale.md`: How to add replicas, upgrade image, perform canary deployments.

**Microservices (Docker Compose):**
- `docker-compose.yml`: All services, networks, volumes defined.
- `.env.example`: Template for environment variables (never include secrets).
- `scripts/bootstrap.sh`: Build images, run migrations, start containers.
- `docs/local-development.md`: How to develop and test locally.

**Terraform-managed cloud infrastructure:**
- `infra/terraform/`: Organized by environment (dev/, staging/, prod/).
- `scripts/bootstrap.sh`: `terraform init` → `terraform plan` → `terraform apply`.
- `docs/decisions.md`: Why this VPC design, why this RDS tier, etc.
- **State management:** Store `.tfstate` in a remote backend (S3, Terraform Cloud), never commit locally.

---

## Application

This principle applies to **all new projects**, regardless of team size, project scope, or platform. An AI agent scaffolding a project should include this structure from the first commit, not retrofit it later.

**When to invoke this skill:**
- Scaffolding a new project or repository
- Choosing infrastructure tools for a new context
- Planning bootstrap automation for an existing project that lacks it
- Reviewing infrastructure code for reproducibility and idempotence
- Preparing a project for team handoff or long-term maintenance