๐ŸŽฏ ๊ตฌ์„ฑ ๊ด€๋ฆฌ์˜ ํ•ต์‹ฌ ์›๋ฆฌ์™€ Terraform์„ ํ™œ์šฉํ•œ IaC ์‹ค์Šต์„ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ“— Today I Learned

CI/CD ํŒŒ์ดํ”„๋ผ์ธ์„ ๊ตฌ์„ฑํ•˜๋ฉด์„œ ๋นŒ๋“œ, ํ…Œ์ŠคํŠธ, ๋ฐฐํฌ ์ž๋™ํ™”๋ฅผ ์ฐจ๊ทผ์ฐจ๊ทผ ์™„์„ฑํ•ด ์™”๋‹ค๋ฉด, ์ด์ œ ๋‚จ์€ ๊ณผ์ œ๋Š” ์‹œ์Šคํ…œ ํ™˜๊ฒฝ ์ž์ฒด๋ฅผ ์–ด๋–ป๊ฒŒ ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ์œ ์ง€ํ•  ๊ฒƒ์ธ๊ฐ€์ž…๋‹ˆ๋‹ค.

๊ตฌ์„ฑ ๊ด€๋ฆฌ (Configuration Management)

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

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

๊ทธ๋ž˜์„œ ๊ตฌ์„ฑ(configuration)์„ ํ•จ๊ป˜ ๊ด€๋ฆฌํ•˜๊ณ  ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ” ๊ตฌ์„ฑ ๊ด€๋ฆฌ์™€ ๋ฒ„์ „ ๊ด€๋ฆฌ์˜ ์ฐจ์ด์ 

ํ•ญ๋ชฉ๊ตฌ์„ฑ ๊ด€๋ฆฌ (Configuration Management)๋ฒ„์ „ ๊ด€๋ฆฌ (Version Control)
๊ด€๋ฆฌ ๋Œ€์ƒ์‹œ์Šคํ…œ์˜ ์„ค์ •, ํ™˜๊ฒฝ, ์˜์กด์„ฑ, ์ธํ”„๋ผ ๊ตฌ์„ฑ ๋“ฑ์†Œ์Šค ์ฝ”๋“œ, ๋ฌธ์„œ, ์„ค์ • ํŒŒ์ผ ๋“ฑ ํ…์ŠคํŠธ ์ค‘์‹ฌ์˜ ๋ณ€๊ฒฝ ๋‚ด์šฉ
๊ด€๋ฆฌ ๋ฒ”์œ„์†Œํ”„ํŠธ์›จ์–ด๊ฐ€ ์‹คํ–‰๋˜๋Š” ์ „์ฒด ํ™˜๊ฒฝ ํฌํ•จ๊ฐœ๋ฐœ ์ค‘์ธ ์ฝ”๋“œ ๋ฐ ์ด๋ ฅ ์ค‘์‹ฌ
๋ชฉ์ ์ผ๊ด€๋œ ์‹คํ–‰ ํ™˜๊ฒฝ ์œ ์ง€, ๋ฐฐํฌ ์‹œ ํ™˜๊ฒฝ ์žฌํ˜„์ฝ”๋“œ ๋ณ€๊ฒฝ ์ด๋ ฅ ์ถ”์ , ํ˜‘์—… ์‹œ ์ถฉ๋Œ ๋ฐฉ์ง€
๋Œ€ํ‘œ ๋„๊ตฌAnsible, Puppet, Chef, Terraform, Helm ๋“ฑGit, SVN, Mercurial ๋“ฑ
์ž๋™ํ™” ์—ญํ• ๋ฐฐํฌ ์ž๋™ํ™”, ์‹œ์Šคํ…œ ๊ตฌ์„ฑ ์ž๋™ํ™”์ฝ”๋“œ ๋ฆฌ๋ทฐ, ๋ธŒ๋žœ์น˜ ์ „๋žต, ํ˜‘์—… ๊ธฐ๋ฐ˜ ๊ฐœ๋ฐœ ํ๋ฆ„



IaC (Infrastructure as Code)

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


IaC ์žฅ์ 

  • ์ผ๊ด€์„ฑ : ๋งค๋ฒˆ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ธํ”„๋ผ๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Œ

  • ์žฌํ˜„์„ฑ : ๋™์ผํ•œ ํ™˜๊ฒฝ์„ ์–ธ์ œ๋“ ์ง€ ๋ฐ˜๋ณตํ•ด์„œ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Œ

  • ๋ฒ„์ „ ๊ด€๋ฆฌ ๊ฐ€๋Šฅ : Git ๋“ฑ์œผ๋กœ ๋ณ€๊ฒฝ ์ด๋ ฅ์„ ์ถ”์ ํ•  ์ˆ˜ ์žˆ์Œ

  • ํ˜‘์—…์— ์šฉ์ด : ํŒ€์› ๊ฐ„์— ํ™˜๊ฒฝ ์ •์˜ ๊ณต์œ  ๋ฐ ๋ฆฌ๋ทฐ ๊ฐ€๋Šฅ

  • CI/CD์— ์ ํ•ฉ : ์ฝ”๋“œ๋กœ ์ธํ”„๋ผ๋ฅผ ๋ฐฐํฌํ•˜๋‹ˆ ์ž๋™ํ™” ํŒŒ์ดํ”„๋ผ์ธ๊ณผ ํ†ตํ•ฉ ์‰ฌ




ํ…Œ๋ผํผ (Terraform)

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

๐Ÿ‘‰ ํ…Œ๋ผํผ ๋‹ค์šด๋กœ๋“œ ๋งํฌ

๐Ÿ“ฆ ์œˆ๋„์šฐ ์‚ฌ์šฉ์ž ํ…Œ๋ผํผ ์„ค์น˜ 101

1๏ธโƒฃ ๋‹ค์šด๋กœ๋“œ ๋ฐ›์€ ํ…Œ๋ผํผ ํŒŒ์ผ์˜ ์••์ถ•์„ ํ‘ผ ํ›„, C://terraform ํด๋”๋ฅผ ๋งŒ๋“ค๊ณ  terraform.exe๋ฅผ ์˜ฎ๊น๋‹ˆ๋‹ค.

2๏ธโƒฃ ์œˆ๋„์šฐ ๊ฒ€์ƒ‰์ฐฝ์— ์‹œ์Šคํ…œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ํŽธ์ง‘์„ ๊ฒ€์ƒ‰ํ•˜๊ณ  ๋‚˜์˜จ ์ฐฝ์—์„œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

3๏ธโƒฃ ์‹œ์Šคํ…œ ๋ณ€์ˆ˜ ์—์„œ Path๋ฅผ ๋ˆ„๋ฅธ ํ›„ ํŽธ์ง‘์„ ๋ˆŒ๋Ÿฌ์ค๋‹ˆ๋‹ค.

4๏ธโƒฃ ์ƒˆ๋กœ ๋งŒ๋“ค๊ธฐ๋ฅผ ๋ˆ„๋ฅด๊ณ  C:\terraform์„ ์ž…๋ ฅํ•œ ๋’ค ํ™•์ธ์„ ๋ˆŒ๋Ÿฌ์ค๋‹ˆ๋‹ค.

5๏ธโƒฃterraform -version์„ ์ถœ๋ ฅํ•ด์„œ ๋ฒ„์ „์ด ์ž˜ ๋‚˜์˜ค๋ฉด ์„ค์น˜๊ฐ€ ์ž˜ ๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค!




IaC ์‹ค์Šต

Terraform์„ ์ด์šฉํ•ด Docker ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ฝ”๋“œ๋กœ ์„ ์–ธํ•˜๊ณ  ์ž๋™ํ™”ํ•˜๋Š” ์‹ค์Šต์„ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

1๏ธโƒฃ ๊ธฐ๋ณธ Docker ์ปจํ…Œ์ด๋„ˆ ์ •์˜

  • main.tf : Terraform์„ ์ด์šฉํ•ด nginx ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ตฌ์„ฑ์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
terraform {
  required_providers {
    docker = {
      source  = "kreuzwerker/docker"
      version = "~> 3.0.1"
    }
  }
}

provider "docker" {}

resource "docker_image" "nginx" {
  name         = "nginx"
  keep_locally = false
}

resource "docker_container" "nginx" {
  image = docker_image.nginx.image_id
  name  = "sample"

  ports {
    internal = 80
    external = 8000
  }
}

2๏ธโƒฃ Terraform ์‹คํ–‰

  • terraform init : ํ…Œ๋ผํผ ํ”„๋กœ์ ํŠธ๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.

  • terraform validate : ๋ฌธ๋ฒ• ์˜ค๋ฅ˜๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

  • terraform fmt : ์ฝ”๋“œ ํฌ๋งท์„ ์ž๋™ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

  • terraform apply : ์‹ค์ œ ์ธํ”„๋ผ๋ฅผ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

    • ์ง์ ‘ yes๋ฅผ ์ž…๋ ฅํ•ด์•ผ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

์‹คํ–‰์ด ์™„๋ฃŒ๋˜๋ฉด, docker ps ๋ฅผ ํ†ตํ•ด ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ’ก ์ด ๊ณผ์ • ์ดํ›„ Terraform์€ ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ terraform.tfstate์— ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.

ํŒŒ์ผ์€ ์•ˆ์ „ํ•œ ๊ณณ์— ๋ณด๊ด€ํ•ด์•ผํ•˜๋ฉฐ ์‚ญ์ œ๋˜๋ฉด ๋ฆฌ์†Œ์Šค๋ฅผ ์ถ”์ ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.


3๏ธโƒฃ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„์„ ๋ณ€์ˆ˜๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

์ฝ”๋“œ๋ฅผ ๋” ์œ ์—ฐํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด, ์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„์„ ๊ฐ’ ๋Œ€์‹  ๋ณ€์ˆ˜๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

  • variable.tf

    variable "container_name" {
    	description = "Value of the name for the Docker container"
    	type        = string
    	default     = "ExampleNginxContainer"
    }
  • terraform.tf

    • name์„ "sample"์—์„œ var.container_name๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.
       terraform {
         required_providers {
           docker = {
             source  = "kreuzwerker/docker"
             version = "~> 3.0.1"
           }
         }
       }
       
       provider "docker" {}
       
       resource "docker_image" "nginx" {
         name         = "nginx"
         keep_locally = false
       }
       
       resource "docker_container" "nginx" {
         image = docker_image.nginx.image_id
         name  = var.container_name
       
         ports {
           internal = 80
           external = 8000
         }
       }

4๏ธโƒฃ Terraform ์‹คํ–‰

terraform apply -auto-approve : ์ค‘๊ฐ„ ํ™•์ธ ์—†์ด ์ž๋™์œผ๋กœ ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.


5๏ธโƒฃ ์ถœ๋ ฅ ๊ฐ’ ์ง€์ •

Terraform์—์„œ๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑํ•œ ๋’ค ํ•„์š”ํ•œ ๊ฐ’์„ ์ž๋™์œผ๋กœ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • output.tf
    output "container_id" {
      description = "ID of the Docker container"
      value       = docker_container.nginx.id
    }
    
    output "image_id" {
      description = "ID of the Docker image"
      value       = docker_image.nginx.id
    }

terraform apply --auto-approve ๋ฅผ ํ†ตํ•ด ์ ์šฉ์ด ์™„๋ฃŒ๋˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ •๋ณด๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.

Outputs:

container_id = "6c9a3e..."
image_id     = "sha256:..."

6๏ธโƒฃ ๋ฆฌ์†Œ์Šค ์ œ๊ฑฐ

  • terraform destroy --auto-approve : ์ƒ์„ฑ๋œ ์ปจํ…Œ์ด๋„ˆ์™€ ์ด๋ฏธ์ง€๋ฅผ ๋ชจ๋‘ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.



โœ๏ธ ํšŒ๊ณ 

์ธํ”„๋ผ๊นŒ์ง€ ์ฝ”๋“œ๋กœ ์ž๋™ํ™”ํ•˜๋‹ˆ ํ›จ์”ฌ ํŽธํ•˜๊ณ  ์ข‹์€ ๊ฒƒ ๊ฐ™๋‹ค.

profile
๐ŸŒฑ๊ฐœ๋ฐœ ๊ธฐ๋ก์žฅ

0๊ฐœ์˜ ๋Œ“๊ธ€