ํฌ์ŠคํŠธ ์ปค๋ฒ„ ์ด๋ฏธ์ง€

Terraform์€ ๊ฐ•๋ ฅํ•œ Infrastructure as Code(IaC) ๋„๊ตฌ๋กœ, ํด๋ผ์šฐ๋“œ ์„œ๋น„์Šค์˜ ์ƒ์„ฑ, ๊ด€๋ฆฌ, ์—…๋ฐ์ดํŠธ๋ฅผ ์ž๋™ํ™”ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

์ด๋Š” ์šฐ๋ฆฌ๊ฐ€ Public Cloud์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ธํ”„๋ผ๋ฅผ ์ฝ”๋“œ ๊ธฐ๋ฐ˜์œผ๋กœ ํšจ์œจ์ ์œผ๋กœ ์ƒ์„ฑ, ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋•์Šต๋‹ˆ๋‹ค.

"์ด๊ฑธ ์™œ ์‚ฌ์šฉํ•˜๋Š”๊ฐ€?" ์˜๋ฌธ์ด ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ €๋„ ๊ฐ€๋” Low Code, No Code๋ฅผ ์™ธ์น˜๋Š” ์‹œ๋Œ€์—์„œ IaC๋Š” ๋ชจ์ˆœ์ด์ง€ ์•Š์€๊ฐ€ ์ƒ๊ฐํ•˜์ง€๋งŒ, ๊ฒฐ๊ตญ์—๋Š” ์ธํ”„๋ผ ๊ด€๋ฆฌ์˜ ํŽธ์˜์„ฑ์„ ์œ„ํ•ด Terraform์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Terraform์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๊ฐ€ ๋งŽ๊ฒ ์ง€๋งŒ, ๋ฌด์—‡๋ณด๋‹ค ์ œ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ€์žฅ ํฐ ์ด์œ ๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ๊ฐ„๋‹จํ•˜๋‹ค๋Š” ์  ์ž…๋‹ˆ๋‹ค.

๋ณดํ†ต ๊ฐœ์ธ Public Cloud๊ณ„์ •์„ ์ด์šฉํ•ด์„œ ํ…Œ์ŠคํŠธ ๋ฐ ๊ณต๋ถ€๋ฅผ ํ•˜๊ณ ๋Š” ํ•˜๋Š”๋ฐ, ์‚ฌ์šฉํ•˜๊ณ  ๋‚˜์„œ ๋‚˜์˜ ์ž‘๊ณ  ์†Œ์ค‘ํ•œ ๋ˆ์„ ์•„๋ผ๊ธฐ ์œ„ํ•ด์„œ ์ƒ์„ฑํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.

์ด ๊ณผ์ •์—์„œ ๋†“์น˜๋Š” ๋ฆฌ์†Œ์Šค๋„ ์žˆ๊ณ , ํ•ญ์ƒ ์‚ฌ์šฉ ์ค‘์ธ ๋ฆฌ์†Œ์Šค๊ฐ€ ์žˆ๋Š”์ง€ Billing์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๐Ÿฅฒ

์ด๋Ÿด ๋•Œ, Terraform์€ ์—„์ฒญ๋‚˜๊ฒŒ ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

Terraform์œผ๋กœ ์ƒ์„ฑ๋œ ๋ฆฌ์†Œ์Šค๋Š” terraform destroy ๋ช…๋ น์–ด ํ•œ๋ฐฉ์œผ๋กœ ์ „๋ถ€ ์‚ญ์ œ ํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ ํŽธํ•˜์ง€ ์•Š์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์„œ๋ก ์ด ๊ธธ์—ˆ๋„ค์š”. ์ด์ œ๋ถ€ํ„ฐ ๋‚˜์˜ค๋Š” ๋‚ด์šฉ์€, ์ œ๊ฐ€ ๋Œ€ํ‘œ์ ์œผ๋กœ Terraform์„ ์‚ฌ์šฉํ•ด์„œ ์ƒ์„ฑ, ์‚ญ์ œ๋ฅผ ๋ฐ˜๋ณตํ•˜๋Š” GKE์ž…๋‹ˆ๋‹ค.

์ด๋ฅผ ๋ณด๊ณ , ํ•œ๋ถ„์ด๋ผ๋„ GKE๋ฅผ ์‰ฝ๊ฒŒ ์ƒ์„ฑ, ์‚ญ์ œํ•˜์˜€์œผ๋ฉด ์ข‹๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์–ด ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.

gcloud auth

Terraform์„ ์ด์šฉํ•ด์„œ GCP ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑ, ์‚ญ์ œ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” GCP์—์„œ ์ œ๊ณตํ•˜๋Š” ์ธ์ฆ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด ์ค‘ ์ €๋Š” gcloud๋ฅผ ์ด์šฉํ•ด์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

gcloud๋Š”, GCP์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ด€๋ฆฌํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ๋กœ, ํ„ฐ๋ฏธ๋„์—์„œ GCP์˜ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์„ค์น˜๋ฒ•์€ GCP docs์— ์นœ์ ˆํ•˜๊ฒŒ ๋‚˜์™€์žˆ์œผ๋‹ˆ ์ฐธ๊ณ ํ•˜์„ธ์š”~

๊ทธ ์ค‘์—์„œ๋„ gcloud auth๋ฅผ ์‚ฌ์šฉํ•  ๊ฑด๋ฐ, ์‚ฌ์šฉ๋ฒ•์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.

shellgcloud auth login --brief

์œ„์˜ ๋ช…๋ น์–ด๋ฅผ Terminal์— ์ž…๋ ฅํ•˜๋ฉด, google ๋กœ๊ทธ์ธ์„ ํ†ตํ•ด์„œ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ธ์ฆ์ด ์™„๋ฃŒ๋ฉ๋‹ˆ๋‹ค.

shellgcloud auth list

์ •์ƒ์ ์œผ๋กœ ๋“ฑ๋ก๋˜์—ˆ๋Š”์ง€ ํ™•์ธ์„ ์œ„ํ•ด์„œ๋Š” list ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

shellgcloud auth revoke test@gmail.com

๋งŒ์•ฝ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ๊ณ„์ •์ด ๋งŽ๊ฑฐ๋‚˜, ๋‹ค๋ฅธ ์ด์œ ๋กœ ์ธ์ฆ์—์„œ ์ œ๊ฑฐํ•˜๊ณ  ์‹ถ์œผ๋ฉด revoke๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.

(์ € ๊ฐ™์€ ๊ฒฝ์šฐ, ํšŒ์‚ฌ๊ณ„์ •๊ณผ ๋ถ„๋ฆฌํ•˜๊ณ  ์‹ถ์–ด์„œ ๊ฐ€๋” ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿด๋ฆฌ๋Š” ์—†๊ฒ ์ง€๋งŒ, ํšŒ์‚ฌ๊ณ„์ •์„ ์ด์šฉํ•ด์„œ ํšŒ์‚ฌ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜๋„ ์žˆ์œผ๋‹ˆ...)

shellgcloud auth application-default login

๋งˆ์ง€๋ง‰์œผ๋กœ ์œ„์˜ ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜๋ฉด, Terraform๊ฐ™์€ application ๋“ฑ์—์„œ google auth์— ๋“ฑ๋ก๋œ ๋‚ด์šฉ์„ default๋กœ ์‚ฌ์šฉํ•˜๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

์œ„์˜ ๋‚ด์šฉ๋Œ€๋กœ gcloud auth๋ฅผ ๋“ฑ๋กํ•˜๋ฉด Terraform์„ ์ด์šฉํ•ด์„œ GCP์— ์ ‘๊ทผํ•  ์ค€๋น„๊ฐ€ ์™„๋ฃŒ ๋ฉ๋‹ˆ๋‹ค.

Terraform ์„ค์น˜ํ•˜๊ธฐ

Terraform ์„ค์น˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.

์ €๊ฐ™์€ ๊ฒฝ์šฐ, Mac ์œ ์ €๋กœ brew๋ฅผ ํ†ตํ•ด์„œ ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

shellbrew tap hashicorp/tap
brew install hashicorp/tap/terraform

Mac ์™ธ์— ํ™˜๊ฒฝ์—์„œ Terraform์„ ์„ค์น˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ Terraform Docs: Install Terraform์„ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

shell$ terraform --version
Terraform v1.4.6
on darwin_arm64

์ •์ƒ์ ์œผ๋กœ ์„ค์น˜๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด์„œ ์œ„์™€ ๊ฐ™์ด ํ…Œ์ŠคํŠธ ํ•ด๋ณด์„ธ์š”.

GKE ์ƒ์„ฑํ•˜๊ธฐ

GKE or Terraform์„ ์กฐ๊ธˆ ๋งŒ์ ธ๋ณด์‹  ๋ถ„๋“ค์€, ์„ค์ •ํ•  ๋‚ด์šฉ์ด ๋งŽ๋‹ค๋Š” ๊ฒƒ์„ ๋Š๋‚„ ๊ฒƒ ์ž…๋‹ˆ๋‹ค.

GKE๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด VPC, Subnet ๋“ฑ์„ ์ถ”๊ฐ€๋กœ ์ƒ์„ฑํ•˜๊ณ  ์ด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ด์— ๋Œ€ํ•œ ๊ณผ์ •์„ BESPIN GLOBAL: Terraform ์„ ์‚ฌ์šฉํ•˜์—ฌ GKE ์ƒ์„ฑํ•˜๊ธฐ ์—์„œ ์ž˜ ์„ค๋ช…ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ €๋Š” ์กฐ๊ธˆ ๋‹ค๋ฅด๊ฒŒ module ๋ฐฉ๋ฒ•์„ ์ด์šฉํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

module์„ ์ง์ ‘ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์€ ํž˜๋“ค์ง€๋งŒ, ์ด๋ฏธ ์ƒ์„ฑ๋˜์–ด ์žˆ๋Š” module์„ ๊ฐ€์ ธ๋‹ค ์“ฐ๋Š”๊ฑด ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.

๋‹คํ–‰ํžˆ๋„, ์ด๋Ÿฌํ•œ ๋ชจ๋“ˆ์„ Google Cloud and HashiCorp์—์„œ ์ œ๊ณตํ•ด์ฃผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๊ดœํžˆ ํž˜๋“ค๊ฒŒ ์‚ด์ง€ ๋ง๊ณ , ๊ฑฐ์ธ์— ์–ด๊นจ์— ์˜ฌ๋ผํƒ€์ž...

Github Repo๋ฅผ Clone ๋ฐ›์•„์„œ ํ•„์š”ํ•œ module์„ ๊ฐ€์ ธ์˜ค๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์ €๋Š” modules ์ค‘ private-cluster๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ณธ์ธ์˜ ํ•„์š”์— ๋”ฐ๋ผ modules๋ฅผ ์„ ํƒํ•˜์…”๋„ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

ํ•ด๋‹น ํŒŒ์ผ์„ ๊ฐœ์ธ์˜ ์„ ํ˜ธ์— ๋”ฐ๋ผ ์ƒˆ๋กœ์šด ํด๋”์— ๊ตฌ์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค.

shell$ tree
.
โ”œโ”€โ”€ gke
โ”‚ย ย  โ”œโ”€โ”€ gke.tf
โ”‚ย ย  โ””โ”€โ”€ variables.tf
โ””โ”€โ”€ module
    โ””โ”€โ”€ google-kubernetes-engine
        โ”œโ”€โ”€ README.md
        โ”œโ”€โ”€ cluster.tf
        โ”œโ”€โ”€ dns.tf
        โ”œโ”€โ”€ firewall.tf
        โ”œโ”€โ”€ main.tf
        โ”œโ”€โ”€ masq.tf
        โ”œโ”€โ”€ networks.tf
        โ”œโ”€โ”€ outputs.tf
        โ”œโ”€โ”€ sa.tf
        โ”œโ”€โ”€ scripts
        โ”‚ย ย  โ””โ”€โ”€ delete-default-resource.sh
        โ”œโ”€โ”€ variables.tf
        โ”œโ”€โ”€ variables_defaults.tf
        โ””โ”€โ”€ versions.tf

gke ๋ผ๋Š” ํด๋”์™€ module ํด๋”๋กœ ๋ถ„๋ฆฌํ•˜์˜€์œผ๋ฉฐ, module ํด๋”์•ˆ์—, google-kubernetes-engine์ด๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์ด์ „์— ๋‹ค์šด ๋ฐ›์€ private-cluster๋ฅผ ๋„ฃ์—ˆ์Šต๋‹ˆ๋‹ค.

์ดํ›„, module์€ ๊ฑด๋“ค์ง€ ์•Š๊ณ , gke ํด๋”์—์„œ ์ž‘์—…ํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ gke.tf์™€, variables.tf๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

json# gke.tf
module "cluster" {
  source = "../module/google-kubernetes-engine"

  ip_range_pods     = ""
  ip_range_services = ""
  name              = "<์ƒ์„ฑํ•  cluster-name์„ ์ž…๋ ฅํ•˜์„ธ์š”>"
  network           = ""
  project_id        = "<project-id๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”>"
  subnetwork        = ""
  region            = "asia-northeast3"
  zones             = ["asia-northeast3-a"]
  regional          = false
  node_pools = [
    {
      name         = "pool-1"
      machine_type = "e2-standard-2"
      autoscaling  = false
      node_count   = 2
      disk_size_gb = 10
      disk_type    = "pd-balanced"
      auto_upgrade = true
    },
  ]
}
json# variables.tf
provider "google" {
  project = "<project-id๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”>"
  region  = "asia-northeast3"
}

terraform {
  backend "gcs" {
    bucket = "terraform์ •๋ณด๋ฅผ ๋‹ด์„ bucket์ด๋ฆ„"
    prefix = "terraform-gke"
  }
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = ">= 4.51.0, < 4.65.0"
    }
  }
}

์œ„์˜ ๋‚ด์šฉ์€ ์ œ๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋‚ด์šฉ์ด์ง€, Terraform์—์„œ GKE๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ํ•„์ˆ˜ ์กฐ๊ฑด์ด ์•„๋‹™๋‹ˆ๋‹ค.

์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€ ๋‚ด์šฉ์œผ๋กœ ์ˆ˜์ •ํ•˜์…”์„œ ์‚ฌ์šฉํ•˜์…”๋„ ๋ฉ๋‹ˆ๋‹ค.

ํŠนํžˆ, variables.tf์— backend๋ถ€๋ถ„์€ gcs๊ฐ€ ์•„๋‹Œ local๋กœ ์‚ฌ์šฉํ•˜์…”๋„ ์ข‹์Šต๋‹ˆ๋‹ค.

Terraform์„ ์ด์šฉํ•ด์„œ ๋ฆฌ์†Œ์Šค ์ƒ์„ฑํ•˜๊ธฐ

๋จผ์ € ๋ชจ๋“  ๋ช…๋ น์–ด๋Š” ์ด์ „์— ์ƒ์„ฑํ•œ gke ํด๋”์—์„œ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค.

์ด์ œ ์ƒ์„ฑ๋งŒ ํ•˜๋ฉด ์™„๋ฃŒ๋ฉ๋‹ˆ๋‹ค.

shellterraform init

์œ„์˜ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด์„œ, terraform์„ ์ดˆ๊ธฐํ™” ํ•ด์ค๋‹ˆ๋‹ค. init ๋ช…๋ น์–ด์˜ ๊ฒฝ์šฐ ๋ฉฑ๋“ฑ์„ฑ์„ ๋ณด์žฅํ•˜์—ฌ ์—ฌ๋Ÿฌ๋จผ ์ž…๋ ฅํ•ด๋„ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

shellterraform plan

๋‹ค์Œ์€ plan ๋ช…๋ น์–ด์ž…๋‹ˆ๋‹ค. Terraform์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด, ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๋ช…๋ น์–ด์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ •์˜ํ•œ tf ํŒŒ์ผ๋“ค๋กœ ์ƒ์„ฑ, ๋ณ€๊ฒฝ, ์‚ญ์ œ๋˜๋Š” ๋ฆฌ์†Œ์Šค๋“ค์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

shellterraform apply

๋งˆ์ง€๋ง‰์œผ๋กœ ์‹ค์ œ GCP์— ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค.

์ƒ์„ฑ, ๋ณ€๊ฒฝ, ์‚ญ์ œ๋˜๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ํ™•์ธํ•˜๊ณ  yes๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ์ž‘์—…์ด ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค.

๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ์‹ค์ œ GCP์—์„œ ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑ ์ค‘์ž„์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

shellApply complete! Resources: 9 added, 0 changed, 0 destroyed.

์œ„์™€ ๊ฐ™์ด terminal์—์„œ terraform ๋ฉ”์‹œ์ง€๊ฐ€ ๋ณด์ด๋ฉด ์ž‘์—…์ด ์™„๋ฃŒ๋œ ์ƒํƒœ์ž…๋‹ˆ๋‹ค.

์ด์ œ ์›ํ•˜๋Š” ๋Œ€๋กœ ์ˆ˜์ •ํ•ด์„œ Terraform์„ ์‚ฌ์šฉํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

shellterraform destroy

๋งˆ์ง€๋ง‰์œผ๋กœ ์ž‘๊ณ  ์†Œ์ค‘ํ•œ ๋ˆ์„ ์•„๋ผ๊ณ ์ž... ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์‚ญ์ œํ•ด์ฃผ์„ธ์š”.