공통 사전 준비

확인할 것:
- terraform -version  → 1.6.0 이상인지
- aws --version
- aws sts get-caller-identity  → 내 계정 맞는지

모르면 찾아볼 것:
- "aws cli configure 방법"
- "terraform install mac/windows"

Terraform 주의사항 (해서는 안되는 것 목록)

1. AWS Access Key / Secret Key 코드에 직접 쓰기
   
   # 이렇게 하면 절대 안됩니다!!!
   provider "aws" {
     access_key = "AKIAIOSFODNN7EXAMPLE"
     secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
   }
   
   → aws configure 로 로컬에 설정하면
     provider에 키 안 써도 자동으로 읽음

2. terraform.tfvars 깃허브에 올리기
   → DB 비밀번호 등 민감한 값이 들어감
   → .gitignore에 *.tfvars 추가 필수

3. .terraform/ 폴더 깃허브에 올리기
   → 용량 크고 불필요
   → .gitignore에 .terraform/ 추가 필수

4. terraform.tfstate 깃허브에 올리기
   → 인프라 상태 정보 + 비밀번호가 평문으로 들어있음
   → 반드시 S3 backend 써야 하는 이유
   → .gitignore에 *.tfstate, *.tfstate.backup 추가 필수

5. main 브랜치에 직접 push
   → 인프라 코드는 반드시 PR + 팀원 리뷰 후 merge
   → 잘못 apply 되면 복구가 어려우니 주의

.gitignore 필수 항목

# Terraform
.terraform/
.terraform.lock.hcl
*.tfstate
*.tfstate.backup
*.tfvars
override.tf
override.tf.json

레포 구조

infra/
├── backend.tf
├── providers.tf
├── variables.tf
├── terraform.tfvars   ← .gitignore 처리 필수!
├── main.tf
├── outputs.tf
└── modules/
    ├── vpc/
    ├── eks/
    ├── rds/
    ├── ecr/
    └── iam/
각 모듈 안에 main.tf / variables.tf / outputs.tf 3개씩

Backend

S3 버킷이랑 DynamoDB 테이블을 먼저 AWS 콘솔이나 CLI로 만들어야 함
(Terraform으로 Terraform 상태를 관리할 수 없으므로)

backend.tf 에 들어갈 내용:
- S3 버킷 이름
- tfstate 파일 경로 (key)
- 리전
- DynamoDB 테이블 이름
- encrypt = true

힌트: terraform backend s3 공식 문서 참고

VPC 모듈

만들어야 하는 리소스:
□ aws_vpc
□ aws_subnet × 6개 (퍼블릭 2, 프라이빗 2, DB 2)
□ aws_internet_gateway
□ aws_eip + aws_nat_gateway × 1개 (비용 절감!)
□ aws_route_table × 2개 (퍼블릭/프라이빗)
□ aws_route_table_association × 4개

⚠️ 중요 힌트:
EKS ALB가 서브넷을 자동 감지하려면 태그가 필요
- 퍼블릭 서브넷: "kubernetes.io/role/elb" = "1"
- 프라이빗 서브넷: "kubernetes.io/role/internal-elb" = "1"
이 태그 없으면 나중에 ALB가 만들어지지 않음

outputs.tf 에서 꺼내야 할 것:
- vpc_id
- public_subnet_ids (list)
- private_subnet_ids (list)
- db_subnet_ids (list)
→ 다른 모듈에서 이걸 가져다 사용

ECR 모듈

만들어야 하는 리소스:
□ aws_ecr_repository
□ aws_ecr_lifecycle_policy

힌트:
- image_tag_mutability = "MUTABLE" (처음엔 이걸로)
- scan_on_push = true
- lifecycle policy: 최근 10개만 유지하도록

outputs.tf 에서 꺼내야 할 것:
- repository_url → CI에서 이 주소로 pus