Terraform์˜ ํ•จ์ •

Terraform์˜ ํ•จ์ •
๋ฃจํ”„, if ๋ฌธ ๋ฐ ๋ฐฐํฌ ๊ธฐ์ˆ ๊ณผ ๊ด€๋ จ๋œ ๋ฌธ์ œ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ผ๋ฐ˜์ ์œผ๋กœ Terraform์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ๋ณด๋‹ค ์ผ๋ฐ˜์ ์ธ ๋ฌธ์ œ๋ฅผ ํฌํ•จํ•˜์—ฌ ๋ช‡ ๊ฐ€์ง€ ํ•จ์ •์„ ๊ฐ•์กฐํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  • count ๋ฐ for_each ๋งค๊ฐœ๋ณ€์ˆ˜์—๋Š” ์ œํ•œ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ฐ€๋™ ์ค‘์ง€ ์‹œ๊ฐ„์ด ์—†๋Š” ๋ฐฐํฌ๋ฅผ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.
  • ์ข‹์€ ๊ณ„ํš์ด๋ผ๋„ ์‹คํŒจํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ฆฌํŒฉํ† ๋ง์—๋Š” ํ•จ์ •์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ง€์—ฐ๋œ ์ผ๊ด€์„ฑ์€ ์ง€์—ฐ๊ณผ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค.

count ๋ฐ for_each ๋งค๊ฐœ๋ณ€์ˆ˜์—๋Š” ์ œํ•œ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ์žฅ์˜ ์˜ˆ์ œ์—์„œ๋Š” ๋ฃจํ”„ ๋ฐ ์กฐ๊ฑด๋ถ€ ๋…ผ๋ฆฌ์—์„œ count ๋งค๊ฐœ ๋ณ€์ˆ˜์™€ for_each ํ‘œํ˜„์‹์„ ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์„ฑ๋Šฅ์€ ์ข‹์ง€๋งŒ ์•Œ์•„์•ผ ํ•  ๋‘ ๊ฐ€์ง€ ์ค‘์š”ํ•œ ์ œํ•œ ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • Count ๋ฐ for_each๋Š” ๋ฆฌ์†Œ์Šค ์ถœ๋ ฅ ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • count ๋ฐ for_each๋Š” ๋ชจ๋“ˆ ๊ตฌ์„ฑ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

count ๋ฐ for_each๋Š” ๋ฆฌ์†Œ์Šค ์ถœ๋ ฅ ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ EC2 ์„œ๋ฒ„๋ฅผ ๋ฐฐํฌํ•ด์•ผ ํ•˜๋Š”๋ฐ ์–ด๋–ค ์ด์œ ๋กœ ASG๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์ง€ ์•Š๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด์„ธ์š”. ๊ท€ํ•˜์˜ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

resource "aws_instance" "example_1" {
   count             = 3
   ami                = "ami-0c55b159cbfafe1f0"
   instance_type = "t2.micro"
}

ํ•˜๋‚˜์”ฉ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

count ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ์ •์  ๊ฐ’์œผ๋กœ ์„ค์ •๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์ด ์ฝ”๋“œ๋Š” ๋ฌธ์ œ ์—†์ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. Apply ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋ฉด 2๊ฐœ์˜ EC2 ์„œ๋ฒ„๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ˜„์žฌ AWS ์ง€์—ญ ๋‚ด์˜ ๊ฐ ๊ฐ€์šฉ ์˜์—ญ(AZ)์— ํ•˜๋‚˜์˜ ์„œ๋ฒ„๋ฅผ ๋ฐฐํฌํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? ์ฝ”๋“œ๊ฐ€ aws_availability_zones ๋ฐ์ดํ„ฐ ์†Œ์Šค์—์„œ ์˜์—ญ ๋ชฉ๋ก์„ ๋กœ๋“œํ•˜๋„๋ก ํ•œ ๋‹ค์Œ ๊ฐ ์˜์—ญ์„ ๋ฐ˜๋ณตํ•˜๊ณ  count ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ฐ ๋ฐฐ์—ด ์ธ๋ฑ์Šค ์•ก์„ธ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๊ธฐ์— ECXNUMX ์„œ๋ฒ„๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

resource "aws_instance" "example_2" {
   count                   = length(data.aws_availability_zones.all.names)
   availability_zone   = data.aws_availability_zones.all.names[count.index]
   ami                     = "ami-0c55b159cbfafe1f0"
   instance_type       = "t2.micro"
}

data "aws_availability_zones" "all" {}

count ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์•„๋ฌด๋Ÿฐ ๋ฌธ์ œ ์—†์ด ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ด ์ฝ”๋“œ๋„ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ƒ์„ฑํ•ด์•ผ ํ•˜๋Š” ์„œ๋ฒ„ ์ˆ˜๊ฐ€ ์ผ๋ถ€ ๋ฆฌ์†Œ์Šค์˜ ์ถœ๋ ฅ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”? ์ด๋ฅผ ์ž…์ฆํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•์€ ์ด๋ฆ„์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด ์ž„์˜์˜ ์ •์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” random_integer ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

resource "random_integer" "num_instances" {
  min = 1
  max = 3
}

์ด ์ฝ”๋“œ๋Š” 1๊ณผ 3 ์‚ฌ์ด์˜ ๋‚œ์ˆ˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. aws_instance ๋ฆฌ์†Œ์Šค์˜ count ํŒŒ๋ผ๋ฏธํ„ฐ์—์„œ ์ด ๋ฆฌ์†Œ์Šค์˜ ์ถœ๋ ฅ์„ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์–ด๋–ค ์ผ์ด ๋ฐœ์ƒํ•˜๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

resource "aws_instance" "example_3" {
   count             = random_integer.num_instances.result
   ami                = "ami-0c55b159cbfafe1f0"
   instance_type = "t2.micro"
}

์ด ์ฝ”๋“œ์—์„œ terraform plan์„ ์‹คํ–‰ํ•˜๋ฉด ๋‹ค์Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

Error: Invalid count argument

   on main.tf line 30, in resource "aws_instance" "example_3":
   30: count = random_integer.num_instances.result

The "count" value depends on resource attributes that cannot be determined until apply, so Terraform cannot predict how many instances will be created. To work around this, use the -target argument to first apply only the resources that the count depends on.

Terraform์—์„œ๋Š” ๋ฆฌ์†Œ์Šค๊ฐ€ ์ƒ์„ฑ๋˜๊ฑฐ๋‚˜ ์ˆ˜์ •๋˜๊ธฐ ์ „์— ๊ณ„ํš ๋‹จ๊ณ„์—์„œ count ๋ฐ for_each๋ฅผ ๊ณ„์‚ฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” count ๋ฐ for_each๊ฐ€ ๋ฆฌํ„ฐ๋Ÿด, ๋ณ€์ˆ˜, ๋ฐ์ดํ„ฐ ์†Œ์Šค ๋ฐ ์‹ฌ์ง€์–ด ๋ฆฌ์†Œ์Šค ๋ชฉ๋ก(๊ธธ์ด๊ฐ€ ์˜ˆ์•ฝ ์‹œ๊ฐ„์— ๊ฒฐ์ •๋  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ)์„ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ณ„์‚ฐ๋œ ๋ฆฌ์†Œ์Šค ์ถœ๋ ฅ ๋ณ€์ˆ˜๋Š” ์ฐธ์กฐํ•  ์ˆ˜ ์—†์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

count ๋ฐ for_each๋Š” ๋ชจ๋“ˆ ๊ตฌ์„ฑ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์–ธ์  ๊ฐ€๋Š” ๋ชจ๋“ˆ ๊ตฌ์„ฑ์— count ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์€ ์œ ํ˜น์„ ๋Š๋‚„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

module "count_example" {
     source = "../../../../modules/services/webserver-cluster"

     count = 3

     cluster_name = "terraform-up-and-running-example"
     server_port = 8080
     instance_type = "t2.micro"
}

์ด ์ฝ”๋“œ๋Š” ๋ชจ๋“ˆ ๋‚ด์—์„œ count๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›น ์„œ๋ฒ„ ํด๋Ÿฌ์Šคํ„ฐ ๋ฆฌ์†Œ์Šค์˜ ๋ณต์‚ฌ๋ณธ 0๊ฐœ๋ฅผ ์ƒ์„ฑํ•˜๋ ค๊ณ  ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. ๋˜๋Š” count ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ XNUMX์œผ๋กœ ์„ค์ •ํ•˜์—ฌ ์ผ๋ถ€ ๋ถ€์šธ ์กฐ๊ฑด์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ชจ๋“ˆ ์—ฐ๊ฒฐ์„ ์„ ํƒ์ ์œผ๋กœ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ํ•ฉ๋ฆฌ์ ์ธ ์ฝ”๋“œ์ฒ˜๋Ÿผ ๋ณด์ผ ์ˆ˜ ์žˆ์ง€๋งŒ terraform ๊ณ„ํš์„ ์‹คํ–‰ํ•  ๋•Œ ๋‹ค์Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

Error: Reserved argument name in module block

   on main.tf line 13, in module "count_example":
   13: count = 3

The name "count" is reserved for use in a future version of Terraform.

์•ˆํƒ€๊น๊ฒŒ๋„ Terraform 0.12.6๋ถ€ํ„ฐ๋Š” ๋ชจ๋“ˆ ๋ฆฌ์†Œ์Šค์—์„œ count ๋˜๋Š” for_each๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Terraform 0.12 ๋ฆด๋ฆฌ์Šค ๋…ธํŠธ(http://bit.ly/3257bv4)์— ๋”ฐ๋ฅด๋ฉด HashiCorp๋Š” ํ–ฅํ›„ ์ด ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ๊ณ„ํš์ด๋ฏ€๋กœ ์ด ์ฑ…์„ ์ฝ๋Š” ์‹œ๊ธฐ์— ๋”ฐ๋ผ ์ด๋ฏธ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ํ™•์‹คํžˆ ์•Œ์•„๋ณด๋ ค๋ฉด, ์—ฌ๊ธฐ์—์„œ Terraform ๋ณ€๊ฒฝ ๋กœ๊ทธ๋ฅผ ์ฝ์–ด๋ณด์„ธ์š”..

์ œ๋กœ ๋‹ค์šดํƒ€์ž„ ๋ฐฐํฌ์˜ ํ•œ๊ณ„

ASG์™€ ํ•จ๊ป˜ create_before_destroy ๋ธ”๋ก์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ž๋™ ํ™•์žฅ ๊ทœ์น™์ด ์ง€์›๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ํ•œ ๊ฐ€์ง€ ์ฃผ์˜ ์‚ฌํ•ญ์„ ์ œ์™ธํ•˜๊ณ  ๊ฐ€๋™ ์ค‘์ง€ ์‹œ๊ฐ„ ์—†๋Š” ๋ฐฐํฌ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ํ›Œ๋ฅญํ•œ ์†”๋ฃจ์…˜์ž…๋‹ˆ๋‹ค. ๋˜๋Š” ๋” ์ •ํ™•ํ•˜๊ฒŒ ๋งํ•˜๋ฉด ๋ชจ๋“  ๋ฐฐํฌ์—์„œ ASG ํฌ๊ธฐ๊ฐ€ ๋‹ค์‹œ min_size๋กœ ์žฌ์„ค์ •๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์‹คํ–‰ ์ค‘์ธ ์„œ๋ฒ„ ์ˆ˜๋ฅผ ๋Š˜๋ฆฌ๊ธฐ ์œ„ํ•ด ์ž๋™ ํฌ๊ธฐ ์กฐ์ • ๊ทœ์น™์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, webserver-cluster ๋ชจ๋“ˆ์—๋Š” ์˜ค์ „ 9์‹œ์— ํด๋Ÿฌ์Šคํ„ฐ์˜ ์„œ๋ฒ„ ์ˆ˜๊ฐ€ 11๊ฐœ์—์„œ 9๊ฐœ๋กœ ๋Š˜์–ด๋‚˜๋Š” aws_autoscaling_schedule ๋ฆฌ์†Œ์Šค ์Œ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์˜ค์ „ XNUMX์‹œ์— ๋ฐฐํฌํ•˜๋ฉด ์ƒˆ ASG๋Š” XNUMX๋Œ€๊ฐ€ ์•„๋‹Œ XNUMX๋Œ€์˜ ์„œ๋ฒ„๋กœ ๋ถ€ํŒ…๋˜์–ด ๋‹ค์Œ ๋‚  ์˜ค์ „ XNUMX์‹œ๊นŒ์ง€ ๊ทธ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

์ด ์ œํ•œ์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • aws_autoscaling_schedule์˜ ๋ฐ˜๋ณต ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ 0 9 * * *(โ€œ์˜ค์ „ 9์‹œ์— ์‹คํ–‰โ€)์—์„œ 0-59 9-17 * * *(โ€œ์˜ค์ „ 9์‹œ๋ถ€ํ„ฐ ์˜คํ›„ 5์‹œ๊นŒ์ง€ XNUMX๋ถ„๋งˆ๋‹ค ์‹คํ–‰โ€)๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. ASG์— ์ด๋ฏธ XNUMX๊ฐœ์˜ ์„œ๋ฒ„๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์ด ์ž๋™ ํฌ๊ธฐ ์กฐ์ • ๊ทœ์น™์„ ๋‹ค์‹œ ์‹คํ–‰ํ•ด๋„ ์•„๋ฌด ๊ฒƒ๋„ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ASG๊ฐ€ ์ตœ๊ทผ์— ๋ฐฐํฌ๋œ ๊ฒฝ์šฐ ์ด ๊ทœ์น™์€ ์ตœ๋Œ€ XNUMX๋ถ„ ์•ˆ์— ์„œ๋ฒ„ ์ˆ˜๊ฐ€ XNUMX๊ฐœ์— ๋„๋‹ฌํ•˜๋„๋ก ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์™„์ „ํžˆ ์„ธ๋ จ๋œ ์ ‘๊ทผ ๋ฐฉ์‹์€ ์•„๋‹ˆ๋ฉฐ, ์„œ๋ฒ„๋ฅผ XNUMX๋Œ€์—์„œ XNUMX๋Œ€๋กœ ํฌ๊ฒŒ ์ ํ”„ํ•˜๋Š” ๊ฒฝ์šฐ์—๋„ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • AWS API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ASG์˜ ํ™œ์„ฑ ์„œ๋ฒ„ ์ˆ˜๋ฅผ ๊ฒฐ์ •ํ•˜๊ณ , ์™ธ๋ถ€ ๋ฐ์ดํ„ฐ ์›๋ณธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฅผ ํ˜ธ์ถœํ•˜๊ณ (249ํŽ˜์ด์ง€์˜ "์™ธ๋ถ€ ๋ฐ์ดํ„ฐ ์›๋ณธ" ์ฐธ์กฐ) ASG์˜ Desired_capacity ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ˜ํ™˜๋œ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•˜๋Š” ์‚ฌ์šฉ์ž ์ง€์ • ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์Šคํฌ๋ฆฝํŠธ. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ฐ๊ฐ์˜ ์ƒˆ๋กœ์šด ASG ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•ญ์ƒ ๊ธฐ์กด Terraform ์ฝ”๋“œ์™€ ๋™์ผํ•œ ์šฉ๋Ÿ‰์œผ๋กœ ์‹คํ–‰๋˜๋ฏ€๋กœ ์œ ์ง€ ๊ด€๋ฆฌ๊ฐ€ ๋” ์–ด๋ ค์›Œ์ง‘๋‹ˆ๋‹ค.

๋ฌผ๋ก  Terraform์€ ๋‹ค์šดํƒ€์ž„ ์—†๋Š” ๋ฐฐํฌ๋ฅผ ์œ„ํ•œ ๊ธฐ๋ณธ ์ง€์›์„ ์ด์ƒ์ ์œผ๋กœ ๊ฐ–์ถ”๊ณ  ์žˆ์ง€๋งŒ 2019๋…„ XNUMX์›” ํ˜„์žฌ HashiCorp ํŒ€์€ ์ด ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ๊ณ„ํš์ด ์—†์Šต๋‹ˆ๋‹ค(์„ธ๋ถ€์ •๋ณด - ์—ฌ๊ธฐ).

์˜ฌ๋ฐ”๋ฅธ ๊ณ„ํš์ด ์„ฑ๊ณต์ ์œผ๋กœ ๊ตฌํ˜„๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋•Œ๋กœ๋Š” plan ๋ช…๋ น์ด ์™„๋ฒฝํ•˜๊ฒŒ ์˜ฌ๋ฐ”๋ฅธ ๋ฐฐํฌ ๊ณ„ํš์„ ์ƒ์„ฑํ•˜์ง€๋งŒ Apply ๋ช…๋ น์ด ์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, 2์žฅ ์•ž๋ถ€๋ถ„์—์„œ ์ƒ์„ฑํ•œ IAM ์‚ฌ์šฉ์ž์— ์‚ฌ์šฉํ•œ ๊ฒƒ๊ณผ ๋™์ผํ•œ ์ด๋ฆ„์œผ๋กœ aws_iam_user ๋ฆฌ์†Œ์Šค๋ฅผ ์ถ”๊ฐ€ํ•ด ๋ณด์‹ญ์‹œ์˜ค.

resource "aws_iam_user" "existing_user" {
   # ะŸะพะดัั‚ะฐะฒัŒั‚ะต ััŽะดะฐ ะธะผั ัƒะถะต ััƒั‰ะตัั‚ะฒัƒัŽั‰ะตะณะพ ะฟะพะปัŒะทะพะฒะฐั‚ะตะปั IAM,
   # ั‡ั‚ะพะฑั‹ ะฟะพะฟั€ะฐะบั‚ะธะบะพะฒะฐั‚ัŒัั ะฒ ะธัะฟะพะปัŒะทะพะฒะฐะฝะธะธ ะบะพะผะฐะฝะดั‹ terraform import
   name = "yevgeniy.brikman"
}

์ด์ œ plan ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋ฉด Terraform์€ ๊ฒ‰์œผ๋กœ๋Š” ํ•ฉ๋ฆฌ์ ์œผ๋กœ ๋ณด์ด๋Š” ๋ฐฐํฌ ๊ณ„ํš์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

Terraform will perform the following actions:

   # aws_iam_user.existing_user will be created
   + resource "aws_iam_user" "existing_user" {
         + arn                  = (known after apply)
         + force_destroy   = false
         + id                    = (known after apply)
         + name               = "yevgeniy.brikman"
         + path                 = "/"
         + unique_id         = (known after apply)
      }

Plan: 1 to add, 0 to change, 0 to destroy.

Apply ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋ฉด ๋‹ค์Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

Error: Error creating IAM User yevgeniy.brikman: EntityAlreadyExists:
User with name yevgeniy.brikman already exists.

   on main.tf line 10, in resource "aws_iam_user" "existing_user":
   10: resource "aws_iam_user" "existing_user" {

๋ฌผ๋ก  ๋ฌธ์ œ๋Š” ํ•ด๋‹น ์ด๋ฆ„์„ ๊ฐ€์ง„ IAM ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋ฏธ ์กด์žฌํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” IAM ์‚ฌ์šฉ์ž๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๊ฑฐ์˜ ๋ชจ๋“  ๋ฆฌ์†Œ์Šค์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€ ์ˆ˜๋™์œผ๋กœ ๋˜๋Š” ๋ช…๋ น์ค„์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด ๋ฆฌ์†Œ์Šค๋ฅผ ๋งŒ๋“ค์—ˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์ง€๋งŒ ์–ด๋Š ์ชฝ์ด๋“  ID๊ฐ€ ์ผ์น˜ํ•˜๋ฉด ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. Terraform์„ ์ฒ˜์Œ ์ ‘ํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์„ ๋†€๋ผ๊ฒŒ ํ•˜๋Š” ์ด ์˜ค๋ฅ˜์—๋Š” ๋‹ค์–‘ํ•œ ๋ณ€ํ˜•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•ต์‹ฌ์€ terraform plan ๋ช…๋ น์ด Terraform ์ƒํƒœ ํŒŒ์ผ์— ์ง€์ •๋œ ๋ฆฌ์†Œ์Šค๋งŒ ๊ณ ๋ คํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฆฌ์†Œ์Šค๊ฐ€ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ์ƒ์„ฑ๋œ ๊ฒฝ์šฐ(์˜ˆ: AWS ์ฝ˜์†”์„ ํด๋ฆญํ•˜์—ฌ ์ˆ˜๋™์œผ๋กœ) ์ƒํƒœ ํŒŒ์ผ์— ํฌํ•จ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ Terraform์€ ๊ณ„ํš ๋ช…๋ น์„ ์‹คํ–‰ํ•  ๋•Œ ํ•ด๋‹น ๋ฆฌ์†Œ์Šค๋ฅผ ๊ณ ๋ คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ์–ธ๋œป ๋ณด๋ฉด ์˜ณ์€ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ๊ณ„ํš์€ ์„ฑ๊ณตํ•˜์ง€ ๋ชปํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์œผ๋กœ๋ถ€ํ„ฐ ๋ฐฐ์šธ ์ˆ˜ ์žˆ๋Š” ๋‘ ๊ฐ€์ง€ ๊ตํ›ˆ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ด๋ฏธ Terraform ์ž‘์—…์„ ์‹œ์ž‘ํ–ˆ๋‹ค๋ฉด ๋‹ค๋ฅธ ๊ฒƒ์„ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์„ธ์š”. ์ธํ”„๋ผ์˜ ์ผ๋ถ€๊ฐ€ Terraform์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ด€๋ฆฌ๋˜๋Š” ๊ฒฝ์šฐ ๋” ์ด์ƒ ์ˆ˜๋™์œผ๋กœ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ด์ƒํ•œ Terraform ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์œ„ํ—˜์ด ์žˆ์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ฝ”๋“œ๊ฐ€ ๋” ์ด์ƒ ์ธํ”„๋ผ๋ฅผ ์ •ํ™•ํ•˜๊ฒŒ ํ‘œํ˜„ํ•˜์ง€ ๋ชปํ•˜๋ฏ€๋กœ IaC์˜ ๋งŽ์€ ์ด์ ์ด ๋ฌดํšจํ™”๋ฉ๋‹ˆ๋‹ค.
  • ์ด๋ฏธ ์ผ๋ถ€ ์ธํ”„๋ผ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ import ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. ๊ธฐ์กด ์ธํ”„๋ผ์—์„œ Terraform์„ ์‚ฌ์šฉํ•˜๊ธฐ ์‹œ์ž‘ํ•˜๋Š” ๊ฒฝ์šฐ terraform import ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฅผ ์ƒํƒœ ํŒŒ์ผ์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ Terraform์€ ์–ด๋–ค ์ธํ”„๋ผ๋ฅผ ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๋Š”์ง€ ์•Œ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. import ๋ช…๋ น์€ ๋‘ ๊ฐœ์˜ ์ธ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ๋Š” ๊ตฌ์„ฑ ํŒŒ์ผ์˜ ๋ฆฌ์†Œ์Šค ์ฃผ์†Œ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์˜ ๊ตฌ๋ฌธ์€ ๋ฆฌ์†Œ์Šค ๋งํฌ์˜ ๊ฒฝ์šฐ์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค: _. (์˜ˆ: aws_iam_user.existing_user) ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” ๊ฐ€์ ธ์˜ฌ ๋ฆฌ์†Œ์Šค์˜ ID์ž…๋‹ˆ๋‹ค. ๋ฆฌ์†Œ์Šค ID aws_iam_user๊ฐ€ ์‚ฌ์šฉ์ž ์ด๋ฆ„(์˜ˆ: yevgeniy.brikman)์ด๊ณ  ๋ฆฌ์†Œ์Šค ID aws_instance๊ฐ€ EC2 ์„œ๋ฒ„ ID(์˜ˆ: i-190e22e5)๋ผ๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ฆฌ์†Œ์Šค๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ•์€ ์ผ๋ฐ˜์ ์œผ๋กœ ํ•ด๋‹น ํŽ˜์ด์ง€ ํ•˜๋‹จ์˜ ์„ค๋ช…์„œ์— ๋‚˜์™€ ์žˆ์Šต๋‹ˆ๋‹ค.

    ๋‹ค์Œ์€ 2์žฅ์—์„œ IAM ์‚ฌ์šฉ์ž์™€ ํ•จ๊ป˜ Terraform ๊ตฌ์„ฑ์— ์ถ”๊ฐ€ํ•œ aws_iam_user ๋ฆฌ์†Œ์Šค๋ฅผ ๋™๊ธฐํ™”ํ•˜๋Š” ๊ฐ€์ ธ์˜ค๊ธฐ ๋ช…๋ น์ž…๋‹ˆ๋‹ค(๋ฌผ๋ก  yevgeniy.brikman์„ ์‚ฌ์šฉ์ž ์ด๋ฆ„์œผ๋กœ ๋Œ€์ฒด).

    $ terraform import aws_iam_user.existing_user yevgeniy.brikman

    Terraform์€ AWS API๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ IAM ์‚ฌ์šฉ์ž๋ฅผ ์ฐพ๊ณ  ํ•ด๋‹น ์‚ฌ์šฉ์ž์™€ Terraform ๊ตฌ์„ฑ์˜ aws_iam_user.existing_user ๋ฆฌ์†Œ์Šค ์‚ฌ์ด์— ์ƒํƒœ ํŒŒ์ผ ์—ฐ๊ฒฐ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ๋ถ€ํ„ฐ plan ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋ฉด Terraform์€ IAM ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋ฏธ ์กด์žฌํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์ธ์‹ํ•˜๊ณ  ์ด๋ฅผ ๋‹ค์‹œ ์ƒ์„ฑํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

    Terraform์œผ๋กœ ๊ฐ€์ ธ์˜ค๋ ค๋Š” ๋ฆฌ์†Œ์Šค๊ฐ€ ์ด๋ฏธ ๋งŽ์€ ๊ฒฝ์šฐ ์ˆ˜๋™์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์”ฉ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์ด ๋ฒˆ๊ฑฐ๋กœ์šธ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์€ ์ฃผ๋ชฉํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ AWS ๊ณ„์ •์—์„œ ์ฝ”๋“œ์™€ ์ƒํƒœ๋ฅผ ์ž๋™์œผ๋กœ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋Š” Terraforming(http://terraforming.dtan4.net/)๊ณผ ๊ฐ™์€ ๋„๊ตฌ๋ฅผ ์‚ดํŽด๋ณผ ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

    ๋ฆฌํŒฉํ† ๋ง์—๋Š” ํ•จ์ •์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ๋ฆฌํŒฉํ† ๋ง ์™ธ๋ถ€ ๋™์ž‘์€ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ์ฝ”๋“œ์˜ ๋‚ด๋ถ€ ๊ตฌ์กฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์ผ๋ฐ˜์ ์ธ ๊ด€ํ–‰์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์ฝ”๋“œ๋ฅผ ๋” ๋ช…ํ™•ํ•˜๊ณ  ๊น”๋”ํ•˜๋ฉฐ ์œ ์ง€ ๊ด€๋ฆฌํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฆฌํŒฉํ† ๋ง์€ ์ •๊ธฐ์ ์œผ๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ํ•„์ˆ˜ ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Terraform์ด๋‚˜ ๊ธฐํƒ€ IaC ๋„๊ตฌ์˜ ๊ฒฝ์šฐ ์ฝ”๋“œ ์กฐ๊ฐ์˜ "์™ธ๋ถ€ ๋™์ž‘"์ด ๋ฌด์—‡์„ ์˜๋ฏธํ•˜๋Š”์ง€ ๋งค์šฐ ์ฃผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ์˜ˆ๋ฅผ ๋“ค์–ด, ์ผ๋ฐ˜์ ์ธ ์œ ํ˜•์˜ ๋ฆฌํŒฉํ† ๋ง์€ ๋ณ€์ˆ˜๋‚˜ ํ•จ์ˆ˜์˜ ์ด๋ฆ„์„ ๋” ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šด ์ด๋ฆ„์œผ๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งŽ์€ IDE์—๋Š” ๋ฆฌํŒฉํ† ๋ง ์ง€์› ๊ธฐ๋Šฅ์ด ๋‚ด์žฅ๋˜์–ด ์žˆ์œผ๋ฉฐ ํ”„๋กœ์ ํŠธ ์ „์ฒด์—์„œ ๋ณ€์ˆ˜์™€ ํ•จ์ˆ˜์˜ ์ด๋ฆ„์„ ์ž๋™์œผ๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฒ”์šฉ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์—์„œ๋Š” ์ด๋Š” ์ƒ๊ฐํ•˜์ง€ ๋ชปํ•  ์ˆ˜๋„ ์žˆ๋Š” ์‚ฌ์†Œํ•œ ์ ˆ์ฐจ์ด์ง€๋งŒ Terraform์—์„œ๋Š” ์ด์— ๋งค์šฐ ์ฃผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ค‘๋‹จ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ์˜ˆ๋ฅผ ๋“ค์–ด webserver-cluster ๋ชจ๋“ˆ์—๋Š” ์ž…๋ ฅ ๋ณ€์ˆ˜ Cluster_name์ด ์žˆ์Šต๋‹ˆ๋‹ค.

    variable "cluster_name" {
       description = "The name to use for all the cluster resources"
       type          = string
    }

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

    ์‚ฌ์‹ค webserver-cluster ๋ชจ๋“ˆ์€ ๋‘ ๋ณด์•ˆ ๊ทธ๋ฃน๊ณผ ALB์˜ name ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํฌํ•จํ•˜์—ฌ ์—ฌ๋Ÿฌ ๋ฆฌ์†Œ์Šค์—์„œ Cluster_name ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

    resource "aws_lb" "example" {
       name                    = var.cluster_name
       load_balancer_type = "application"
       subnets = data.aws_subnet_ids.default.ids
       security_groups      = [aws_security_group.alb.id]
    }

    ๋ฆฌ์†Œ์Šค์˜ name ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด Terraform์€ ํ•ด๋‹น ๋ฆฌ์†Œ์Šค์˜ ์ด์ „ ๋ฒ„์ „์„ ์‚ญ์ œํ•˜๊ณ  ๊ทธ ์ž๋ฆฌ์— ์ƒˆ ๋ฒ„์ „์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ•ด๋‹น ๋ฆฌ์†Œ์Šค๊ฐ€ ALB์ธ ๊ฒฝ์šฐ ํ•ด๋‹น ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ญ์ œํ•˜๊ณ  ์ƒˆ ๋ฒ„์ „์„ ๋‹ค์šด๋กœ๋“œํ•˜๋Š” ์‚ฌ์ด์— ํŠธ๋ž˜ํ”ฝ์„ ์›น ์„œ๋ฒ„๋กœ ๋ฆฌ๋””๋ ‰์…˜ํ•˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ์—†์Šต๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ณด์•ˆ ๊ทธ๋ฃน์ด ์‚ญ์ œ๋˜๋ฉด ์„œ๋ฒ„๋Š” ์ƒˆ ๊ทธ๋ฃน์ด ์ƒ์„ฑ๋  ๋•Œ๊นŒ์ง€ ๋ชจ๋“  ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ์„ ๊ฑฐ๋ถ€ํ•˜๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

    ๊ด€์‹ฌ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ๋˜ ๋‹ค๋ฅธ ์œ ํ˜•์˜ ๋ฆฌํŒฉํ† ๋ง์€ Terraform ID๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. webserver-cluster ๋ชจ๋“ˆ์˜ aws_security_group ๋ฆฌ์†Œ์Šค๋ฅผ ์˜ˆ๋กœ ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

    resource "aws_security_group" "instance" {
      # (...)
    }

    ์ด ๋ฆฌ์†Œ์Šค์˜ ์‹๋ณ„์ž๋ฅผ ์ธ์Šคํ„ด์Šค๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๋ฆฌํŒฉํ† ๋ง ์ค‘์— ๋” ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šด(๊ท€ํ•˜์˜ ์˜๊ฒฌ์œผ๋กœ๋Š”) ์ด๋ฆ„์ธ Cluster_instance๋กœ ๋ณ€๊ฒฝํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค๊ณ  ์ƒ์ƒํ•ด ๋ณด์‹ญ์‹œ์˜ค.

    resource "aws_security_group" "cluster_instance" {
       # (...)
    }

    ๊ฒฐ๊ตญ์—๋Š” ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚ ๊นŒ์š”? ๋งž์Šต๋‹ˆ๋‹ค. ํ˜ผ๋ž€์ž…๋‹ˆ๋‹ค.

    Terraform์€ ๊ฐ ๋ฆฌ์†Œ์Šค ID๋ฅผ ํด๋ผ์šฐ๋“œ ์ œ๊ณต์—…์ฒด ID์™€ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, iam_user๋Š” AWS IAM ์‚ฌ์šฉ์ž ID์™€ ์—ฐ๊ฒฐ๋˜๊ณ , aws_instance๋Š” AWS EC2 ์„œ๋ฒ„ ID์™€ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค. ๋ฆฌ์†Œ์Šค ID๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด(์˜ˆ: aws_security_group์˜ ๊ฒฝ์šฐ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ธ์Šคํ„ด์Šค์—์„œ Cluster_instance๋กœ) Terraform์œผ๋กœ ์ด์ „ ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ญ์ œํ•˜๊ณ  ์ƒˆ ๋ฆฌ์†Œ์Šค๋ฅผ ์ถ”๊ฐ€ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ ์šฉํ•˜๋ฉด Terraform์€ ์ด์ „ ๋ณด์•ˆ ๊ทธ๋ฃน์„ ์‚ญ์ œํ•˜๊ณ  ์ƒˆ ๋ณด์•ˆ ๊ทธ๋ฃน์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐ˜๋ฉด ์„œ๋ฒ„๋Š” ๋ชจ๋“  ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ์„ ๊ฑฐ๋ถ€ํ•˜๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

    ์ด ํ† ๋ก ์—์„œ ์•Œ์•„์•ผ ํ•  ๋„ค ๊ฐ€์ง€ ์ฃผ์š” ๊ตํ›ˆ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

    • ํ•ญ์ƒ plan ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. ์ด ๋ชจ๋“  ๊ฑธ๋ฆผ๋Œ์„ ๋“œ๋Ÿฌ๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ถœ๋ ฅ์„ ์ฃผ์˜ ๊นŠ๊ฒŒ ๊ฒ€ํ† ํ•˜๊ณ  Terraform์ด ์‚ญ์ œํ•ด์„œ๋Š” ์•ˆ ๋  ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ญ์ œํ•  ๊ณ„ํš์ธ ์ƒํ™ฉ์— ์ฃผ์˜ํ•˜์„ธ์š”.
    • ์‚ญ์ œํ•˜๊ธฐ ์ „์— ์ƒ์„ฑํ•˜์„ธ์š”. ๋ฆฌ์†Œ์Šค๋ฅผ ๊ต์ฒดํ•˜๋ ค๋ฉด ์›๋ณธ์„ ์‚ญ์ œํ•˜๊ธฐ ์ „์— ๋Œ€์ฒด ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•˜๋Š”์ง€ ์‹ ์ค‘ํ•˜๊ฒŒ ์ƒ๊ฐํ•ด ๋ณด์„ธ์š”. ๋Œ€๋‹ต์ด '์˜ˆ'๋ผ๋ฉด create_before_destroy๊ฐ€ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‘ ๋‹จ๊ณ„๋ฅผ ์ˆ˜ํ–‰ํ•˜์—ฌ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ˆ˜๋™์œผ๋กœ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋จผ์ € ๊ตฌ์„ฑ์— ์ƒˆ ๋ฆฌ์†Œ์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์ ์šฉ ๋ช…๋ น์„ ์‹คํ–‰ํ•œ ๋‹ค์Œ ๊ตฌ์„ฑ์—์„œ ์ด์ „ ๋ฆฌ์†Œ์Šค๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ์ ์šฉ ๋ช…๋ น์„ ๋‹ค์‹œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
    • ์‹๋ณ„์ž๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ญ์ œํ•˜๊ณ  ์ƒˆ ๋ฒ„์ „์„ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ  ๋ฆฌ์†Œ์Šค์™€ ์—ฐ๊ฒฐ๋œ ID๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด(์˜ˆ: aws_security_group ์ด๋ฆ„์„ ์ธ์Šคํ„ด์Šค์—์„œ Cluster_instance๋กœ ๋ณ€๊ฒฝ) ๊ทธ์— ๋”ฐ๋ผ Terraform ์ƒํƒœ ํŒŒ์ผ์„ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ž‘์—…์„ ์ˆ˜๋™์œผ๋กœ ์ˆ˜ํ–‰ํ•˜์ง€ ๋งˆ์„ธ์š”. ๋Œ€์‹  terraform state ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์„ธ์š”. ์‹๋ณ„์ž ์ด๋ฆ„์„ ๋ฐ”๊ฟ€ ๋•Œ ๋‹ค์Œ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋Š” terraform state mv ๋ช…๋ น์„ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
      terraform state mv <ORIGINAL_REFERENCE> <NEW_REFERENCE>

      ORIGINAL_REFERENCE๋Š” ํ˜„์žฌ ํ˜•์‹์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์ฐธ์กฐํ•˜๋Š” ํ‘œํ˜„์‹์ด๊ณ  NEW_REFERENCE๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ์ด๋™ํ•˜๋ ค๋Š” ์œ„์น˜์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, aws_security_group ๊ทธ๋ฃน์˜ ์ด๋ฆ„์„ ์ธ์Šคํ„ด์Šค์—์„œ Cluster_instance๋กœ ๋ฐ”๊พธ๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ ๋ช…๋ น์„ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

      $ terraform state mv 
         aws_security_group.instance 
         aws_security_group.cluster_instance

      ์ด๋Š” ์ด์ „์— aws_security_group.instance์™€ ์—ฐ๊ฒฐ๋˜์—ˆ๋˜ ์ƒํƒœ๊ฐ€ ์ด์ œ aws_security_group.cluster_instance์™€ ์—ฐ๊ฒฐ๋˜์–ด์•ผ ํ•จ์„ Terraform์— ์•Œ๋ ค์ค๋‹ˆ๋‹ค. ์ด๋ฆ„์„ ๋ฐ”๊พธ๊ณ  ์ด ๋ช…๋ น์„ ์‹คํ–‰ํ•œ ํ›„์—๋„ terraform plan์— ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ํ‘œ์‹œ๋˜์ง€ ์•Š์œผ๋ฉด ๋ชจ๋“  ์ž‘์—…์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ˆ˜ํ–‰ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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

    ์ง€์—ฐ๋œ ์ผ๊ด€์„ฑ์€ ์ผ๊ด€์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค... ์ง€์—ฐ๊ณผ ํ•จ๊ป˜

    AWS์™€ ๊ฐ™์€ ์ผ๋ถ€ ํด๋ผ์šฐ๋“œ ์ œ๊ณต์—…์ฒด์˜ API๋Š” ๋น„๋™๊ธฐ์‹์ด๋ฉฐ ์ผ๊ด€์„ฑ์ด ์ง€์—ฐ๋ฉ๋‹ˆ๋‹ค. ๋น„๋™๊ธฐ์„ฑ์€ ์š”์ฒญ๋œ ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์ฆ‰์‹œ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ผ๊ด€์„ฑ์ด ์ง€์—ฐ๋œ๋‹ค๋Š” ๊ฒƒ์€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์‹œ์Šคํ…œ ์ „์ฒด์— ์ „ํŒŒ๋˜๋Š” ๋ฐ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ผ์ด ๋ฐœ์ƒํ•˜๋Š” ๋™์•ˆ ๊ท€ํ•˜์˜ ์‘๋‹ต์€ API ํ˜ธ์ถœ์— ์‘๋‹ตํ•˜๋Š” ๋ฐ์ดํ„ฐ ์›๋ณธ ๋ณต์ œ๋ณธ์— ๋”ฐ๋ผ ์ผ๊ด€๋˜์ง€ ์•Š๊ณ  ์ข…์†๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ์˜ˆ๋ฅผ ๋“ค์–ด AWS์— EC2 ์„œ๋ฒ„ ์ƒ์„ฑ์„ ์š”์ฒญํ•˜๋Š” API ํ˜ธ์ถœ์„ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. API๋Š” ์„œ๋ฒ„ ์ž์ฒด๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ๊ฑฐ์˜ ์ฆ‰์‹œ "์„ฑ๊ณต" ์‘๋‹ต(201 ์ƒ์„ฑ๋จ)์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰์‹œ ์—ฐ๊ฒฐ์„ ์‹œ๋„ํ•˜๋ฉด ํ•ด๋‹น ์‹œ์ ์— AWS๊ฐ€ ์—ฌ์ „ํžˆ ๋ฆฌ์†Œ์Šค๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  ์žˆ๊ฑฐ๋‚˜ ์„œ๋ฒ„๊ฐ€ ์•„์ง ๋ถ€ํŒ…๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฑฐ์˜ ํ™•์‹คํžˆ ์‹คํŒจํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด ์„œ๋ฒ„์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด ๋‹ค์‹œ ํ˜ธ์ถœํ•˜๋ฉด ์˜ค๋ฅ˜(404 ์ฐพ์„ ์ˆ˜ ์—†์Œ)๊ฐ€ ๋‚˜ํƒ€๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” ์ด EC2 ์„œ๋ฒ„์— ๋Œ€ํ•œ ์ •๋ณด๊ฐ€ ์–ด๋””์—์„œ๋‚˜ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ด์ง€๊ธฐ ์ „์— ์—ฌ์ „ํžˆ AWS ์ „์ฒด์— ์ „ํŒŒ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. ๋ช‡ ์ดˆ ์ •๋„ ๊ธฐ๋‹ค๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    ์ง€์—ฐ ์ผ๊ด€์„ฑ์ด ์žˆ๋Š” ๋น„๋™๊ธฐ API๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋งˆ๋‹ค ์ž‘์—…์ด ์™„๋ฃŒ๋˜์–ด ์‹œ์Šคํ…œ์— ์ „ํŒŒ๋  ๋•Œ๊นŒ์ง€ ์ฃผ๊ธฐ์ ์œผ๋กœ ์š”์ฒญ์„ ์žฌ์‹œ๋„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์•ˆํƒ€๊น๊ฒŒ๋„ AWS SDK๋Š” ์ด์— ๋Œ€ํ•œ ์ข‹์€ ๋„๊ตฌ๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š์œผ๋ฉฐ Terraform ํ”„๋กœ์ ํŠธ๋Š” 6813(https://github.com/hashicorp/terraform/issues/6813)๊ณผ ๊ฐ™์€ ๋งŽ์€ ๋ฒ„๊ทธ๋กœ ์ธํ•ด ์–ด๋ ค์›€์„ ๊ฒช์—ˆ์Šต๋‹ˆ๋‹ค.

    $ terraform apply
    aws_subnet.private-persistence.2: InvalidSubnetID.NotFound:
    The subnet ID 'subnet-xxxxxxx' does not exist

    ์ฆ‰, ๋ฆฌ์†Œ์Šค(์˜ˆ: ์„œ๋ธŒ๋„ท)๋ฅผ ์ƒ์„ฑํ•œ ๋‹ค์Œ ์ด์— ๋Œ€ํ•œ ์ผ๋ถ€ ์ •๋ณด(์˜ˆ: ์ƒˆ๋กœ ์ƒ์„ฑ๋œ ์„œ๋ธŒ๋„ท์˜ ID)๋ฅผ ์–ป์œผ๋ ค๊ณ  ์‹œ๋„ํ•˜์ง€๋งŒ Terraform์ด ์ด๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฒ„๊ทธ(6813 ํฌํ•จ)๋Š” ๋Œ€๋ถ€๋ถ„ ์ˆ˜์ •๋˜์—ˆ์ง€๋งŒ ํŠนํžˆ Terraform์ด ์ƒˆ๋กœ์šด ๋ฆฌ์†Œ์Šค ์œ ํ˜•์— ๋Œ€ํ•œ ์ง€์›์„ ์ถ”๊ฐ€ํ•  ๋•Œ ์—ฌ์ „ํžˆ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์„ฑ๊ฐ€์‹  ์ผ์ด์ง€๋งŒ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์•„๋ฌด๋Ÿฐ ํ•ด๋ฅผ ๋ผ์น˜ ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. terraform Apply๋ฅผ ๋‹ค์‹œ ์‹คํ–‰ํ•˜๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋•Œ์ฏค์—๋Š” ์ •๋ณด๊ฐ€ ์ด๋ฏธ ์‹œ์Šคํ…œ ์ „์ฒด์— ํผ์ ธ ์žˆ์„ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

    ์ด ๋ฐœ์ทŒ๋ฌธ์€ Evgeniy Brikman์˜ ์ฑ…์—์„œ ๋ฐœ์ทŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. "Terraform: ์ฝ”๋“œ ์ˆ˜์ค€์˜ ์ธํ”„๋ผ".

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€