Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

JINIers

220831_Infrastructure as Code with Terraform 본문

GCP/Qwiklabs

220831_Infrastructure as Code with Terraform

JINIers 2022. 8. 31. 16:36

Terraform을 사용한 코드형 인프라

+ 수정 : 220901: 부가설명 추가

 


[개요]

terraform
- 코드로서의 인프라
- 안전하고 반복 가능한 방식
- 인프라 구축, 변경, 관리하기 위한 도구
- HCL(HashiCorp Configuration Language) 이라는 구성언어로 환경을 관리할 수 있음

사용자 인터페이스에서 리소스를 수동으로 구성하는 대신 파일에서 인프라를 관리하는 프로세스
운영자가 HCL를 사용하여 원하는 리소스의 정의가 포함된 파일을 작성할 수 있음

 


[워크플로]

- 범위 : 주어진 프로젝트에 대해 생성해야하는 리소스 확인
- 작성자 : 범위 매게변수를 기반으로 HCL에서 구성파일 생성
- 초기화 : terraform init
ㄴ 구성파일이 있는 프로젝트 디렉토리에서 실행
프로젝트에 대한 올바른 공급자 플러그인이 다운됨
- 계획 및 적용
ㄴ terraform plan : 생성 프로세스 확인
ㄴ terraform apply : 실제 리소스와 구성파일의 향후 변경사항을 배포환경에 실제로 존재하는 것과 비교하는 상태파일 생성 ???????
뭔말이야 이게..


상태파일 생성
ㄴ 실제 리소스 + 구성파일의 변경사항 


[학습내용]

1. terraform으로 인프라 구축, 변경, 파괴
2. terraform으로 리소스 종속성 생성
3. terraform으로 인프라 프로비저닝

 


작업 1. 인프라 구축

[파일생성]

touch main.tf


[내용추가]

terraform {
  required_providers {
    google = {
      source = "hashicorp/google"
    }
  }
}
provider "google" {
  version = "3.5.0"
  project = "<PROJECT_ID>"
  region  = "us-central1"
  zone    = "us-central1-c"
}
resource "google_compute_network" "vpc_network" {
  name = "terraform-network"
}

 

- provider: 리소스 생성 및 관리 담당

terraform 구성이 다른 공급자의 리소스를 관리하는 경우 여러 공급자 블록이 존재할 수 있음

 


[초기화]

terraform init

- 후속명령에서 사용할 다양한 로컬 설정과 데이터초기화

 

[리소스 생성]

terraform apply

 

[현재상태 검사]

terraform show

작업 2. 인프라 변경

terraform 구성을 변경하면 terraform은 원하는 상태에 도달하는데 필요한 것들만 수정하는 실행계획을 구축함

ㄴ 뭔말이야

terraform을 사용하여 인프라를 변경하면 구성뿐 아니라 상태도 버전 제어할 수 있으므로 시간이 지남에 따라 인프라가 어떻게 발전하는지 확인할 수 있ㅇㅁ


[리소스 추가]

resource "google_compute_instance" "vm_instance" {
  name         = "terraform-instance"
  machine_type = "f1-micro"
  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-11"
    }
  }
  network_interface {
    network = google_compute_network.vpc_network.name
    access_config {
    }
  }
}

 

[결과]

terraform {
  required_providers {
    google = {
      source = "hashicorp/google"
    }
  }
}
provider "google" {
  version = "3.5.0"
  project = "<PROJECT_ID>"
  region  = "us-central1"
  zone    = "us-central1-c"
}
resource "google_compute_network" "vpc_network" {
  name = "terraform-network"
}

resource "google_compute_instance" "vm_instance" {
  name         = "terraform-instance"
  machine_type = "f1-micro"
  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-11"
    }
  }
  network_interface {
    network = google_compute_network.vpc_network.name
    access_config {
    }
  }
}

 

 

[적용]

terraform apply
yes

 


[리소스 변경2: vm_instance tags 추가]

terraform {
  required_providers {
    google = {
      source = "hashicorp/google"
    }
  }
}
provider "google" {
  version = "3.5.0"
  project = "<PROJECT_ID>"
  region  = "us-central1"
  zone    = "us-central1-c"
}
resource "google_compute_network" "vpc_network" {
  name = "terraform-network"
}

resource "google_compute_instance" "vm_instance" {
  name         = "terraform-instance"
  machine_type = "f1-micro"
  tags         = ["web", "dev"]

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-11"
    }
  }
  network_interface {
    network = google_compute_network.vpc_network.name
    access_config {
    }
  }
}

 

 

[적용]

terraform apply
yes


[리소스 변경3: boot_disk 변경]

terraform {
  required_providers {
    google = {
      source = "hashicorp/google"
    }
  }
}
provider "google" {
  version = "3.5.0"
  project = "<PROJECT_ID>"
  region  = "us-central1"
  zone    = "us-central1-c"
}
resource "google_compute_network" "vpc_network" {
  name = "terraform-network"
}

resource "google_compute_instance" "vm_instance" {
  name         = "terraform-instance"
  machine_type = "f1-micro"
  tags         = ["web", "dev"]
  boot_disk {
    initialize_params {
      image = "cos-cloud/cos-stable"
    }
  }
  network_interface {
    network = google_compute_network.vpc_network.name
    access_config {
    }
  }
}

인스턴스의 디스크 이미지를 변경하는 것은 인프라를 파괴 후 변경하는 것의 예시 중 하나

- 파괴적인 변경 : 공급자가 기존 리소스를 업데이트하는 대신 교체해야하는 변경

   * 일반적으로 클라우드 공급자가 구성에 설명된 방식으로 리소스 업데이트를 지원하지 않기 때문에 발생

 

 

[적용]

terraform apply
yes

-/+ : terraform이 리소스를 제자리에서 업데이트하지 않고 파괴 후 다시 생성함

+ : 리소스 생성(아래에는 설정할 속성이 같이 표시됨)

      * known afrer apply : 리소스가 생성될 때까지 값을 알 수 없음

- : 인스턴스와 네트워크가 파괴됨

~ : terraform이 리소스를 제자리에서 업데이트함

 

[인프라 파괴]

terraform destroy

인프라 파괴는 드문 경우지만 terraform을 사용하여 개발, 테스트, 스테이징 과 같은 여러 환경을 가동하는 경우 파괴가 유용한 작업인 경우가 많다.


작업 3. 리소스 종속성 생성

실제 인프라에는 다양한 리소스 및 리소스 유형이 있음

terraform 구성에는 여러 리소스, 여러 리소스 유형이 포함될 수 있으며 이러한 유형은 여러 공급자에 걸쳐 있을 수도 있음

 

 

[리소스 재생성]

terraform apply


[고정 IP 주소 할당]

terraform {
  required_providers {
    google = {
      source = "hashicorp/google"
    }
  }
}
provider "google" {
  version = "3.5.0"
  project = "<PROJECT_ID>"
  region  = "us-central1"
  zone    = "us-central1-c"
}
resource "google_compute_network" "vpc_network" {
  name = "terraform-network"
}

resource "google_compute_instance" "vm_instance" {
  name         = "terraform-instance"
  machine_type = "f1-micro"
  tags         = ["web", "dev"]

  boot_disk {
    initialize_params {
      image = "cos-cloud/cos-stable"
    }
  }
  network_interface {
    network = google_compute_network.vpc_network.name
    access_config {
    }
  }
}

resource "google_compute_address" "vm_static_ip" {
  name = "terraform-static-ip"
}


[생성 내용 확인]

terraform plan

terraform apply와 달리 plan은 변경될 내용만 표시하고 실제 변경사항을 직접 적용하진 않음

 

 

[리소스 수정4: network_interface 수정]

terraform {
  required_providers {
    google = {
      source = "hashicorp/google"
    }
  }
}
provider "google" {
  version = "3.5.0"
  project = "<PROJECT_ID>"
  region  = "us-central1"
  zone    = "us-central1-c"
}
resource "google_compute_network" "vpc_network" {
  name = "terraform-network"
}

resource "google_compute_address" "vm_static_ip" {
  name = "terraform-static-ip"
}

resource "google_compute_instance" "vm_instance" {
  name         = "terraform-instance"
  machine_type = "f1-micro"
  tags         = ["web", "dev"]
  boot_disk {
    initialize_params {
      image = "cos-cloud/cos-stable"
    }
  }
  network_interface {
    network = google_compute_network.vpc_network.name
    access_config {
     nat_ip = google_compute_address.vm_static_ip.address
    }
  }
}

 

[계획 저장]

terraform plan -out static_ip

계획 실행 + 저장

plan에서 생성한 파일을 적용하려고 하면 terraform은 먼저 계획을 적용하기 전에 동일한 변경사항이 적용되는지 확인함

 


[변경사항 적용]

terraform apply "static_ip"

 

 

[암시적 및 명시적 종속성: depends_on]

terraform {
  required_providers {
    google = {
      source = "hashicorp/google"
    }
  }
}
provider "google" {
  version = "3.5.0"
  project = "<PROJECT_ID>"
  region  = "us-central1"
  zone    = "us-central1-c"
}
resource "google_compute_network" "vpc_network" {
  name = "terraform-network"
}

resource "google_compute_address" "vm_static_ip" {
  name = "terraform-static-ip"
}

resource "google_compute_instance" "vm_instance" {
  name         = "terraform-instance"
  machine_type = "f1-micro"
  tags         = ["web", "dev"]
  boot_disk {
    initialize_params {
      image = "cos-cloud/cos-stable"
    }
  }
  network_interface {
    network = google_compute_network.vpc_network.name
    access_config {
     nat_ip = google_compute_address.vm_static_ip.address
    }
  }
}


# New resource for the storage bucket our application will use.
resource "google_storage_bucket" "example_bucket" {
  name     = "<UNIQUE-BUCKET-NAME>"
  location = "US"
  website {
    main_page_suffix = "index.html"
    not_found_page   = "404.html"
  }
}
# Create a new instance that uses the bucket
resource "google_compute_instance" "another_instance" {
  # Tells Terraform that this VM instance must be created only after the
  # storage bucket has been created.
  depends_on = [google_storage_bucket.example_bucket]

  name         = "terraform-instance-2"
  machine_type = "f1-micro"
  boot_disk {
    initialize_params {
      image = "cos-cloud/cos-stable"
    }
  }
  network_interface {
    network = google_compute_network.vpc_network.self_link
    access_config {
    }
  }
}

terraform은 한 리소스가 다른 리소스에 종속될 때 자동으로 추론 가능

terraform은 이 종속성 정보를 사용하여 다른 리소스를 생성하고 업데이트할 올바른 순서를 결정

 

 

 

[변경사항 확인 및 적용]

terraform plan
terraform apply
yes

작업 4. 인프라 제공


[제공자 정의: provisioner]

terraform {
  required_providers {
    google = {
      source = "hashicorp/google"
    }
  }
}
provider "google" {
  version = "3.5.0"
  project = "<PROJECT_ID>"
  region  = "us-central1"
  zone    = "us-central1-c"
}
resource "google_compute_network" "vpc_network" {
  name = "terraform-network"
}

resource "google_compute_address" "vm_static_ip" {
  name = "terraform-static-ip"
}

resource "google_compute_instance" "vm_instance" {
  name         = "terraform-instance"
  machine_type = "f1-micro"
  tags         = ["web", "dev"]
  provisioner "local-exec" {
    command = "echo ${google_compute_instance.vm_instance.name}:  ${google_compute_instance.vm_instance.network_interface[0].access_config[0].nat_ip} >> ip_address.txt"
  }


  boot_disk {
    initialize_params {
      image = "cos-cloud/cos-stable"
    }
  }
  network_interface {
    network = google_compute_network.vpc_network.name
    access_config {
     nat_ip = google_compute_address.vm_static_ip.address
    }
  }
}


# New resource for the storage bucket our application will use.
resource "google_storage_bucket" "example_bucket" {
  name     = "<UNIQUE-BUCKET-NAME>"
  location = "US"
  website {
    main_page_suffix = "index.html"
    not_found_page   = "404.html"
  }
}
# Create a new instance that uses the bucket
resource "google_compute_instance" "another_instance" {
  # Tells Terraform that this VM instance must be created only after the
  # storage bucket has been created.
  depends_on = [google_storage_bucket.example_bucket]

  name         = "terraform-instance-2"
  machine_type = "f1-micro"
  boot_disk {
    initialize_params {
      image = "cos-cloud/cos-stable"
    }
  }
  network_interface {
    network = google_compute_network.vpc_network.self_link
    access_config {
    }
  }
}

local-exec : terraform을 실행하는 시스템에서 로컬로 명령 실행

 


[적용]

terraform apply
yes

 

[재생성]

terraform taint google_compute_instance.vm_instance

* 오염된 자원은 파괴하고 재생성한다.

 

[적용]

terraform apply
yes

끗.

 

하 이거 너무 어려워 시간이 너무 부족해여 하ㅡㄱ흑흑하ㅓ흑

시간 한시간 아니고 한 90분쯤 줬으면 조켔어 ㅜㅜㅠㅜㅠㅜㅠㅜㅠㅠㅜㅠ

Comments