Terraform ๋ฉด์ ‘ ์งˆ๋ฌธ ์™„๋ฒฝ ๊ฐ€์ด๋“œ 2026: Infrastructure as Code ํ•ต์‹ฌ ์ •๋ฆฌ

Terraform ๋ฉด์ ‘์—์„œ ์ž์ฃผ ์ถœ์ œ๋˜๋Š” ์ƒํƒœ ๊ด€๋ฆฌ, ๋ชจ๋“ˆ, ์›Œํฌ์ŠคํŽ˜์ด์Šค, ํ”„๋กœ๋ฐ”์ด๋”, IaC ๋ชจ๋ฒ” ์‚ฌ๋ก€๋ฅผ ์ฒด๊ณ„์ ์œผ๋กœ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค. 2026๋…„ Terraform 1.14 ๋ฐ HCP Terraform ์ตœ์‹  ๋‚ด์šฉ์„ ๋ฐ˜์˜ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

Terraform Infrastructure as Code ๋ฉด์ ‘ ์ค€๋น„ - HCL ๊ตฌ์„ฑ๊ณผ ํด๋ผ์šฐ๋“œ ํ”„๋กœ๋น„์ €๋‹ ๋‹ค์ด์–ด๊ทธ๋žจ

Terraform ๋ฉด์ ‘ ์งˆ๋ฌธ์€ ํ›„๋ณด์ž๊ฐ€ ํด๋ผ์šฐ๋“œ ์ธํ”„๋ผ๋ฅผ ์„ ์–ธ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ , ์ƒํƒœ(state)๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๋‹ค๋ฃจ๋ฉฐ, ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“ˆ์„ ์„ค๊ณ„ํ•˜๋Š” ๋Šฅ๋ ฅ์„ ํ‰๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. Terraform 1.14์—์„œ ๋ชจ๋“ˆ ์†Œ์Šค์— ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๊ณ  HCP Terraform์ด ๊ด€๋ฆฌํ˜• ์‹คํ–‰ ํ”Œ๋žซํผ์„ ํ™•์žฅํ•จ์— ๋”ฐ๋ผ, 2026๋…„ ๋ฉด์ ‘๊ด€์€ ํ›„๋ณด์ž์—๊ฒŒ ๊ธฐ๋ณธ์ ์ธ HCL ์ง€์‹๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ง„ํ™”ํ•˜๋Š” IaC ์ƒํƒœ๊ณ„์— ๋Œ€ํ•œ ์ดํ•ด๋„๊นŒ์ง€ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค.

๋ฉด์ ‘๊ด€์ด ์‹ค์ œ๋กœ ํ‰๊ฐ€ํ•˜๋Š” ํฌ์ธํŠธ

Terraform ๋ฉด์ ‘์—์„œ ๋ฌธ๋ฒ• ์•”๊ธฐ๋ฅผ ์ค‘์‹œํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๋“œ๋ญ…๋‹ˆ๋‹ค. ํ•ต์‹ฌ ํ‰๊ฐ€ ์˜์—ญ์€ ์ƒํƒœ ๊ด€๋ฆฌ ์ „๋žต, ๋ชจ๋“ˆ ์„ค๊ณ„ ํŒจํ„ด, ์‹œํฌ๋ฆฟ ์ฒ˜๋ฆฌ, ๊ทธ๋ฆฌ๊ณ  ์šด์˜ ํ™˜๊ฒฝ์—์„œ์˜ plan/apply ์‚ฌ์ดํด์— ๋Œ€ํ•œ ์ถ”๋ก  ๋Šฅ๋ ฅ์ž…๋‹ˆ๋‹ค.

๋ชจ๋“  ํ›„๋ณด์ž๊ฐ€ ์•Œ์•„์•ผ ํ•  Terraform ํ•ต์‹ฌ ๊ฐœ๋…

Terraform์ด๋ž€ ๋ฌด์—‡์ด๋ฉฐ ๋‹ค๋ฅธ IaC ๋„๊ตฌ์™€ ์–ด๋–ป๊ฒŒ ๋‹ค๋ฆ…๋‹ˆ๊นŒ?

Terraform์€ HCL(HashiCorp Configuration Language)๋กœ ์ž‘์„ฑ๋œ ๊ตฌ์„ฑ ํŒŒ์ผ์„ ํ†ตํ•ด ํด๋ผ์šฐ๋“œ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์„ ์–ธ์  Infrastructure as Code ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. Ansible์ด๋‚˜ ์…ธ ์Šคํฌ๋ฆฝํŠธ์™€ ๊ฐ™์€ ๋ช…๋ นํ˜•(imperative) ๋„๊ตฌ์™€ ๋‹ฌ๋ฆฌ, Terraform์€ ํ˜„์žฌ ์ธํ”„๋ผ๋ฅผ ์ถ”์ ํ•˜๋Š” ์ƒํƒœ ํŒŒ์ผ์„ ์œ ์ง€ํ•˜๊ณ  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ ์šฉํ•˜๊ธฐ ์ „์— ์ฐจ์ด์ ("plan")์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ์ฐจ๋ณ„์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. Terraform์€ ํด๋ผ์šฐ๋“œ ๋น„์ข…์†์ (AWS, Azure, GCP ๋ฐ ์ˆ˜๋ฐฑ ๊ฐœ์˜ ํ”„๋กœ๋ฐ”์ด๋”๋ฅผ ์ง€์›)์ด๋ฉฐ, ์˜ˆ๊ธฐ์น˜ ์•Š์€ ๋ณ€๊ฒฝ์„ ๋ฐฉ์ง€ํ•˜๋Š” plan-before-apply ์›Œํฌํ”Œ๋กœ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ๋‚ด๋ถ€ ๋ฐฉํ–ฅ์„ฑ ๋น„์ˆœํ™˜ ๊ทธ๋ž˜ํ”„(DAG)๋ฅผ ํ†ตํ•ด ๋ฆฌ์†Œ์Šค ์ข…์†์„ฑ์„ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

ํƒ„ํƒ„ํ•œ ๋‹ต๋ณ€์—๋Š” ์ƒํƒœ๊ณ„ ๋ณ€ํ™”์— ๋Œ€ํ•œ ์–ธ๊ธ‰๋„ ํฌํ•จ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. HashiCorp๊ฐ€ 2023๋…„์— BSL ๋ผ์ด์„ ์Šค๋ฅผ ์ฑ„ํƒํ•œ ์ดํ›„, Linux Foundation ์‚ฐํ•˜์—์„œ ์˜คํ”ˆ์†Œ์Šค ํฌํฌ์ธ OpenTofu๊ฐ€ ๋“ฑ์žฅํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๋‘ ๋„๊ตฌ๋Š” ๋™์ผํ•œ HCL ๊ตฌ๋ฌธ์„ ๊ณต์œ ํ•˜์ง€๋งŒ ๊ธฐ๋Šฅ ๋ฉด์—์„œ ๋ถ„ํ™”๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Terraform 1.14๋Š” HCP์™€์˜ ํ”Œ๋žซํผ ํ†ตํ•ฉ์— ์ค‘์ ์„ ๋‘๊ณ , OpenTofu 1.9๋Š” ์ƒํƒœ ์•”ํ˜ธํ™” ๋ฐ ๋™์  ๋ฐฑ์—”๋“œ๋ฅผ ์šฐ์„ ์‹œํ•ฉ๋‹ˆ๋‹ค.

Terraform ์›Œํฌํ”Œ๋กœ ์„ค๋ช…: init, plan, apply, destroy

๋„ค ๊ฐ€์ง€ ํ•ต์‹ฌ ๋ช…๋ น์–ด๋Š” ๋ชจ๋“  Terraform ์ž‘์—…์˜ ์ˆ˜๋ช… ์ฃผ๊ธฐ๋ฅผ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.

bash
# 1. Initialize - ํ”„๋กœ๋ฐ”์ด๋”์™€ ๋ชจ๋“ˆ ๋‹ค์šด๋กœ๋“œ
terraform init

# 2. Plan - ์•„๋ฌด๊ฒƒ๋„ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ  ๋ณ€๊ฒฝ๋  ๋‚ด์šฉ ํ‘œ์‹œ
terraform plan -out=tfplan

# 3. Apply - ๊ณ„ํš๋œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ ์‹คํ–‰
terraform apply tfplan

# 4. Destroy - ๊ด€๋ฆฌ ์ค‘์ธ ๋ชจ๋“  ๋ฆฌ์†Œ์Šค ์‚ญ์ œ
terraform destroy

terraform init์€ ํ”„๋กœ๋ฐ”์ด๋” ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  ๋ฐฑ์—”๋“œ๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค. terraform plan์€ ์›ํ•˜๋Š” ์ƒํƒœ(๊ตฌ์„ฑ ํŒŒ์ผ)์™€ ์‹ค์ œ ์ƒํƒœ(์ƒํƒœ ํŒŒ์ผ)๋ฅผ ๋น„๊ตํ•˜์—ฌ ๋ณ€๊ฒฝ ์„ธํŠธ๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. terraform apply๋Š” ํ•ด๋‹น ๋ณ€๊ฒฝ ์„ธํŠธ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. -out ์˜ต์…˜์œผ๋กœ plan์„ ํŒŒ์ผ์— ์ €์žฅํ•˜๋ฉด ๊ฒ€ํ† ๋œ ์ •ํ™•ํ•œ plan์ด ์ ์šฉ๋˜๋„๋ก ๋ณด์žฅํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋Š” CI/CD ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ํ•„์ˆ˜์ ์ž…๋‹ˆ๋‹ค.

์ƒํƒœ ๊ด€๋ฆฌ: ๊ฐ€์žฅ ์ž์ฃผ ์ถœ์ œ๋˜๋Š” ๋ฉด์ ‘ ์ฃผ์ œ

Terraform ์ƒํƒœ๋ž€ ๋ฌด์—‡์ด๋ฉฐ ์™œ ์ค‘์š”ํ•ฉ๋‹ˆ๊นŒ?

Terraform ์ƒํƒœ๋Š” ๊ตฌ์„ฑ ๋ฆฌ์†Œ์Šค๋ฅผ ์‹ค์ œ ์ธํ”„๋ผ ๊ฐ์ฒด์— ๋งคํ•‘ํ•˜๋Š” JSON ํŒŒ์ผ(terraform.tfstate)์ž…๋‹ˆ๋‹ค. ์ƒํƒœ ์—†์ด๋Š” Terraform์ด ๋ฌด์—‡์ด ์กด์žฌํ•˜๋Š”์ง€, ๋ฌด์—‡์ด ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”์ง€, ๋ฌด์—‡์„ ์‚ญ์ œํ•ด์•ผ ํ•˜๋Š”์ง€ ํŒ๋‹จํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ƒํƒœ์—๋Š” ๋ฆฌ์†Œ์Šค ID, ์†์„ฑ ๊ฐ’, ์ข…์†์„ฑ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ์ƒํƒœ๋ฅผ ์žƒ์œผ๋ฉด Terraform์ด ๊ด€๋ฆฌํ•˜๋Š” ๋ชจ๋“  ๋ฆฌ์†Œ์Šค๋ฅผ ์ถ”์ ํ•  ์ˆ˜ ์—†๊ฒŒ ๋˜๋ฉฐ, ๋ชจ๋“  ๊ฐ์ฒด๋ฅผ ์ˆ˜๋™์œผ๋กœ importํ•˜๊ฑฐ๋‚˜, ๋” ์‹ฌํ•œ ๊ฒฝ์šฐ ๋น„์šฉ์ด ๊ณ„์† ๋ฐœ์ƒํ•˜๋Š” ๊ณ ์•„ ํด๋ผ์šฐ๋“œ ๋ฆฌ์†Œ์Šค๊ฐ€ ๋‚จ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์šด์˜ ํ™˜๊ฒฝ์—์„œ ์ƒํƒœ๋ฅผ ์–ด๋–ป๊ฒŒ ๊ด€๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

๋กœ์ปฌ ์ƒํƒœ ํŒŒ์ผ์€ ํŒ€ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ํ‘œ์ค€ ์šด์˜ ํ™˜๊ฒฝ ์„ค์ •์€ ์ž ๊ธˆ(locking) ๊ธฐ๋Šฅ์ด ์žˆ๋Š” ์›๊ฒฉ ๋ฐฑ์—”๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

hcl
# backend.tf
terraform {
  backend "s3" {
    bucket         = "company-terraform-state"
    key            = "prod/networking/terraform.tfstate"
    region         = "eu-west-1"
    dynamodb_table = "terraform-locks"
    encrypt        = true
  }
}

์ด ๊ตฌ์„ฑ์€ ์„œ๋ฒ„ ์ธก ์•”ํ˜ธํ™”๋ฅผ ์ ์šฉํ•˜์—ฌ S3์— ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๊ณ , DynamoDB๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒํƒœ ์ž ๊ธˆ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ž ๊ธˆ์€ ๋‘ ๋ช…์˜ ์—”์ง€๋‹ˆ์–ด(๋˜๋Š” ๋‘ ๊ฐœ์˜ CI ํŒŒ์ดํ”„๋ผ์ธ)๊ฐ€ ๋™์‹œ์— apply๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์ƒํƒœ๋ฅผ ์†์ƒ์‹œํ‚ค๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

HCP Terraform(์ด์ „ ๋ช…์นญ Terraform Cloud)์€ ์ถ”๊ฐ€ ์ธํ”„๋ผ ์—†์ด ์ƒํƒœ ์ €์žฅ, ์ž ๊ธˆ, ์‹คํ–‰ ์ด๋ ฅ, RBAC๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ด€๋ฆฌํ˜• ๋Œ€์•ˆ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. HashiCorp ์ƒํƒœ๊ณ„์— ์ด๋ฏธ ํˆฌ์žํ•œ ์กฐ์ง์˜ ๊ฒฝ์šฐ, S3 ๋ฒ„ํ‚ท๊ณผ DynamoDB ํ…Œ์ด๋ธ”์„ ์œ ์ง€ ๊ด€๋ฆฌํ•˜๋Š” ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์—†์•จ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ƒํƒœ ํŒŒ์ผ ๋ชจ๋ฒ” ์‚ฌ๋ก€๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

  • terraform.tfstate๋ฅผ ์ ˆ๋Œ€๋กœ ๋ฒ„์ „ ๊ด€๋ฆฌ์— ์ปค๋ฐ‹ํ•˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋น„๋ฐ€๋ฒˆํ˜ธ, API ํ‚ค ๋“ฑ์˜ ์‹œํฌ๋ฆฟ์ด ํ‰๋ฌธ์œผ๋กœ ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ฐฑ์—”๋“œ์—์„œ ์ €์žฅ ์‹œ ์•”ํ˜ธํ™”๋ฅผ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค(S3 SSE, GCS ์•”ํ˜ธํ™”, Azure Storage ์•”ํ˜ธํ™”).
  • ํ™˜๊ฒฝ๋ณ„๋กœ ๋ณ„๋„์˜ ์ƒํƒœ ํŒŒ์ผ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. dev, staging, production์— ๋‹จ์ผ ์ƒํƒœ ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์šฐ๋ฐœ์  ํŒŒ๊ดด์˜ ์›์ธ์ด ๋ฉ๋‹ˆ๋‹ค.
  • ์ƒํƒœ ์ž ๊ธˆ์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ์ž ๊ธˆ์„ ์ง€์›ํ•˜๋Š” ๋ชจ๋“  ์›๊ฒฉ ๋ฐฑ์—”๋“œ์—์„œ ์ž ๊ธˆ์„ ํ™œ์„ฑํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • terraform state list์™€ terraform state show๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์ƒํƒœ๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ  ๊ฒ€์‚ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ƒํƒœ ํŒŒ์ผ ์žฌํ•ด ๋ณต๊ตฌ

์ƒํƒœ ๋ฐฑ์—”๋“œ์—์„œ ํ•ญ์ƒ ๋ฒ„์ „ ๊ด€๋ฆฌ๋ฅผ ํ™œ์„ฑํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(S3 ๋ฒ„์ „ ๊ด€๋ฆฌ, GCS ๊ฐ์ฒด ๋ฒ„์ „ ๊ด€๋ฆฌ). ๋ฐฑ์—… ์—†์ด ์ƒํƒœ ํŒŒ์ผ์ด ์†์ƒ๋˜๊ฑฐ๋‚˜ ์‹ค์ˆ˜๋กœ ์‚ญ์ œ๋˜๋ฉด ๋ณต๊ตฌ๋ฅผ ์œ„ํ•ด ์ˆ˜ ์‹œ๊ฐ„์˜ ์ˆ˜๋™ terraform import ์ž‘์—…์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“ˆ: ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ธํ”„๋ผ ์ปดํฌ๋„ŒํŠธ

Terraform ๋ชจ๋“ˆ์€ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ?

๋ชจ๋“ˆ์€ ๋ฆฌ์†Œ์Šค ์ง‘ํ•ฉ์„ ์บก์Аํ™”ํ•˜๋Š” .tf ํŒŒ์ผ์ด ํฌํ•จ๋œ ๋””๋ ‰ํ„ฐ๋ฆฌ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  Terraform ๊ตฌ์„ฑ์€ ๊ธฐ์ˆ ์ ์œผ๋กœ ๋ชจ๋“ˆ(๋ฃจํŠธ ๋ชจ๋“ˆ)์ž…๋‹ˆ๋‹ค. ์ž์‹ ๋ชจ๋“ˆ์€ ์žฌ์‚ฌ์šฉ์„ ์ด‰์ง„ํ•˜๊ณ  ํ‘œ์ค€์„ ๊ฐ•์ œํ•˜๊ธฐ ์œ„ํ•ด ๋ฃจํŠธ ๋ชจ๋“ˆ์—์„œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

hcl
# main.tf - ๋ชจ๋“ˆ ํ˜ธ์ถœ
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "5.16.0"

  name = "production-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["eu-west-1a", "eu-west-1b", "eu-west-1c"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]

  enable_nat_gateway = true
  single_nat_gateway = true
}

Terraform 1.14๋Š” ์ค‘์š”ํ•œ ๊ฐœ์„  ์‚ฌํ•ญ์„ ๋„์ž…ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ด์ œ ๋ชจ๋“ˆ source์™€ version ์†์„ฑ์— ๋ณ€์ˆ˜(variables)์™€ locals๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ „์—๋Š” ๋™์  ๋ชจ๋“ˆ ์†Œ์‹ฑ์„ ์œ„ํ•ด Terragrunt์™€ ๊ฐ™์€ ์šฐํšŒ ๋ฐฉ๋ฒ•์„ ๊ฐ•์ œํ•˜๋˜ ๊ณ ์ •์ ์ธ ์ œํ•œ ์‚ฌํ•ญ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

์ž˜ ์„ค๊ณ„๋œ ๋ชจ๋“ˆ์˜ ์กฐ๊ฑด์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์šด์˜ ์ˆ˜์ค€์˜ ๋ชจ๋“ˆ์€ ๋‹ค์Œ ์›์น™์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

  • ๋ช…ํ™•ํ•œ ์ž…์ถœ๋ ฅ: ๋ชจ๋“  ๋ณ€์ˆ˜์— ์„ค๋ช…, ํƒ€์ž… ์ œ์•ฝ ์กฐ๊ฑด, ์ ์šฉ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ ํ•ฉ๋ฆฌ์ ์ธ ๊ธฐ๋ณธ๊ฐ’์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ถœ๋ ฅ(outputs)์€ ํ•˜๋ฅ˜ ๋ชจ๋“ˆ์ด ํ•„์š”๋กœ ํ•˜๋Š” ๊ฐ’์„ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
  • ์ตœ์†Œ ๋ฒ”์œ„: ๋ชจ๋“ˆ์€ ํ•˜๋‚˜์˜ ๋…ผ๋ฆฌ์  ์ปดํฌ๋„ŒํŠธ(VPC, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํด๋Ÿฌ์Šคํ„ฐ, Kubernetes ๋„ค์ž„์ŠคํŽ˜์ด์Šค)๋ฅผ ๊ด€๋ฆฌํ•˜๋ฉฐ, ์ „์ฒด ํ™˜๊ฒฝ์„ ๊ด€๋ฆฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ํ•˜๋“œ์ฝ”๋”ฉ ๊ธˆ์ง€: ํ”„๋กœ๋ฐ”์ด๋” ๊ตฌ์„ฑ, ๋ฆฌ์ „, ๊ณ„์ • ID, ํ™˜๊ฒฝ๋ณ„ ๊ฐ’์€ ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ๋˜๋ฉฐ, ๋ชจ๋“ˆ ๋‚ด๋ถ€์—์„œ ๋ฆฌํ„ฐ๋Ÿด๋กœ ์ž‘์„ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๋ฒ„์ „ ๊ด€๋ฆฌ๋œ ๋ฆด๋ฆฌ์Šค: ๊ฒŒ์‹œ๋œ ๋ชจ๋“ˆ์€ ์‹œ๋งจํ‹ฑ ๋ฒ„์ „ ๊ด€๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. version = "5.16.0"์„ ๊ณ ์ •ํ•˜๋ฉด ์˜ˆ๊ธฐ์น˜ ์•Š์€ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

DevOps ๋ฉด์ ‘ ์ค€๋น„๊ฐ€ ๋˜์…จ๋‚˜์š”?

์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ, flashcards, ๊ธฐ์ˆ  ํ…Œ์ŠคํŠธ๋กœ ์—ฐ์Šตํ•˜์„ธ์š”.

์›Œํฌ์ŠคํŽ˜์ด์Šค, ํ™˜๊ฒฝ, ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

๋‹ค์ค‘ ํ™˜๊ฒฝ์„ ์–ด๋–ป๊ฒŒ ๊ด€๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

์„ธ ๊ฐ€์ง€ ์ผ๋ฐ˜์ ์ธ ํŒจํ„ด์ด ์กด์žฌํ•˜๋ฉฐ, ๊ฐ๊ฐ ๋šœ๋ ทํ•œ ํŠธ๋ ˆ์ด๋“œ์˜คํ”„๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

| ํŒจํ„ด | ๋ฉ”์ปค๋‹ˆ์ฆ˜ | ์ ํ•ฉํ•œ ๊ฒฝ์šฐ | ์œ„ํ—˜ ์š”์†Œ | |------|----------|-------------|----------| | ์›Œํฌ์ŠคํŽ˜์ด์Šค | terraform workspace select prod | ๋‹จ์ˆœํ•œ ํ”„๋กœ์ ํŠธ, ํ™˜๊ฒฝ๋ณ„ ๋™์ผ ๊ตฌ์„ฑ | ๊ณต์œ  ์ƒํƒœ ๋ฐฑ์—”๋“œ, ์ž˜๋ชป๋œ ์›Œํฌ์ŠคํŽ˜์ด์Šค์— apply ์‹คํ–‰ ๊ฐ€๋Šฅ | | ๋””๋ ‰ํ„ฐ๋ฆฌ๋ณ„ ํ™˜๊ฒฝ | ๋ณ„๋„์˜ dev/, staging/, prod/ ๋””๋ ‰ํ„ฐ๋ฆฌ | ํ™˜๊ฒฝ ๊ฐ„ ์™„์ „ํ•œ ๊ฒฉ๋ฆฌ | ๋””๋ ‰ํ„ฐ๋ฆฌ ๊ฐ„ ์ฝ”๋“œ ์ค‘๋ณต | | Terragrunt | ๋ฐฑ์—”๋“œ ๊ตฌ์„ฑ์„ ์ƒ์„ฑํ•˜๋Š” DRY ๋ž˜ํผ | ๋Œ€๊ทœ๋ชจ ๋ฉ€ํ‹ฐ ๊ณ„์ • ํ™˜๊ฒฝ | ์ถ”๊ฐ€ ๋„๊ตฌ ์˜์กด์„ฑ |

๊ณต์œ  ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•œ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ณ„ ํ™˜๊ฒฝ ์ ‘๊ทผ ๋ฐฉ์‹์ด ์šด์˜ ํ™˜๊ฒฝ์—์„œ ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ž…๋‹ˆ๋‹ค. ๊ฐ ํ™˜๊ฒฝ ๋””๋ ‰ํ„ฐ๋ฆฌ์—๋Š” ๋™์ผํ•œ ๋ชจ๋“ˆ์„ ๋‹ค๋ฅธ ๋ณ€์ˆ˜ ๊ฐ’์œผ๋กœ ํ˜ธ์ถœํ•˜๋Š” main.tf๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฉฐ, ๊ฐ๊ฐ ์ž์ฒด์ ์œผ๋กœ ๊ฒฉ๋ฆฌ๋œ ์ƒํƒœ ํŒŒ์ผ์„ ๋ณด์œ ํ•ฉ๋‹ˆ๋‹ค.

terraform workspace์™€ ๋””๋ ‰ํ„ฐ๋ฆฌ ๊ฒฉ๋ฆฌ์˜ ์ฐจ์ด์ ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์›Œํฌ์ŠคํŽ˜์ด์Šค๋Š” ๋™์ผํ•œ ๋ฐฑ์—”๋“œ ๋‚ด์—์„œ ์ด๋ฆ„์ด ์ง€์ •๋œ ์ƒํƒœ ํŒŒ์ผ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. terraform workspace select staging์œผ๋กœ ์›Œํฌ์ŠคํŽ˜์ด์Šค๋ฅผ ์ „ํ™˜ํ•˜๋ฉด Terraform์ด ์ฝ๊ณ  ์“ฐ๋Š” ์ƒํƒœ ํŒŒ์ผ์ด ๋ณ€๊ฒฝ๋˜์ง€๋งŒ, ๊ตฌ์„ฑ ์ž์ฒด๋Š” ๋™์ผํ•˜๊ฒŒ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.

์ œํ•œ ์‚ฌํ•ญ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์›Œํฌ์ŠคํŽ˜์ด์Šค๋Š” ๋™์ผํ•œ ๋ฐฑ์—”๋“œ ๊ตฌ์„ฑ๊ณผ ํ”„๋กœ๋ฐ”์ด๋” ์„ค์ •์„ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค. ๋””๋ ‰ํ„ฐ๋ฆฌ ๊ฒฉ๋ฆฌ๋Š” ๋” ๊ฐ•๋ ฅํ•œ ๊ฒฝ๊ณ„๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ, ๊ฐ ํ™˜๊ฒฝ์ด ๋‹ค๋ฅธ AWS ๊ณ„์ •, ๋‹ค๋ฅธ ์ƒํƒœ ๋ฐฑ์—”๋“œ, ๋˜๋Š” ๋‹ค๋ฅธ ํ”„๋กœ๋ฐ”์ด๋” ๋ฒ„์ „์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—„๊ฒฉํ•œ ํญ๋ฐœ ๋ฐ˜๊ฒฝ ์ œ์–ด๊ฐ€ ํ•„์š”ํ•œ ๊ทœ์ œ ํ™˜๊ฒฝ์—์„œ๋Š” ๋””๋ ‰ํ„ฐ๋ฆฌ ๊ฒฉ๋ฆฌ๊ฐ€ ๋” ์•ˆ์ „ํ•œ ์„ ํƒ์ž…๋‹ˆ๋‹ค.

ํ”„๋กœ๋ฐ”์ด๋”, ๋ฐ์ดํ„ฐ ์†Œ์Šค, ๋ฆฌ์†Œ์Šค ์ˆ˜๋ช… ์ฃผ๊ธฐ

ํ”„๋กœ๋ฐ”์ด๋”๋ž€ ๋ฌด์—‡์ด๋ฉฐ ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๊นŒ?

ํ”„๋กœ๋ฐ”์ด๋”๋Š” HCL ๊ตฌ์„ฑ์„ ํŠน์ • ํ”Œ๋žซํผ์— ๋Œ€ํ•œ API ํ˜ธ์ถœ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์ž…๋‹ˆ๋‹ค. AWS ํ”„๋กœ๋ฐ”์ด๋”๋Š” AWS API๋ฅผ ํ˜ธ์ถœํ•˜๊ณ , Kubernetes ํ”„๋กœ๋ฐ”์ด๋”๋Š” Kubernetes API ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•ฉ๋‹ˆ๋‹ค.

hcl
# providers.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.80"
    }
  }
}

provider "aws" {
  region = var.aws_region

  default_tags {
    tags = {
      Environment = var.environment
      ManagedBy   = "terraform"
      Team        = var.team_name
    }
  }
}

~> 5.80 ๋ฒ„์ „ ์ œ์•ฝ ์กฐ๊ฑด์€ ํŒจ์น˜ ์—…๋ฐ์ดํŠธ(5.80.x)๋ฅผ ํ—ˆ์šฉํ•˜์ง€๋งŒ ๋งˆ์ด๋„ˆ ๋ฒ„์ „ ๋ณ€๊ฒฝ์€ ์ฐจ๋‹จํ•˜์—ฌ, ์•ˆ์ •์„ฑ๊ณผ ๋ณด์•ˆ ํŒจ์น˜ ์‚ฌ์ด์˜ ๊ท ํ˜•์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. default_tags ๋ธ”๋ก์€ ํ”„๋กœ๋ฐ”์ด๋”๊ฐ€ ์ƒ์„ฑํ•˜๋Š” ๋ชจ๋“  ๋ฆฌ์†Œ์Šค์— ์ผ๊ด€๋œ ํƒœ๊น…์„ ์ ์šฉํ•˜๋ฉฐ, ์ด๋Š” ๊ฑฐ๋ฒ„๋„Œ์Šค ๋ฐ ๋น„์šฉ ํ• ๋‹น์— ๋Œ€ํ•œ ์ผ๋ฐ˜์ ์ธ ๋ฉด์ ‘ ๋…ผ์˜ ํฌ์ธํŠธ์ž…๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ ์†Œ์Šค์™€ ๋ฆฌ์†Œ์Šค์˜ ์ฐจ์ด์ ์„ ์„ค๋ช…ํ•˜์‹ญ์‹œ์˜ค

๋ฆฌ์†Œ์Šค(resource ๋ธ”๋ก)๋Š” ์ธํ”„๋ผ๋ฅผ ์ƒ์„ฑ, ์—…๋ฐ์ดํŠธ, ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ์†Œ์Šค(data ๋ธ”๋ก)๋Š” ๊ธฐ์กด ์ธํ”„๋ผ๋ฅผ ๊ด€๋ฆฌํ•˜์ง€ ์•Š๊ณ  ์ฝ๊ธฐ๋งŒ ํ•ฉ๋‹ˆ๋‹ค.

hcl
# ๋ฐ์ดํ„ฐ ์†Œ์Šค - ๊ธฐ์กด AMI๋ฅผ ์ฝ์œผ๋ฉฐ, ์•„๋ฌด๊ฒƒ๋„ ์ƒ์„ฑํ•˜์ง€ ์•Š์Œ
data "aws_ami" "ubuntu" {
  most_recent = true
  owners      = ["099720109477"] # Canonical

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-*"]
  }
}

# ๋ฆฌ์†Œ์Šค - ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ EC2 ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t3.micro"
}

๋ฐ์ดํ„ฐ ์†Œ์Šค๋Š” plan ์ค‘์— ํ‰๊ฐ€๋˜๋ฏ€๋กœ, ๊ณต์œ  ์ธํ”„๋ผ ์ฐธ์กฐ(๋‹ค๋ฅธ ํŒ€์ด ์ƒ์„ฑํ•œ VPC), ๋™์  ๊ฐ’ ์กฐํšŒ(์ตœ์‹  AMI ID), ์™ธ๋ถ€ ๊ตฌ์„ฑ ์ฝ๊ธฐ(SSM ํŒŒ๋ผ๋ฏธํ„ฐ, Vault ์‹œํฌ๋ฆฟ)์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ˆ˜๋ช… ์ฃผ๊ธฐ ๋ฉ”ํƒ€ ์ธ์ˆ˜

๋ฉด์ ‘์—์„œ ์ž์ฃผ ๋“ฑ์žฅํ•˜๋Š” ์„ธ ๊ฐ€์ง€ ์ˆ˜๋ช… ์ฃผ๊ธฐ ๊ทœ์น™์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. create_before_destroy(๋ฌด์ค‘๋‹จ ๊ต์ฒด), prevent_destroy(๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ๊ฐ™์€ ์ค‘์š” ๋ฆฌ์†Œ์Šค ๋ณดํ˜ธ), ignore_changes(ASG desired capacity์™€ ๊ฐ™์ด Terraform ์™ธ๋ถ€์—์„œ ์ˆ˜์ •๋˜๋Š” ํ•„๋“œ์— ๋Œ€ํ•œ ๋“œ๋ฆฌํ”„ํŠธ ๋ฐฉ์ง€).

๊ณ ๊ธ‰ ์ฃผ์ œ: Import, Moved ๋ธ”๋ก, ํ…Œ์ŠคํŒ…

terraform import๋Š” ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋ฉฐ ์–ธ์ œ ํ•„์š”ํ•ฉ๋‹ˆ๊นŒ?

terraform import๋Š” ๊ธฐ์กด ํด๋ผ์šฐ๋“œ ๋ฆฌ์†Œ์Šค๋ฅผ Terraform ๋ฆฌ์†Œ์Šค ๋ธ”๋ก์— ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์ธ ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ์ธํ”„๋ผ๊ฐ€ ์ˆ˜๋™์œผ๋กœ(ClickOps) ๋˜๋Š” ๋‹ค๋ฅธ ๋„๊ตฌ๋กœ ์ƒ์„ฑ๋˜์—ˆ๊ณ , ํŒ€์ด ์ด์ œ Terraform์œผ๋กœ ๊ด€๋ฆฌํ•˜๋ ค๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.

Terraform 1.5 ์ด์ƒ์—์„œ๋Š” CLI ์ „์šฉ ์›Œํฌํ”Œ๋กœ๋ฅผ ๋Œ€์ฒดํ•˜๋Š” import ๋ธ”๋ก์„ ๊ตฌ์„ฑ์— ์ง์ ‘ ๋„์ž…ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

hcl
# import.tf
import {
  to = aws_s3_bucket.legacy_data
  id = "my-legacy-bucket-name"
}

resource "aws_s3_bucket" "legacy_data" {
  bucket = "my-legacy-bucket-name"
}

์ด ๋ธ”๋ก๊ณผ ํ•จ๊ป˜ terraform plan์„ ์‹คํ–‰ํ•˜๋ฉด ๊ธฐ์กด ๋ฒ„ํ‚ท์„ ์ƒํƒœ๋กœ ์ˆ˜์šฉํ•˜๋Š” plan์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ด ์„ ์–ธ์  import ์ ‘๊ทผ ๋ฐฉ์‹์€ ํ’€ ๋ฆฌํ€˜์ŠคํŠธ์—์„œ ๊ฒ€ํ†  ๊ฐ€๋Šฅํ•˜๊ณ , ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•˜๋ฉฐ, ์ƒํƒœ์— ๋Œ€ํ•œ ์ง์ ‘์ ์ธ CLI ์•ก์„ธ์Šค๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

moved ๋ธ”๋ก์ด๋ž€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

Terraform ์ฝ”๋“œ๋ฅผ ๋ฆฌํŒฉํ„ฐ๋ง(๋ฆฌ์†Œ์Šค ์ด๋ฆ„ ๋ณ€๊ฒฝ, ๋ชจ๋“ˆ๋กœ ์ด๋™)ํ•  ๋•Œ ๊ณผ๊ฑฐ์—๋Š” terraform state mv ๋ช…๋ น์ด ํ•„์š”ํ•˜์˜€์Šต๋‹ˆ๋‹ค. moved ๋ธ”๋ก์€ ์ด๋ฅผ ์„ ์–ธ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

hcl
# ๋ฆฌ์†Œ์Šค ์ด๋ฆ„์„ "web"์—์„œ "app"์œผ๋กœ ๋ณ€๊ฒฝ
moved {
  from = aws_instance.web
  to   = aws_instance.app
}

Terraform์€ plan ์ค‘์— ์ด๋™์„ ์ธ์‹ํ•˜๊ณ  ์ƒํƒœ๋ฅผ ์ž๋™์œผ๋กœ ์—…๋ฐ์ดํŠธํ•˜์—ฌ, ์‚ญ์ œ ํ›„ ์žฌ์ƒ์„ฑ ์‚ฌ์ดํด์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋Œ€๊ทœ๋ชจ ๊ตฌ์„ฑ์„ ๋ชจ๋“ˆ๋กœ ์žฌ๊ตฌ์กฐํ™”ํ•  ๋•Œ ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

Terraform ํ…Œ์ŠคํŒ…์€ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ?

Terraform 1.6 ์ด์ƒ์—๋Š” .tftest.hcl ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๋Š” ๋„ค์ดํ‹ฐ๋ธŒ ํ…Œ์ŠคํŒ… ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

hcl
# tests/vpc.tftest.hcl
run "creates_vpc_with_correct_cidr" {
  command = plan

  assert {
    condition     = aws_vpc.main.cidr_block == "10.0.0.0/16"
    error_message = "VPC CIDR block does not match expected value"
  }
}

run "creates_three_private_subnets" {
  command = plan

  assert {
    condition     = length(aws_subnet.private) == 3
    error_message = "Expected 3 private subnets"
  }
}

Terraform 1.14์—์„œ๋Š” ํ•จ์ˆ˜๋ฅผ ํ—ˆ์šฉํ•˜๋Š” mock ๋ธ”๋ก, ์‹คํŒจํ•œ ํ…Œ์ŠคํŠธ ๋””๋ฒ„๊น…์„ ์œ„ํ•œ skip_cleanup, run ๋ธ”๋ก ๋‚ด์˜ ๊ฒฉ๋ฆฌ๋œ ํ…Œ์ŠคํŠธ ์ƒํƒœ๋ฅผ ์œ„ํ•œ backend ๋ธ”๋ก ๋“ฑ์œผ๋กœ ๊ธฐ๋Šฅ์ด ํ™•์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋„ค์ดํ‹ฐ๋ธŒ ํ…Œ์ŠคํŒ…์€ ๊ธฐ๋ณธ์ ์ธ ๊ฒ€์ฆ์„ ์œ„ํ•ด Terratest์™€ ๊ฐ™์€ ์™ธ๋ถ€ ๋„๊ตฌ์˜ ํ•„์š”์„ฑ์„ ์—†์• ์ค๋‹ˆ๋‹ค.

CI/CD ํŒŒ์ดํ”„๋ผ์ธ์—์„œ์˜ Terraform

์šด์˜ ํ™˜๊ฒฝ Terraform ํŒŒ์ดํ”„๋ผ์ธ์€ ์–ด๋–ค ๋ชจ์Šต์ž…๋‹ˆ๊นŒ?

๊ฒฌ๊ณ ํ•œ CI/CD ํŒŒ์ดํ”„๋ผ์ธ์€ ๋ชจ๋“  ๋‹จ๊ณ„์—์„œ ์•ˆ์ „์„ ๊ฐ•์ œํ•ฉ๋‹ˆ๋‹ค.

  1. ๋ฆฐํŠธ ๋ฐ ๊ฒ€์ฆ: terraform fmt -check์™€ terraform validate๋กœ ๊ตฌ๋ฌธ ๋ฌธ์ œ๋ฅผ ๊ฐ์ง€ํ•ฉ๋‹ˆ๋‹ค.
  2. PR ์‹œ Plan: ๋ชจ๋“  ํ’€ ๋ฆฌํ€˜์ŠคํŠธ์—์„œ terraform plan์„ ์‹คํ–‰ํ•˜๊ณ  ์ถœ๋ ฅ์„ PR ์ฝ”๋ฉ˜ํŠธ๋กœ ๊ฒŒ์‹œํ•ฉ๋‹ˆ๋‹ค. ๊ฒ€ํ† ๋œ plan ์—†์ด๋Š” apply๋ฅผ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  3. ์ •์ฑ… ๊ฒ€์‚ฌ: OPA(Open Policy Agent), Sentinel(HCP Terraform), Checkov ๋“ฑ์˜ ๋„๊ตฌ๋กœ ์กฐ์ง ์ •์ฑ…(ํผ๋ธ”๋ฆญ S3 ๋ฒ„ํ‚ท ๊ธˆ์ง€, ํ•„์ˆ˜ ์•”ํ˜ธํ™”, ํ•„์ˆ˜ ํƒœ๊ทธ)์— ๋Œ€ํ•ด plan์„ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.
  4. ๋จธ์ง€ ์‹œ Apply: PR ์Šน์ธ ๋ฐ ์ •์ฑ… ๊ฒ€์‚ฌ ํ†ต๊ณผ ํ›„, ์ €์žฅ๋œ plan ํŒŒ์ผ์—์„œ terraform apply๊ฐ€ ์ž๋™์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
  5. ์ƒํƒœ ๋ฐฑ์—…: apply ํ›„ ํŒŒ์ดํ”„๋ผ์ธ์ด ์ƒํƒœ ๋ฌด๊ฒฐ์„ฑ์„ ๊ฒ€์ฆํ•˜๊ณ , ๋ฐฑ์—”๋“œ์˜ ๋ฒ„์ „ ๊ด€๋ฆฌ๊ฐ€ ์ƒˆ๋กœ์šด ์ƒํƒœ ๋ฒ„์ „์„ ์บก์ฒ˜ํ•ฉ๋‹ˆ๋‹ค.

ํ™ฉ๊ธˆ๋ฅ : ์–ด๋–ค ์‚ฌ๋žŒ๋„ ๋กœ์ปฌ ๋จธ์‹ ์—์„œ ์šด์˜ ํ™˜๊ฒฝ์— ๋Œ€ํ•ด terraform apply๋ฅผ ์‹คํ–‰ํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์šด์˜ ํ™˜๊ฒฝ apply๋Š” ํŒŒ์ดํ”„๋ผ์ธ์„ ํ†ตํ•ด ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ฒฐ๋ก 

Terraform ๋ฉด์ ‘ ์ค€๋น„์˜ ํ•ต์‹ฌ ์š”์•ฝ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์ƒํƒœ ๊ด€๋ฆฌ๋Š” ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋‹จ์ผ ์ฃผ์ œ์ž…๋‹ˆ๋‹ค. ๋ฉด์ ‘์— ๋“ค์–ด๊ฐ€๊ธฐ ์ „์— ์›๊ฒฉ ๋ฐฑ์—”๋“œ, ์ž ๊ธˆ, ์•”ํ˜ธํ™”, ์žฌํ•ด ๋ณต๊ตฌ ์ „๋žต์„ ๋ฐ˜๋“œ์‹œ ์ดํ•ดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ชจ๋“ˆ ์„ค๊ณ„๋Š” ์ฃผ๋‹ˆ์–ด์™€ ์‹œ๋‹ˆ์–ด ํ›„๋ณด์ž๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ๋ช…ํ™•ํ•œ ์ธํ„ฐํŽ˜์ด์Šค์™€ ์ตœ์†Œ ๋ฒ”์œ„๋ฅผ ๊ฐ€์ง„ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ณ  ๋ฒ„์ „ ๊ด€๋ฆฌ๋œ ๋ชจ๋“ˆ์„ ๊ตฌ์ถ•ํ•˜๋Š” ๋Šฅ๋ ฅ์„ ๋ณด์—ฌ์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • plan/apply ์›Œํฌํ”Œ๋กœ๋ฅผ ๊นŠ์ด ์ดํ•ดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. plan์„ ํŒŒ์ผ๋กœ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ์™œ ์ค‘์š”ํ•œ์ง€, DAG๊ฐ€ ์‹คํ–‰ ์ˆœ์„œ๋ฅผ ์–ด๋–ป๊ฒŒ ๊ฒฐ์ •ํ•˜๋Š”์ง€, -target์ด ๋ฌด์—‡์„ ํ•˜๋Š”์ง€(๊ทธ๋ฆฌ๊ณ  ์™œ ์•„๊ปด์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”์ง€) ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • Terraform 1.14๋Š” ๋ชจ๋“ˆ ์†Œ์Šค์—์„œ์˜ ๋ณ€์ˆ˜ ์‚ฌ์šฉ, ํ™•์žฅ๋œ ํ…Œ์ŠคํŒ…, ๋” ๊ธด๋ฐ€ํ•œ HCP ํ†ตํ•ฉ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ตœ์‹  ๊ธฐ๋Šฅ์„ ์–ธ๊ธ‰ํ•˜๋ฉด ์ƒํƒœ๊ณ„์— ๋Œ€ํ•œ ์ ๊ทน์ ์ธ ๊ด€์‹ฌ์„ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Terraform ๋Œ€ OpenTofu ํ˜„ํ™ฉ์„ ์†”์งํ•˜๊ฒŒ ๋‹ค๋ฃจ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ผ์ด์„ ์Šค ๋ถ„๋ฆฌ, ๊ธฐ๋Šฅ ๋ถ„ํ™”, ๊ฐ ๋„๊ตฌ์˜ ์ ํ•ฉํ•œ ์‚ฌ์šฉ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์ดํ•ดํ•˜๋ฉด ๊ตฌ๋ฌธ ์ง€์‹์„ ๋„˜์–ด์„  ์•„ํ‚คํ…์ฒ˜์  ์„ฑ์ˆ™๋„๋ฅผ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Terraform ์„ธ๋ถ€ ์‚ฌํ•ญ๊ณผ ํ•จ๊ป˜ DevOps ๋ฉด์ ‘ ๊ธฐ์ดˆ๋ฅผ ํ•™์Šตํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๋ฉด์ ‘๊ด€์€ IaC ์งˆ๋ฌธ๊ณผ ๋” ๋„“์€ ์ธํ”„๋ผ ์ฃผ์ œ๋ฅผ ์ž์ฃผ ํ˜ผํ•ฉํ•˜์—ฌ ์ถœ์ œํ•ฉ๋‹ˆ๋‹ค.
  • Terraform์ด Kubernetes ์›Œํฌ๋กœ๋“œ๊ฐ€ ์‹คํ–‰๋˜๋Š” ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ํ”„๋กœ๋น„์ €๋‹ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์œผ๋ฏ€๋กœ, Kubernetes ๋ฐฐํฌ ๊ฐœ๋…๋„ ํ•จ๊ป˜ ๋ณต์Šตํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

์—ฐ์Šต์„ ์‹œ์ž‘ํ•˜์„ธ์š”!

๋ฉด์ ‘ ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ์™€ ๊ธฐ์ˆ  ํ…Œ์ŠคํŠธ๋กœ ์ง€์‹์„ ํ…Œ์ŠคํŠธํ•˜์„ธ์š”.

ํƒœ๊ทธ

#terraform
#infrastructure-as-code
#devops
#iac
#interview

๊ณต์œ 

๊ด€๋ จ ๊ธฐ์‚ฌ

Pod, Service, Deployment๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” Kubernetes ์•„ํ‚คํ…์ฒ˜ ๋‹ค์ด์–ด๊ทธ๋žจ

Kubernetes ๋ฉด์ ‘ ์™„๋ฒฝ ๊ฐ€์ด๋“œ: Pod, Service, Deployment ํ•ต์‹ฌ ์ •๋ฆฌ

Kubernetes ๋ฉด์ ‘์—์„œ ์ž์ฃผ ์ถœ์ œ๋˜๋Š” Pod, Service, Deployment์˜ ํ•ต์‹ฌ ๊ฐœ๋…์„ YAML ์˜ˆ์ œ์™€ ํ•จ๊ป˜ ์ƒ์„ธํžˆ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค. 2026๋…„ ์ตœ์‹  ํŠธ๋ Œ๋“œ๋ฅผ ๋ฐ˜์˜ํ•œ ์‹ค์ „ ๋Œ€๋น„ ๊ฐ€์ด๋“œ์ž…๋‹ˆ๋‹ค.

DevOps ์ธํ„ฐ๋ทฐ ํ•„์ˆ˜ ์งˆ๋ฌธ

DevOps ์ธํ„ฐ๋ทฐ ํ•„์ˆ˜ ์งˆ๋ฌธ: ์™„์ „ ๊ฐ€์ด๋“œ 2026

CI/CD, Kubernetes, Docker, Terraform, SRE ์‹ค์ฒœ์— ๊ด€ํ•œ ํ•„์ˆ˜ ์งˆ๋ฌธ์œผ๋กœ DevOps ์ธํ„ฐ๋ทฐ๋ฅผ ์ค€๋น„ํ•˜์‹ญ์‹œ์˜ค. ์ƒ์„ธํ•œ ๋‹ต๋ณ€ ํฌํ•จ.

๊ฐœ๋ฐœ์—์„œ ํ”„๋กœ๋•์…˜๊นŒ์ง€์˜ Docker ๊ฐ€์ด๋“œ

Docker: ๊ฐœ๋ฐœ์—์„œ ํ”„๋กœ๋•์…˜๊นŒ์ง€

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…Œ์ด๋„ˆํ™”๋ฅผ ์œ„ํ•œ ์™„๋ฒฝํ•œ Docker ๊ฐ€์ด๋“œ. Dockerfile, Docker Compose, ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ ๋ฐ ํ”„๋กœ๋•์…˜ ๋ฐฐํฌ๋ฅผ ์‹ค์šฉ์ ์ธ ์˜ˆ์ œ์™€ ํ•จ๊ป˜ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.