| name | spec-driven-infra |
| description | Creates infrastructure specs before applying changes. Use when starting a new infra project, adding significant resources, or when requirements are unclear. Use when the change affects production or spans multiple services. |
Spec-Driven Infra
Overview
์ธํ๋ผ ๋ณ๊ฒฝ ์ ์ ๊ตฌ์กฐํ๋ ์คํ์ ์์ฑํ๋ ์ํฌํ๋ก์ฐ์
๋๋ค.
์คํ์ ๋ฌด์์, ์, ์ด๋ป๊ฒ ๋ณ๊ฒฝํ๋์ง์ ํฉ์ ๋ฌธ์์ด๋ฉฐ, ๋ณ๊ฒฝ์ ๋ธ๋์คํธ ๋ ๋์ด์ค์ ๋กค๋ฐฑ ๊ณํ์ ํฌํจํฉ๋๋ค.
When to Use
- ์๋ก์ด ์ธํ๋ผ ๊ตฌ์ฑ (VPC, ํด๋ฌ์คํฐ, ์๋น์ค)
- ํ๋ก๋์
ํ๊ฒฝ ๋ณ๊ฒฝ
- ์ฌ๋ฌ ์๋น์ค์ ์ํฅ์ ์ฃผ๋ ๋ณ๊ฒฝ
- ์๊ตฌ์ฌํญ์ด ๋ชจํธํ๊ฑฐ๋ ๋ถ์์ ํ ๋
- ์ํคํ
์ฒ ๊ฒฐ์ ์ด ํ์ํ ๋
์ ์ฉํ์ง ์๋ ๊ฒฝ์ฐ: ํ๊ทธ ๋ณ๊ฒฝ, ๋จ์ผ ํ๋ผ๋ฏธํฐ ์์ , ๋ช
ํํ ๋ฒ๊ทธ ์์ .
Gated Workflow
SPECIFY โโโ PLAN โโโ TASKS โโโ IMPLEMENT
โ โ โ โ
v v v v
Review Review Review Verify
๊ฐ ๋จ๊ณ๋ฅผ ๊ฒ์ฆ ์์ด ๋์ด๊ฐ์ง ์์ต๋๋ค.
Phase 1: Specify
Assumptions ๋จผ์ ๋ช
์
ASSUMPTIONS:
1. VPC CIDR์ 10.0.0.0/16 ์ฌ์ฉ (๊ธฐ์กด ๋คํธ์ํฌ์ ์ถฉ๋ ์์)
2. Multi-AZ ๊ตฌ์ฑ (ap-northeast-2a, 2c)
3. NAT Gateway๋ AZ๋น 1๊ฐ
4. Terraform backend๋ ๊ธฐ์กด S3 + DynamoDB ์ฌ์ฉ
โ ํ์ธ ํ์ํ ํญ๋ชฉ์ด ์์ผ๋ฉด ์ง์ ํด ์ฃผ์ธ์.
Spec Template
# Infra Spec: [์ ๋ชฉ]
## ๋ชฉ์
[๋ฌด์์ ์ ๊ตฌ์ถ/๋ณ๊ฒฝํ๋์ง. ๋น์ฆ๋์ค ์๊ตฌ์ฌํญ.]
## ํ์ฌ ์ํ
[ํ์ฌ ์ธํ๋ผ ๊ตฌ์ฑ. ๋ค์ด์ด๊ทธ๋จ ํฌํจ ๊ถ์ฅ.]
## ๋ชฉํ ์ํ
[๋ณ๊ฒฝ ํ ์ธํ๋ผ ๊ตฌ์ฑ. ๋ค์ด์ด๊ทธ๋จ ํฌํจ.]
## ๊ธฐ์ ์คํ
- IaC: Terraform 1.x / Ansible 2.x
- Provider: AWS (ap-northeast-2)
- ๋ชจ๋: [์ฌ์ฉํ ๋ชจ๋ ๋ชฉ๋ก]
## ๋ฆฌ์์ค ๋ชฉ๋ก
| ๋ฆฌ์์ค | ์ด๋ฆ ๊ท์น | ์๋ |
|------------------|-------------------------|------|
| VPC | prd-vpc-main | 1 |
| Subnet (Private) | prd-subnet-private-{az} | 2 |
| Security Group | prd-sg-{service} | N |
## ๋คํธ์ํฌ ์ค๊ณ
| CIDR | ์ฉ๋ | AZ |
|--------------|----------------|----|
| 10.0.0.0/16 | VPC | - |
| 10.0.1.0/24 | Public Subnet | 2a |
| 10.0.2.0/24 | Public Subnet | 2c |
| 10.0.11.0/24 | Private Subnet | 2a |
| 10.0.12.0/24 | Private Subnet | 2c |
## ๋ณด์ ์๊ตฌ์ฌํญ
- [ ] ์ต์ ๊ถํ ์์น (IAM)
- [ ] ์ํธํ (at rest + in transit)
- [ ] ๋คํธ์ํฌ ๊ฒฉ๋ฆฌ (Private Subnet)
- [ ] ๊ฐ์ฌ ๋ก๊ทธ (CloudTrail, VPC Flow Logs)
## ๋ชจ๋ํฐ๋ง ์๊ตฌ์ฌํญ
- [ ] CloudWatch Alarm: CPU, Memory, Disk
- [ ] ๋ก๊ทธ ์์ง: CloudWatch Logs / ์ธ๋ถ ์์คํ
- [ ] ์๋ฆผ ์ฑ๋: Slack / Email
## ๋ธ๋์คํธ ๋ ๋์ด์ค
- ์ํฅ ์๋น์ค: [๋ชฉ๋ก]
- ๋ค์ดํ์: [์์ ์๊ฐ]
- ์ํฅ ์ฌ์ฉ์: [๋ฒ์]
## ๋น์ฉ ์ถ์
- ์๊ฐ ์์ ๋น์ฉ: [AWS Pricing Calculator ๋๋ infracost ๊ฒฐ๊ณผ]
- ๊ธฐ์กด ๋๋น ์ฆ๊ฐ: [+/- ๊ธ์ก]
- ๋น์ฉ ์ต์ ํ: [Reserved/Spot/Savings Plan ์ ์ฉ ์ฌ๋ถ]
## Boundaries
- Always: IaC๋ก๋ง ๋ณ๊ฒฝ, plan ํ์ธ ํ apply, ๋กค๋ฐฑ ๊ณํ ์๋ฆฝ
- Ask first: ํ๋ก๋์
apply, ๋ฐ์ดํฐ ๋ง์ด๊ทธ๋ ์ด์
, SG ์ญ์
- Never: ์ฝ์ ์๋ ๋ณ๊ฒฝ, ์ํฌ๋ฆฟ ํ๋์ฝ๋ฉ, ๋กค๋ฐฑ ๊ณํ ์์ด ์ ์ฉ
## ์ฑ๊ณต ๊ธฐ์ค
- [ ] terraform plan โ ์์ ๋ฆฌ์์ค๋ง ์์ฑ
- [ ] ์๋น์ค health check ํต๊ณผ
- [ ] ๋ชจ๋ํฐ๋ง ์๋ฆผ ์ ์ ๋์
- [ ] ๋ณด์ ๊ฐ์ฌ ํต๊ณผ
## ๋ฏธ๊ฒฐ ์ฌํญ
- [ํ์ธ ํ์ํ ํญ๋ชฉ]
Ansible Spec Template
Terraform/AWS๊ฐ ์๋ Ansible role/playbook ์ค๊ณ ์ ์ฌ์ฉํฉ๋๋ค.
# Ansible Spec: [์ ๋ชฉ]
## ๋ชฉ์
[๋ฌด์์ ์ ์๋ํํ๋์ง. ์๋ ์์
๋๋น ์ด์ .]
## ๋์ ํ๊ฒฝ
| ํญ๋ชฉ | ๋ด์ฉ |
|--------------|-----------------------------------------|
| ๋์ OS | Ubuntu 22/24, Rocky 9, AmazonLinux 2023 |
| ์ฐ๊ฒฐ ๋ฐฉ์ | SSH / docker / winrm |
| ๊ถํ ์์น | become: true (sudo/runas) |
| Ansible ๋ฒ์ | 2.15+ |
## Inventory ๊ตฌ์กฐ
[group_name]
host1 ansible_host=10.x.x.x
[group_name:vars]
ansible_user=ansible
ansible_ssh_private_key_file=~/.ssh/id_ed25519
## Role / Playbook ๊ตฌ์กฐ
playbooks/
โโโ site.yml # ์ ์ฒด ์ง์
์
โโโ vars/
โ โโโ common.yml # ํ๋ฌธ ๋ณ์
โ โโโ secrets.yml # vault ์ํธํ
โโโ roles/
โโโ role_name/
โโโ tasks/main.yml
โโโ handlers/main.yml
โโโ defaults/main.yml
โโโ templates/
## ๋ฉฑ๋ฑ์ฑ ๋ณด์ฅ ๊ณํ
| Task | ๋ฉฑ๋ฑ์ฑ ๋ฐฉ๋ฒ |
|-------------|----------------------------------|
| ํจํค์ง ์ค์น | `state: present` |
| ํ์ผ ์์ฑ | `creates:` ๋๋ `stat` ์ ํ ์ฒดํฌ |
| ์๋น์ค ์์ | `state: started` |
| ์ค์ ๋ณ๊ฒฝ | `lineinfile` / `template` |
## OS๋ณ ๋ถ๊ธฐ ๊ณํ
| ์์
| Debian | RedHat |
|----------|--------|-------------|
| ํจํค์ง | `apt` | `dnf`/`yum` |
| ์๋น์ค๋ช
| `ssh` | `sshd` |
| ๊ทธ๋ฃน | `sudo` | `wheel` |
## ์ํฌ๋ฆฟ ๊ด๋ฆฌ
- vault ์ํธํ ๋์: [๋ชฉ๋ก]
- vault password ๊ด๋ฆฌ ๋ฐฉ๋ฒ: [ํ์ผ/ํ๊ฒฝ๋ณ์/CI Secret]
## ํ
์คํธ ๊ณํ
- [ ] `--syntax-check` ํต๊ณผ
- [ ] `--check` dry-run ํต๊ณผ
- [ ] Molecule ํ
์คํธ (๋์ OS๋ณ)
- [ ] ์ค์ ํ๊ฒฝ ์ ์ฉ ํ ์ฌ์คํ โ changed=0 ํ์ธ
## ๋กค๋ฐฑ ๊ณํ
- ์ค์ ํ์ผ: `backup: true` ์ต์
์ผ๋ก ์๋ ๋ฐฑ์
- ํจํค์ง: `state: absent`๋ก ์ ๊ฑฐ
- ์ ์ฒด ๋กค๋ฐฑ: [๋ฐฉ๋ฒ]
## ์ฑ๊ณต ๊ธฐ์ค
- [ ] ์ ์ฒด OS `failed=0`
- [ ] ์ฌ์คํ ์ `changed=0` (๋ฉฑ๋ฑ์ฑ)
- [ ] `--check` ๋ชจ๋ ํธํ
- [ ] vault ์ํฌ๋ฆฟ ํ๋ฌธ ๋
ธ์ถ ์์
Phase 2: Plan
์คํ ํ์ ํ ๊ธฐ์ ๊ตฌํ ๊ณํ์ ์์ฑํฉ๋๋ค.
- ๋ชจ๋ ๊ตฌ์กฐ ๊ฒฐ์
- ์์กด์ฑ ๊ทธ๋ํ ์์ฑ
- ํ๊ฒฝ๋ณ ์ ์ฉ ์์ ๊ฒฐ์
- ๋ฆฌ์คํฌ ์๋ณ ๋ฐ ๋์ ๋ฐฉ์
Phase 3: Tasks
skill://planning-and-breakdown ์คํฌ์ ์ฌ์ฉํ์ฌ ํ์คํฌ๋ก ๋ถํดํฉ๋๋ค.
Phase 4: Implement
skill://incremental-change ์คํฌ์ ์ฌ์ฉํ์ฌ ์ ์ง์ ์ผ๋ก ์ ์ฉํฉ๋๋ค.
Spec as Living Document
- ๊ฒฐ์ ๋ณ๊ฒฝ ์ ์คํ ๋จผ์ ์
๋ฐ์ดํธ
- ๋ฒ์ ๋ณ๊ฒฝ ์ ์คํ์ ๋ฐ์
- ์คํ์ ๋ฒ์ ๊ด๋ฆฌ์ ํฌํจ
- PR์์ ์คํ ์น์
์ฐธ์กฐ
Common Rationalizations
| Rationalization | Reality |
|---|
| "๊ฐ๋จํ ๋ณ๊ฒฝ์ด๋ผ ์คํ ๋ถํ์ํฉ๋๋ค" | ๊ฐ๋จํด๋ ๋ธ๋์คํธ ๋ ๋์ด์ค์ ๋กค๋ฐฑ ๊ณํ์ ํ์ํฉ๋๋ค. |
| "์ฝ๋ ๋จผ์ ์์ฑํ๊ณ ๋ฌธ์ํํ๊ฒ ์ต๋๋ค" | ๊ทธ๊ฑด ๋ฌธ์ํ์ด์ง ์คํ์ด ์๋๋๋ค. ์คํ์ ๊ฐ์น๋ ์ฌ์ ํฉ์์
๋๋ค. |
| "์๊ตฌ์ฌํญ์ด ๋ฐ๋ ํ
๋ฐ ์คํ์ ์ ์๋๊น" | ๋ฐ๋๋ฉด ์คํ์ ์
๋ฐ์ดํธํฉ๋๋ค. ์๋ ๊ฒ๋ณด๋ค ๋ซ์ต๋๋ค. |
| "์๊ฐ์ด ์์ต๋๋ค" | 15๋ถ ์คํ์ด ์ ์๊ฐ ์ฅ์ ๋ณต๊ตฌ๋ฅผ ๋ฐฉ์งํฉ๋๋ค. |
Red Flags
- ์คํ ์์ด terraform ์ฝ๋ ์์ฑ ์์
- ๋ธ๋์คํธ ๋ ๋์ด์ค ๋ฏธํ์
- ๋กค๋ฐฑ ๊ณํ ์์
- ๋ณด์ ์๊ตฌ์ฌํญ ๋๋ฝ
- ๋ชจ๋ํฐ๋ง ๊ณํ ์์
- "๋น์ฐํ ์๊ฒ ์ง" ๊ฐ์ ์ผ๋ก ์งํ
Verification
๊ตฌํ ์์ ์ ํ์ธ: