docs(10_Wiki): 위키 전체 재구성 — Topic_* 폴더를 4개 카테고리로 통합 + 대규모 중복 제거
Topic_Agent/Topic_Blog/Topics/Topics_Biz/Topics_Meeting/Topics_Rag의 마크다운 지식 문서를 Topic_General/Topic_Programming/Topic_Graphic/Topic_Business 4개 카테고리로 재분류. - 중복 제거: frontmatter의 status:duplicate/merged + duplicate_of/redirect_to 필드로 자기 자신을 중복으로 선언한 리다이렉트 stub 1032개 제거, 완전 동일 내용 파일 472개 제거, 동일 파일명·다른 내용 충돌 시 더 큰(완전한) 버전만 유지(162개 제거) — 총 1639개 중복 제거. - 분류: 폴더 단위로 명확한 항목(AI_and_ML/Coding/Architecture 등 → Programming, Comfyui/Visual_Effects → Graphic, Topics_Biz/Topics_Meeting/사업 등 → Business, Poetic_Blog_Writing/창의성/Game_Design 등 → General)은 폴더 우선순위로, 나머지 혼재 폴더(Topic_Agent/Topic_Blog/Topics 루트/Thinking & Reasoning/Other/UI_UX_Assets)는 title/tags 키워드 스코어링으로 파일 단위 분류(불명확한 경우 General로 폴백). 원본 폴더명은 "From_*" 서브폴더로 보존해 추적 가능성 유지. - 최종 배치: Programming 2784 / General 1608 / Graphic 285 / Business 249 = 4926개 문서. - 에이전트 운영 상태(.astra/.agent/.obsidian/sessions/memory/_company/docs/lessons/_shared/src)는 지식 콘텐츠가 아니므로 재분류 대상에서 제외하고 원위치 유지. - Topics/Topic_email(상위 보호 폴더 Topic_email과 파일명 100% 중복) 삭제 — 보호 폴더 자체는 미변경. - 완전히 비게 된 Topic_Agent/Topic_Blog/Topics_Biz/Topics_Rag 폴더 제거.
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
---
|
||||
id: devops-terraform-patterns
|
||||
title: Terraform — 모듈 / 워크스페이스 / state
|
||||
category: Coding
|
||||
status: draft
|
||||
source_trust_level: B
|
||||
verification_status: conceptual
|
||||
created_at: 2026-05-09
|
||||
updated_at: 2026-05-09
|
||||
tags: [devops, terraform, iac, vibe-coding]
|
||||
tech_stack: { language: "HCL / Terraform", applicable_to: ["DevOps"] }
|
||||
applied_in: []
|
||||
aliases: [terraform, IaC, state file, workspace, module, OpenTofu]
|
||||
---
|
||||
|
||||
# Terraform
|
||||
|
||||
> Infra 를 코드로. **Module = 재사용 단위, State = 진실 source, Workspace = 환경 분리**. 1.x 부터 OpenTofu 로 fork — 둘 다 호환. State 는 항상 remote backend.
|
||||
|
||||
## 📖 핵심 개념
|
||||
- HCL: 선언형. resource / data / module / variable / output.
|
||||
- State: `terraform.tfstate` — 무엇이 만들어졌는지.
|
||||
- Plan / Apply: dry-run / 실행.
|
||||
- Module: 재사용 가능한 폴더 묶음.
|
||||
- Workspace: 같은 코드 다른 state.
|
||||
|
||||
## 💻 코드 패턴
|
||||
|
||||
### 폴더 구조
|
||||
```
|
||||
infra/
|
||||
modules/
|
||||
rds/
|
||||
main.tf
|
||||
variables.tf
|
||||
outputs.tf
|
||||
envs/
|
||||
dev/
|
||||
main.tf
|
||||
backend.tf
|
||||
terraform.tfvars
|
||||
prod/
|
||||
main.tf
|
||||
backend.tf
|
||||
terraform.tfvars
|
||||
```
|
||||
|
||||
### Module
|
||||
```hcl
|
||||
# modules/rds/main.tf
|
||||
variable "name" { type = string }
|
||||
variable "instance_class" { type = string; default = "db.t4g.micro" }
|
||||
variable "vpc_security_group_ids" { type = list(string) }
|
||||
variable "subnet_ids" { type = list(string) }
|
||||
|
||||
resource "aws_db_subnet_group" "this" {
|
||||
name = "${var.name}-subnets"
|
||||
subnet_ids = var.subnet_ids
|
||||
}
|
||||
|
||||
resource "aws_db_instance" "this" {
|
||||
identifier = var.name
|
||||
engine = "postgres"
|
||||
engine_version = "16"
|
||||
instance_class = var.instance_class
|
||||
allocated_storage = 20
|
||||
storage_encrypted = true
|
||||
vpc_security_group_ids = var.vpc_security_group_ids
|
||||
db_subnet_group_name = aws_db_subnet_group.this.name
|
||||
backup_retention_period = 7
|
||||
deletion_protection = true
|
||||
skip_final_snapshot = false
|
||||
username = "app"
|
||||
manage_master_user_password = true
|
||||
}
|
||||
|
||||
output "endpoint" { value = aws_db_instance.this.endpoint }
|
||||
```
|
||||
|
||||
### Env 호출
|
||||
```hcl
|
||||
# envs/prod/main.tf
|
||||
module "rds_main" {
|
||||
source = "../../modules/rds"
|
||||
name = "app-prod"
|
||||
instance_class = "db.r7g.large"
|
||||
vpc_security_group_ids = [aws_security_group.db.id]
|
||||
subnet_ids = data.aws_subnets.private.ids
|
||||
}
|
||||
|
||||
output "rds_endpoint" { value = module.rds_main.endpoint }
|
||||
```
|
||||
|
||||
### Backend (remote state)
|
||||
```hcl
|
||||
# envs/prod/backend.tf
|
||||
terraform {
|
||||
required_version = ">= 1.6"
|
||||
backend "s3" {
|
||||
bucket = "tf-state-myco-prod"
|
||||
key = "main.tfstate"
|
||||
region = "us-east-1"
|
||||
dynamodb_table = "tf-locks"
|
||||
encrypt = true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Provider lock
|
||||
```hcl
|
||||
terraform {
|
||||
required_providers {
|
||||
aws = { source = "hashicorp/aws"; version = "~> 5.0" }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`.terraform.lock.hcl` 은 commit.
|
||||
|
||||
### Variables / tfvars
|
||||
```hcl
|
||||
# variables.tf
|
||||
variable "env" { type = string }
|
||||
variable "region" { type = string; default = "us-east-1" }
|
||||
|
||||
# terraform.tfvars (NOT committed if secrets)
|
||||
env = "prod"
|
||||
```
|
||||
|
||||
### Workflow
|
||||
```bash
|
||||
terraform init
|
||||
terraform fmt -recursive
|
||||
terraform validate
|
||||
terraform plan -out=tfplan
|
||||
terraform apply tfplan
|
||||
```
|
||||
|
||||
### Secrets
|
||||
```hcl
|
||||
# ❌ tfvars 안 secret
|
||||
db_password = "..."
|
||||
|
||||
# ✅ env or AWS Secrets Manager
|
||||
data "aws_secretsmanager_secret_version" "db" {
|
||||
secret_id = "app/db"
|
||||
}
|
||||
|
||||
resource "aws_db_instance" "this" {
|
||||
password = jsondecode(data.aws_secretsmanager_secret_version.db.secret_string)["password"]
|
||||
}
|
||||
```
|
||||
|
||||
### tfsec / checkov (보안 검사)
|
||||
```bash
|
||||
tfsec .
|
||||
checkov -d .
|
||||
```
|
||||
|
||||
CI 에서 plan + tfsec 자동.
|
||||
|
||||
### Drift detection
|
||||
```bash
|
||||
terraform plan -detailed-exitcode
|
||||
# exit 0 = no change, 2 = drift
|
||||
```
|
||||
|
||||
## 🤔 의사결정 기준
|
||||
| 환경 | 분리 |
|
||||
|---|---|
|
||||
| 작은 팀, 1 env | workspace 또는 단일 폴더 |
|
||||
| Multi-env | 폴더 분리 (envs/dev, envs/prod) |
|
||||
| 큰 조직 / 격리 | 별도 state file + IAM 분리 |
|
||||
| Shared infra (VPC) | 별도 module + remote state read |
|
||||
| Pulumi vs Terraform | Pulumi = TS/Python, Terraform = HCL |
|
||||
| OpenTofu | 라이센스 자유 — 같이 호환 |
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **State 로컬 파일**: 잃으면 인프라 분실. 항상 remote.
|
||||
- **State lock 없음**: 동시 apply 시 깨짐. dynamodb 또는 S3 locking.
|
||||
- **Secret tfvars 에 commit**: leak.
|
||||
- **수동 console 변경 + apply**: drift, 다음 apply 가 덮음.
|
||||
- **Module 거대 (1000줄)**: 작게 단위.
|
||||
- **Resource 직접 dev/prod 혼용**: 분리.
|
||||
- **Provider version unlock**: 무작위 brake.
|
||||
- **`terraform destroy` 실수**: prod 보호 — `prevent_destroy` lifecycle.
|
||||
|
||||
## 🤖 LLM 활용 힌트
|
||||
- modules/ + envs/ + remote state.
|
||||
- secret = AWS Secrets Manager / Vault.
|
||||
- CI = init + fmt + validate + plan + tfsec.
|
||||
|
||||
## 🔗 관련 문서
|
||||
- [[DevOps_IaC_Drift_Detection]]
|
||||
- [[DevOps_Secrets_Rotation_Automation]]
|
||||
- [[DevOps_Kubernetes_Basics]]
|
||||
Reference in New Issue
Block a user