Post

Terragrunt๋ž€?

Terragrunt๋ž€?

๐Ÿฅ‘ ๋“ค์–ด๊ฐ€๋ฉฐ

์ตœ๊ทผ ํšŒ์‚ฌ์—์„œ Terraform์œผ๋กœ ๊ด€๋ฆฌํ•˜๋˜ ์ธํ”„๋ผ ๊ตฌ์„ฑ์„ Terragrunt ๊ธฐ๋ฐ˜์œผ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ–ˆ๋‹ค.

๊ธฐ์กด์—๋Š” Terraform๋งŒ์œผ๋กœ๋„ ์ธํ”„๋ผ๋ฅผ ์ฝ”๋“œ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์—ˆ์ง€๋งŒ, ์„œ๋น„์Šค๊ฐ€ ํ™•์žฅ๋˜๋ฉด์„œ ํ…Œ๋„Œ์‹œ๋ณ„๋กœ ์ƒํƒœ๋ฅผ ๋ถ„๋ฆฌํ•˜๊ณ  ๊ณตํ†ต ์„ค์ •์„ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ตฌ์กฐ๊ฐ€ ํ•„์š”ํ•ด์กŒ๋‹ค. ํŠนํžˆ ์—ฌ๋Ÿฌ ํ…Œ๋„Œ์‹œ๊ฐ€ ๊ฐ™์€ ํ˜•ํƒœ์˜ ์ธํ”„๋ผ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ๋„ ๊ฐ์ž์˜ ์ƒํƒœ๋Š” ๋…๋ฆฝ์ ์œผ๋กœ ๊ด€๋ฆฌ๋˜์–ด์•ผ ํ–ˆ๋‹ค.

๋˜ํ•œ VPC, subnet, route table ๊ฐ™์€ ๊ธฐ๋ณธ ๋„คํŠธ์›Œํฌ ๋ฆฌ์†Œ์Šค๋Š” ์—ฌ๋Ÿฌ ํ…Œ๋„Œ์‹œ๊ฐ€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ๋ฐ˜ ๋ฆฌ์†Œ์Šค์— ๊ฐ€๊นŒ์› ๋‹ค. ๊ทธ๋ž˜์„œ ์ด๋Ÿฐ ๊ณตํ†ต ์ธํ”„๋ผ๋Š” core ์˜์—ญ์—์„œ ๋จผ์ € ๊ด€๋ฆฌํ•˜๊ณ , ๊ฐ ํ…Œ๋„Œ์‹œ๋Š” core์—์„œ ๋งŒ๋“ค์–ด์ง„ ๋„คํŠธ์›Œํฌ ์ •๋ณด๋ฅผ ์ฐธ์กฐํ•ด์„œ ์ž์‹ ์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌ์กฐ๋ฅผ ์žก์•˜๋‹ค.

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” Terragrunt๊ฐ€ ๋ฌด์—‡์ธ์ง€, Terraform๋งŒ ์‚ฌ์šฉํ•  ๋•Œ ์–ด๋–ค ๋ถˆํŽธํ•จ์ด ์žˆ์—ˆ๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  Terragrunt๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ํ…Œ๋„Œ์‹œ๋ณ„ ์ƒํƒœ ๊ด€๋ฆฌ์™€ ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”์ง€ ์ •๋ฆฌํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.


๐Ÿ“Œ Terragrunt๋ž€?

Terragrunt๋Š” Terraform์„ ๋” ํŽธํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์–‡์€ ๋ž˜ํผ ๋„๊ตฌ๋‹ค.

Terraform์„ ๋Œ€์ฒดํ•˜๋Š” ๋„๊ตฌ๊ฐ€ ์•„๋‹ˆ๋ผ, Terraform ์œ„์—์„œ ๋™์ž‘ํ•˜๋ฉด์„œ ๋ฐ˜๋ณต๋˜๋Š” ์„ค์ •์„ ์ค„์ด๊ณ  ์—ฌ๋Ÿฌ ํ™˜๊ฒฝ์˜ ์ธํ”„๋ผ ์ฝ”๋“œ๋ฅผ ๋” ๊ตฌ์กฐ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ค€๋‹ค.

Terraform์€ ์ธํ”„๋ผ๋ฅผ ์ฝ”๋“œ๋กœ ์„ ์–ธํ•˜๊ณ , plan, apply๋ฅผ ํ†ตํ•ด ์‹ค์ œ ํด๋ผ์šฐ๋“œ ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค. ํ•˜์ง€๋งŒ ์‹ค์ œ ์šด์˜ ํ™˜๊ฒฝ์—์„œ๋Š” ๋‹จ์ˆœํžˆ ๋ฆฌ์†Œ์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ๋งŽ์€ ๊ณ ๋ฏผ์ด ํ•„์š”ํ•˜๋‹ค.

  • dev, stage, prod ๊ฐ™์€ ํ™˜๊ฒฝ์„ ์–ด๋–ป๊ฒŒ ๋‚˜๋ˆŒ์ง€
  • ๊ฐ ํ™˜๊ฒฝ์˜ state๋ฅผ ์–ด๋””์— ์ €์žฅํ• ์ง€
  • ๊ณตํ†ต module์„ ์–ด๋–ป๊ฒŒ ์žฌ์‚ฌ์šฉํ• ์ง€
  • ํ…Œ๋„Œ์‹œ๋ณ„ ์„ค์ •์„ ์–ด๋–ป๊ฒŒ ๋ถ„๋ฆฌํ• ์ง€
  • ํ™˜๊ฒฝ์ด ๋Š˜์–ด๋‚  ๋•Œ ์ค‘๋ณต ์ฝ”๋“œ๋ฅผ ์–ด๋–ป๊ฒŒ ์ค„์ผ์ง€

Terragrunt๋Š” ์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด Terraform ์„ค์ • ๋ฐ”๊นฅ์—์„œ ๊ณตํ†ต ์„ค์ •, remote state, module source, dependency ๋“ฑ์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.


Terraform๋งŒ ์‚ฌ์šฉํ•  ๋•Œ์˜ ๋ถˆํŽธํ•จ

Terraform๋งŒ ์‚ฌ์šฉํ•ด๋„ module์„ ํ™œ์šฉํ•˜๋ฉด ์–ด๋А ์ •๋„ ์ค‘๋ณต์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ ํ™˜๊ฒฝ์ด๋‚˜ ํ…Œ๋„Œ์‹œ๊ฐ€ ๋Š˜์–ด๋‚˜๋ฉด ๋น„์Šทํ•œ ์„ค์ •์ด ์—ฌ๋Ÿฌ ๊ณณ์— ๋ฐ˜๋ณต๋˜๊ธฐ ์‰ฝ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๊ฐ™์€ module์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ tenant-a, tenant-b, tenant-c์ฒ˜๋Ÿผ ํ…Œ๋„Œ์‹œ๋ณ„๋กœ ๋ณ€์ˆ˜๋งŒ ๋‹ค๋ฅธ ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.

์ด๋•Œ Terraform ์ฝ”๋“œ๊ฐ€ ์•„๋ž˜์ฒ˜๋Ÿผ ๋ฐ˜๋ณต๋  ์ˆ˜ ์žˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
terraform/
โ”œโ”€โ”€ prod
โ”‚   โ”œโ”€โ”€ tenant-a
โ”‚   โ”‚   โ”œโ”€โ”€ main.tf
โ”‚   โ”‚   โ”œโ”€โ”€ backend.tf
โ”‚   โ”‚   โ””โ”€โ”€ variables.tf
โ”‚   โ”œโ”€โ”€ tenant-b
โ”‚   โ”‚   โ”œโ”€โ”€ main.tf
โ”‚   โ”‚   โ”œโ”€โ”€ backend.tf
โ”‚   โ”‚   โ””โ”€โ”€ variables.tf
โ”‚   โ””โ”€โ”€ tenant-c
โ”‚       โ”œโ”€โ”€ main.tf
โ”‚       โ”œโ”€โ”€ backend.tf
โ”‚       โ””โ”€โ”€ variables.tf
โ””โ”€โ”€ modules
    โ””โ”€โ”€ tenant

๋ฌผ๋ก  ๋™์ž‘์€ ํ•˜์ง€๋งŒ ํ…Œ๋„Œ์‹œ๊ฐ€ ์ถ”๊ฐ€๋ ์ˆ˜๋ก ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๋Š” ํŒŒ์ผ์ด ๋งŽ์•„์ง„๋‹ค. ํŠนํžˆ backend ์„ค์ •์ด๋‚˜ provider ์„ค์ •์ฒ˜๋Ÿผ ๊ฑฐ์˜ ๋™์ผํ•œ ๋‚ด์šฉ์ด ์—ฌ๋Ÿฌ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ๋ฐ˜๋ณต๋œ๋‹ค.

์ด๋Ÿฐ ๊ตฌ์กฐ์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค.

  • ํ…Œ๋„Œ์‹œ๋ณ„ backend ์„ค์ •์ด ๋ฐ˜๋ณต๋œ๋‹ค.
  • ๊ณตํ†ต ์„ค์ •์ด ๋ณ€๊ฒฝ๋  ๋•Œ ์—ฌ๋Ÿฌ ํŒŒ์ผ์„ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค.
  • ์„ค์ • ๋ˆ„๋ฝ์ด๋‚˜ ๋ถˆ์ผ์น˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์‰ฝ๋‹ค.
  • ์‹ ๊ทœ ํ…Œ๋„Œ์‹œ ์ถ”๊ฐ€ ์ ˆ์ฐจ๊ฐ€ ๋ฒˆ๊ฑฐ๋กœ์›Œ์ง„๋‹ค.
  • state๋ฅผ ์–ด๋–ค ๋‹จ์œ„๋กœ ๋ถ„๋ฆฌํ–ˆ๋Š”์ง€ ํ•œ๋ˆˆ์— ํŒŒ์•…ํ•˜๊ธฐ ์–ด๋ ต๋‹ค.


์™œ ํ…Œ๋„Œ์‹œ๋ณ„ state ๋ถ„๋ฆฌ๊ฐ€ ํ•„์š”ํ• ๊นŒ?

Terraform์€ state ํŒŒ์ผ์„ ํ†ตํ•ด ํ˜„์žฌ ์ธํ”„๋ผ ์ƒํƒœ๋ฅผ ์ถ”์ ํ•œ๋‹ค.

state์—๋Š” Terraform์ด ๊ด€๋ฆฌํ•˜๋Š” ๋ฆฌ์†Œ์Šค ์ •๋ณด๊ฐ€ ์ €์žฅ๋œ๋‹ค. ๋”ฐ๋ผ์„œ state๋ฅผ ์–ด๋–ป๊ฒŒ ๋‚˜๋ˆŒ์ง€๋Š” ์ธํ”„๋ผ ์šด์˜์—์„œ ์ค‘์š”ํ•œ ์„ค๊ณ„ ํฌ์ธํŠธ๋‹ค.

๋ฉ€ํ‹ฐ ํ…Œ๋„Œ์‹œ ํ™˜๊ฒฝ์—์„œ๋Š” ํ…Œ๋„Œ์‹œ๋ณ„๋กœ state๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์œ ๋ฆฌํ•œ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด tenant-a์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ์ž‘์—…์ด tenant-b์˜ state์™€ ์„ž์—ฌ ์žˆ๋‹ค๋ฉด ๋ณ€๊ฒฝ ์˜ํ–ฅ ๋ฒ”์œ„๊ฐ€ ์ปค์ง„๋‹ค. ๋ฐ˜๋Œ€๋กœ ํ…Œ๋„Œ์‹œ๋ณ„๋กœ state๊ฐ€ ๋ถ„๋ฆฌ๋˜์–ด ์žˆ๋‹ค๋ฉด ํŠน์ • ํ…Œ๋„Œ์‹œ์˜ ๋ณ€๊ฒฝ์€ ํ•ด๋‹น ํ…Œ๋„Œ์‹œ์˜ state ์•ˆ์—์„œ๋งŒ ๊ด€๋ฆฌ๋œ๋‹ค.

ํ…Œ๋„Œ์‹œ๋ณ„ state ๋ถ„๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์žฅ์ ์ด ์žˆ๋‹ค.

  • ํŠน์ • ํ…Œ๋„Œ์‹œ ๋ณ€๊ฒฝ์ด ๋‹ค๋ฅธ ํ…Œ๋„Œ์‹œ์— ์˜ํ–ฅ์„ ์ฃผ๋Š” ์œ„ํ—˜์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.
  • ์žฅ์• ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์˜ํ–ฅ ๋ฒ”์œ„๋ฅผ ์ขํ˜€์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํ…Œ๋„Œ์‹œ๋ณ„ plan, apply ์ž‘์—…์ด ๋ช…ํ™•ํ•ด์ง„๋‹ค.
  • ์‹ ๊ทœ ํ…Œ๋„Œ์‹œ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ ๊ธฐ์กด ํ…Œ๋„Œ์‹œ์˜ state๋ฅผ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š์•„๋„ ๋œ๋‹ค.
  • ์šด์˜ ์ค‘ ๋กค๋ฐฑ์ด๋‚˜ ์žฌ์ ์šฉ ๋ฒ”์œ„๋ฅผ ์ œํ•œํ•˜๊ธฐ ์‰ฝ๋‹ค.

ํšŒ์‚ฌ์—์„œ๋„ ์ด๋ฒˆ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์˜ ํ•ต์‹ฌ์€ Terraform ์ฝ”๋“œ๋ฅผ ๋‹จ์ˆœํžˆ Terragrunt๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ํ…Œ๋„Œ์‹œ๋ณ„๋กœ state๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด์—ˆ๋‹ค.


Terragrunt๋ฅผ ์‚ฌ์šฉํ•œ ๊ตฌ์กฐ

Terragrunt๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ƒ์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ๊ณตํ†ต ์„ค์ •์„ ๋‘๊ณ , ํ•˜์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ๋Š” ๊ฐ ํ™˜๊ฒฝ์ด๋‚˜ ํ…Œ๋„Œ์‹œ์— ํ•„์š”ํ•œ ๊ฐ’๋งŒ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋•Œ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด live์™€ modules๋ฅผ ๋‚˜๋ˆ„๋Š” ๊ตฌ์กฐ๋‹ค.

  • live: ์‹ค์ œ ํ™˜๊ฒฝ๋ณ„ Terragrunt ์„ค์ •
  • modules: ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ Terraform module

modules์—๋Š” VPC, tenant ๋ฆฌ์†Œ์Šค์ฒ˜๋Ÿผ ์žฌ์‚ฌ์šฉํ•  Terraform ์ฝ”๋“œ๊ฐ€ ๋“ค์–ด๊ฐ€๊ณ , live์—๋Š” prod, stage ๊ฐ™์€ ์‹ค์ œ ํ™˜๊ฒฝ์—์„œ ์–ด๋–ค module์„ ์–ด๋–ค ๊ฐ’์œผ๋กœ ์‹คํ–‰ํ• ์ง€ ์ •์˜ํ•œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์•„๋ž˜์™€ ๊ฐ™์€ ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
infra/
โ”œโ”€โ”€ live
โ”‚   โ”œโ”€โ”€ terragrunt.hcl
โ”‚   โ”œโ”€โ”€ prod
โ”‚   โ”‚   โ”œโ”€โ”€ core
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ network
โ”‚   โ”‚   โ”‚       โ””โ”€โ”€ terragrunt.hcl
โ”‚   โ”‚   โ””โ”€โ”€ tenants
โ”‚   โ”‚       โ”œโ”€โ”€ tenant-a
โ”‚   โ”‚       โ”‚   โ””โ”€โ”€ terragrunt.hcl
โ”‚   โ”‚       โ””โ”€โ”€ tenant-b
โ”‚   โ”‚           โ””โ”€โ”€ terragrunt.hcl
โ”‚   โ””โ”€โ”€ stage
โ”‚       โ”œโ”€โ”€ core
โ”‚       โ”‚   โ””โ”€โ”€ network
โ”‚       โ”‚       โ””โ”€โ”€ terragrunt.hcl
โ”‚       โ””โ”€โ”€ tenants
โ”‚           โ””โ”€โ”€ tenant-a
โ”‚               โ””โ”€โ”€ terragrunt.hcl
โ””โ”€โ”€ modules
    โ”œโ”€โ”€ network
    โ””โ”€โ”€ tenant

live/terragrunt.hcl์—๋Š” ๊ณตํ†ต remote state ์„ค์ •์ด๋‚˜ ๊ณตํ†ต input์„ ๋‘˜ ์ˆ˜ ์žˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
remote_state {
  backend = "s3"

  config = {
    bucket         = "my-terraform-state"
    key            = "${path_relative_to_include()}/terraform.tfstate"
    region         = "ap-northeast-2"
    encrypt        = true
    dynamodb_table = "terraform-lock"
  }
}

์—ฌ๊ธฐ์„œ path_relative_to_include()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ˜„์žฌ Terragrunt ์„ค์ • ํŒŒ์ผ์˜ ์ƒ๋Œ€ ๊ฒฝ๋กœ๋ฅผ ๊ธฐ์ค€์œผ๋กœ state key๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด live/prod/tenants/tenant-a์—์„œ ์‹คํ–‰ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ key๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

1
prod/tenants/tenant-a/terraform.tfstate

live/prod/tenants/tenant-b์—์„œ ์‹คํ–‰ํ•˜๋ฉด state key๋Š” ๋‹ฌ๋ผ์ง„๋‹ค.

1
prod/tenants/tenant-b/terraform.tfstate

์ฆ‰, ๊ณตํ†ต remote state ์„ค์ •์€ ์žฌ์‚ฌ์šฉํ•˜๋ฉด์„œ๋„ ์‹ค์ œ state ํŒŒ์ผ์€ ํ…Œ๋„Œ์‹œ๋ณ„๋กœ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.


core์™€ tenant ๋ถ„๋ฆฌ

์ด๋ฒˆ ๊ตฌ์กฐ์—์„œ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์€ core์™€ tenant๋ฅผ ๋ถ„๋ฆฌํ•œ ๊ฒƒ์ด๋‹ค.

core๋Š” ์—ฌ๋Ÿฌ ํ…Œ๋„Œ์‹œ๊ฐ€ ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ๋ฐ˜ ์ธํ”„๋ผ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์˜์—ญ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด VPC, subnet, route table, security group์ฒ˜๋Ÿผ ํ…Œ๋„Œ์‹œ๋ณ„๋กœ ๋งค๋ฒˆ ์ƒˆ๋กœ ๋งŒ๋“ค๊ธฐ๋ณด๋‹ค ๊ณตํ†ต ๊ธฐ๋ฐ˜์œผ๋กœ ๋‘๊ณ  ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๋ฆฌ์†Œ์Šค๊ฐ€ ์—ฌ๊ธฐ์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค.

๋ฐ˜๋ฉด tenant ์˜์—ญ์€ ๊ฐ ํ…Œ๋„Œ์‹œ์— ํ•„์š”ํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค. ์ด๋•Œ ํ…Œ๋„Œ์‹œ ๋ฆฌ์†Œ์Šค๋Š” ๋„คํŠธ์›Œํฌ๋ฅผ ์ง์ ‘ ์ƒˆ๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, core์—์„œ ๋งŒ๋“ค์–ด๋‘” ๋„คํŠธ์›Œํฌ ์ •๋ณด๋ฅผ ์ฐธ์กฐํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค.

์ด๋ ‡๊ฒŒ ๋‚˜๋ˆ„๋ฉด ์ฑ…์ž„์ด ๋ช…ํ™•ํ•ด์ง„๋‹ค.

  • core: ๊ณตํ†ต ๋„คํŠธ์›Œํฌ์™€ ๊ธฐ๋ฐ˜ ๋ฆฌ์†Œ์Šค ๊ด€๋ฆฌ
  • tenant: ํ…Œ๋„Œ์‹œ๋ณ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฆฌ์†Œ์Šค ๊ด€๋ฆฌ
  • modules: ์‹ค์ œ Terraform module ์ •์˜

์˜ˆ๋ฅผ ๋“ค์–ด core/network์—์„œ๋Š” VPC์™€ subnet์„ ๋งŒ๋“ค๊ณ  output์œผ๋กœ ํ•„์š”ํ•œ ๊ฐ’์„ ๋‚ด๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

1
2
3
4
5
6
7
output "vpc_id" {
  value = aws_vpc.main.id
}

output "private_subnet_ids" {
  value = aws_subnet.private[*].id
}

๊ทธ๋ฆฌ๊ณ  ํ…Œ๋„Œ์‹œ ์ชฝ Terragrunt ์„ค์ •์—์„œ๋Š” dependency๋ฅผ ์‚ฌ์šฉํ•ด core/network์˜ output์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
dependency "network" {
  config_path = "../../core/network"
}

inputs = {
  environment        = "prod"
  tenant_name        = "tenant-a"
  vpc_id             = dependency.network.outputs.vpc_id
  private_subnet_ids = dependency.network.outputs.private_subnet_ids
}

์ด ๊ตฌ์กฐ์—์„œ๋Š” ํ…Œ๋„Œ์‹œ๊ฐ€ ๋Š˜์–ด๋‚˜๋„ VPC๋‚˜ subnet ๊ฐ™์€ ๊ธฐ๋ณธ ๋„คํŠธ์›Œํฌ๋ฅผ ๊ณ„์† ๋ณต์‚ฌํ•ด์„œ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†๋‹ค. ๊ฐ ํ…Œ๋„Œ์‹œ๋Š” ๊ณตํ†ต ๋„คํŠธ์›Œํฌ ์œ„์—์„œ ํ•„์š”ํ•œ ๋ฆฌ์†Œ์Šค๋งŒ ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค.

๋˜ํ•œ core์™€ tenant์˜ state๊ฐ€ ๋ถ„๋ฆฌ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ณตํ†ต ๋„คํŠธ์›Œํฌ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์ž‘์—…๊ณผ ํŠน์ • ํ…Œ๋„Œ์‹œ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์ž‘์—…์„ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ณตํ†ต ๋ฆฌ์†Œ์Šค๋ฅผ ์ˆ˜์ •ํ•  ๋•Œ๋Š” ๋” ์‹ ์ค‘ํ•˜๊ฒŒ ๋ฆฌ๋ทฐํ•˜๊ณ , ํ…Œ๋„Œ์‹œ๋ณ„ ๋ณ€๊ฒฝ์€ ์ƒ๋Œ€์ ์œผ๋กœ ์ข์€ ๋ฒ”์œ„์—์„œ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.


ํ…Œ๋„Œ์‹œ๋ณ„ terragrunt.hcl ์˜ˆ์‹œ

๊ฐ ํ…Œ๋„Œ์‹œ ๋””๋ ‰ํ„ฐ๋ฆฌ์˜ terragrunt.hcl์—์„œ๋Š” ๊ณตํ†ต ์„ค์ •์„ includeํ•˜๊ณ , ์‚ฌ์šฉํ•  Terraform module๊ณผ ์ž…๋ ฅ๊ฐ’๋งŒ ์ •์˜ํ•œ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
include {
  path = find_in_parent_folders()
}

terraform {
  source = "../../../../modules/tenant"
}

dependency "network" {
  config_path = "../../core/network"
}

inputs = {
  environment        = "prod"
  tenant_name        = "tenant-a"
  vpc_id             = dependency.network.outputs.vpc_id
  private_subnet_ids = dependency.network.outputs.private_subnet_ids
}

include๋Š” ์ƒ์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ์˜ terragrunt.hcl์„ ๊ฐ€์ ธ์˜ค๋Š” ์„ค์ •์ด๋‹ค.

find_in_parent_folders()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ˜„์žฌ ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ๋ถ€ํ„ฐ ์ƒ์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ๋กœ ์˜ฌ๋ผ๊ฐ€๋ฉฐ terragrunt.hcl์„ ์ฐพ๋Š”๋‹ค. ๊ทธ๋ž˜์„œ ํ•˜์œ„ ํ…Œ๋„Œ์‹œ ์„ค์ •์—์„œ๋Š” remote state ๊ฐ™์€ ๊ณตํ†ต ์„ค์ •์„ ๋ฐ˜๋ณตํ•ด์„œ ์ž‘์„ฑํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

terraform.source์—๋Š” ์‹ค์ œ ์‚ฌ์šฉํ•  Terraform module ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•œ๋‹ค.

dependency๋Š” ๋‹ค๋ฅธ Terragrunt module์˜ output์„ ๊ฐ€์ ธ์˜ฌ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. ์œ„ ์˜ˆ์‹œ์—์„œ๋Š” core/network์—์„œ ์ƒ์„ฑํ•œ VPC ID์™€ private subnet ID๋ฅผ ๊ฐ€์ ธ์™€ ํ…Œ๋„Œ์‹œ module์˜ input์œผ๋กœ ๋„˜๊ธฐ๊ณ  ์žˆ๋‹ค.

๊ฒฐ๊ณผ์ ์œผ๋กœ ํ…Œ๋„Œ์‹œ๋ณ„ ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ๋Š” ์•„๋ž˜ ๋‚ด์šฉ๋งŒ ๊ด€๋ฆฌํ•˜๋ฉด ๋œ๋‹ค.

  • ์–ด๋–ค module์„ ์‚ฌ์šฉํ• ์ง€
  • ์–ด๋–ค ํ™˜๊ฒฝ์ธ์ง€
  • ์–ด๋–ค ํ…Œ๋„Œ์‹œ์ธ์ง€
  • ์–ด๋–ค core ๋ฆฌ์†Œ์Šค๋ฅผ ์ฐธ์กฐํ• ์ง€
  • ํ…Œ๋„Œ์‹œ๋ณ„๋กœ ๋‹ฌ๋ผ์ง€๋Š” ์ž…๋ ฅ๊ฐ’์€ ๋ฌด์—‡์ธ์ง€


Terragrunt๋กœ ๊ฐœ์„ ๋œ ์ 

์ด๋ฒˆ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ํ†ตํ•ด ๊ฐ€์žฅ ํฌ๊ฒŒ ๊ฐœ์„ ๋œ ๋ถ€๋ถ„์€ ์ค‘๋ณต ์ œ๊ฑฐ์™€ ํ™•์žฅ์„ฑ์ด๋‹ค.

๊ธฐ์กด์—๋Š” ์ƒˆ๋กœ์šด ํ…Œ๋„Œ์‹œ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ ๋น„์Šทํ•œ Terraform ์„ค์ •์„ ๋ณต์‚ฌํ•˜๊ณ , backend ์„ค์ •์ด๋‚˜ ๋ณ€์ˆ˜ ํŒŒ์ผ์„ ์ง์ ‘ ์ˆ˜์ •ํ•ด์•ผ ํ–ˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ ์„ค์ •์ด ๋ˆ„๋ฝ๋˜๊ฑฐ๋‚˜ ๊ธฐ์กด ํ…Œ๋„Œ์‹œ์™€ ๋‹ค๋ฅด๊ฒŒ ์ž‘์„ฑ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์—ˆ๋‹ค.

Terragrunt๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ณตํ†ต ์„ค์ •์€ ์ƒ์œ„ ํŒŒ์ผ์—์„œ ๊ด€๋ฆฌํ•˜๊ณ , ํ…Œ๋„Œ์‹œ๋ณ„ ์„ค์ •์€ ํ•„์š”ํ•œ ์ž…๋ ฅ๊ฐ’๋งŒ ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค.

์‹ ๊ทœ ํ…Œ๋„Œ์‹œ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ๋„ ์ „์ฒด Terraform ์ฝ”๋“œ๋ฅผ ๋ณต์‚ฌํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ์ƒˆ๋กœ์šด ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ๋งŒ๋“ค๊ณ  terragrunt.hcl์— ํ…Œ๋„Œ์‹œ๋ณ„ input๋งŒ ์ •์˜ํ•˜๋ฉด ๋œ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
live/
โ””โ”€โ”€ prod/
    โ”œโ”€โ”€ core/
    โ”‚   โ””โ”€โ”€ network/
    โ”‚       โ””โ”€โ”€ terragrunt.hcl
    โ””โ”€โ”€ tenants/
        โ”œโ”€โ”€ tenant-a/
        โ”‚   โ””โ”€โ”€ terragrunt.hcl
        โ”œโ”€โ”€ tenant-b/
        โ”‚   โ””โ”€โ”€ terragrunt.hcl
        โ””โ”€โ”€ tenant-c/
            โ””โ”€โ”€ terragrunt.hcl

์ด ๊ตฌ์กฐ์—์„œ๋Š” ํ…Œ๋„Œ์‹œ๊ฐ€ ๋Š˜์–ด๋‚˜๋„ ๊ธฐ์กด module๊ณผ ๊ณตํ†ต ์„ค์ •์„ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ณตํ†ต ๋„คํŠธ์›Œํฌ๋Š” core์—์„œ ํ•œ ๋ฒˆ ๊ด€๋ฆฌํ•˜๊ณ , ๊ฐ ํ…Œ๋„Œ์‹œ๋Š” ๊ทธ output์„ ์ฐธ์กฐํ•ด์„œ ํ•„์š”ํ•œ ๋ฆฌ์†Œ์Šค๋งŒ ์ƒ์„ฑํ•œ๋‹ค. ๋™์‹œ์— state๋Š” core์™€ ํ…Œ๋„Œ์‹œ๋ณ„๋กœ ๋ถ„๋ฆฌ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณ€๊ฒฝ ์˜ํ–ฅ ๋ฒ”์œ„๋„ ๋ช…ํ™•ํ•ด์ง„๋‹ค.


Terragrunt๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ฃผ์˜ํ•  ์ 

Terragrunt๊ฐ€ ๋ชจ๋“  ๋ฌธ์ œ๋ฅผ ์ž๋™์œผ๋กœ ํ•ด๊ฒฐํ•ด์ฃผ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

Terraform ์œ„์— ํ•œ ๊ณ„์ธต์ด ๋” ์ƒ๊ธฐ๋Š” ๋งŒํผ ๋””๋ ‰ํ„ฐ๋ฆฌ ๊ตฌ์กฐ์™€ ์„ค์ • ๊ทœ์น™์„ ๋ช…ํ™•ํžˆ ์ •ํ•ด์•ผ ํ•œ๋‹ค. ๊ตฌ์กฐ๊ฐ€ ์• ๋งคํ•˜๋ฉด Terraform๋งŒ ์‚ฌ์šฉํ•  ๋•Œ๋ณด๋‹ค ์˜คํžˆ๋ ค ๋ณต์žกํ•ด์งˆ ์ˆ˜ ์žˆ๋‹ค.

ํŠนํžˆ ์•„๋ž˜ ๋‚ด์šฉ์€ ์ดˆ๊ธฐ์— ์ž˜ ์ •ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

  • state๋ฅผ ์–ด๋–ค ๋‹จ์œ„๋กœ ๋ถ„๋ฆฌํ• ์ง€
  • ํ™˜๊ฒฝ๊ณผ ํ…Œ๋„Œ์‹œ ๋””๋ ‰ํ„ฐ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ์–ด๋–ป๊ฒŒ ๊ฐ€์ ธ๊ฐˆ์ง€
  • ๊ณตํ†ต ์„ค์ •๊ณผ ๊ฐœ๋ณ„ ์„ค์ •์˜ ๊ฒฝ๊ณ„๋ฅผ ์–ด๋””์— ๋‘˜์ง€
  • core ๋ฆฌ์†Œ์Šค์™€ tenant ๋ฆฌ์†Œ์Šค์˜ ์ฑ…์ž„์„ ์–ด๋””๊นŒ์ง€ ๋‚˜๋ˆŒ์ง€
  • module ๋ฒ„์ „ ๊ด€๋ฆฌ๋ฅผ ์–ด๋–ป๊ฒŒ ํ• ์ง€
  • ๋ฆฌ์†Œ์Šค ๊ฐ„ dependency๋ฅผ Terragrunt๋กœ ๊ด€๋ฆฌํ• ์ง€
  • ์‹ ๊ทœ ํ…Œ๋„Œ์‹œ ์ถ”๊ฐ€ ์ ˆ์ฐจ๋ฅผ ์–ด๋–ป๊ฒŒ ํ‘œ์ค€ํ™”ํ• ์ง€

Terragrunt ๋„์ž…์˜ ํ•ต์‹ฌ์€ ๋„๊ตฌ๋ฅผ ๋ฐ”๊พธ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ์ธํ”„๋ผ ์ฝ”๋“œ์˜ ๊ฒฝ๊ณ„์™€ ์ฑ…์ž„์„ ๋‹ค์‹œ ์„ค๊ณ„ํ•˜๋Š” ๊ฒƒ์— ๊ฐ€๊น๋‹ค.


๋งˆ๋ฌด๋ฆฌ

Terragrunt๋Š” Terraform์„ ๋Œ€์ฒดํ•˜๋Š” ๋„๊ตฌ๊ฐ€ ์•„๋‹ˆ๋ผ Terraform์„ ๋” ๊ตฌ์กฐ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋„๊ตฌ๋‹ค.

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

์ด๋ฒˆ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์—์„œ๋Š” Terragrunt๋ฅผ ์‚ฌ์šฉํ•ด ๊ณตํ†ต ์„ค์ •์„ ์žฌ์‚ฌ์šฉํ•˜๊ณ , ํ…Œ๋„Œ์‹œ๋ณ„๋กœ state๋ฅผ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค. ํŠนํžˆ ๊ธฐ๋ณธ ๋„คํŠธ์›Œํฌ ๊ฐ™์€ ๊ณตํ†ต ๋ฆฌ์†Œ์Šค๋Š” core์—์„œ ๊ด€๋ฆฌํ•˜๊ณ , ๊ฐ ํ…Œ๋„Œ์‹œ๋Š” core์˜ output์„ ์ฐธ์กฐํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌ์„ฑํ–ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์‹ ๊ทœ ํ…Œ๋„Œ์‹œ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ์˜ ์ž‘์—…๋Ÿ‰์„ ์ค„์ด๊ณ , ๋ณ€๊ฒฝ ์˜ํ–ฅ ๋ฒ”์œ„๋ฅผ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

๊ฒฐ๊ตญ ์ค‘์š”ํ•œ ๊ฒƒ์€ Terragrunt ์ž์ฒด๋ณด๋‹ค๋„ state๋ฅผ ์–ด๋–ค ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„๊ณ , ์–ด๋–ค ์„ค์ •์„ ๊ณตํ†ตํ™”ํ•˜๋ฉฐ, ์–ด๋–ค ๊ฐ’์„ ํ…Œ๋„Œ์‹œ๋ณ„๋กœ ๋ถ„๋ฆฌํ• ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ์„ค๊ณ„๋‹ค.

Terragrunt๋Š” ๊ทธ ์„ค๊ณ„๋ฅผ ์ฝ”๋“œ๋กœ ์œ ์ง€ํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋„์™€์ฃผ๋Š” ๋„๊ตฌ๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

This post is licensed under CC BY 4.0 by the author.