본문 바로가기
기술 단어장/IaC

[Terraform] 공식문서로 파해쳐본Terraform GCP 배포

by MFDO 2025. 3. 26.

 

 

 

 

본 문서는 아래 링크에서 제공하는

학습지에서 가장 높은 가독성을 보입니다.

혹은 게시글 최하단에 있는 pdf 내용에서

동일 내용을 확인할 수 있습니다.

 

 

Terraform_GCP.pdf

 

drive.google.com

 

블로그로 옮겨 쓰는게 제일 복잡하다...

 

 

 


 

 

 

 

 

2025.03.25 ()

오늘의 다짐/목표

매번 아 저거 잘 모르는데 하면서 주눅들지 말고 하고 자신감을 가지자!
 - Terraform 환경 구성
 - GCP 배포

 

 * 나만의 도전과제 : 지독하게 공식 문서만 읽고 구현하기 (국내 자료 금지)

 

 

 

 

 


 

Terraform CLI

 : 노리진 않았는데 마침 내가 원하는 친구들이 딱 예제로 주어졌다

 

- 7개의 튜토리얼이 제공된다

 - 3-10분 정도 길이였기에 처음 도전할 GCP는 차근차근 모두 보고자 했다.

 

 * https://developer.hashicorp.com/terraform/cli/commands

 

 

현재부터 공식 튜토리얼을 따름
https://developer.hashicorp.com/terraform/tutorials/gcp-get-started

 

 

(1) What is Infrastructure as Code with Terraform?

 - Terraform

  > HashiCorp가 만든 IaC 도구

  > 선언형(declarative) 구성 파일로 리소스와 인프라를 정의하여 관리

 

 - Terraform 사용의 이점

  > 여러 클라우드 플랫폼에서 인프라를 관리

  > 빠르게 인프라 코드를 작성할 수 있음

  > 상태(State)를 통해 배포할 때마다 리소스 변경 이력을 추적 가능

  > 구성 파일을 SVM에 포함하여 안전하게 협업 가능

 

 - Provider

  > Terraform 플러그인

  > 클라우드 플랫폼 혹은 기타 API를 통해 인프라와 상호 작용하게 함

  > 1,000개 이상의 프로바이더를 지원 (AWS, GitHub, DataDog ...)

  > 원하는건 Terraform Registry에서 찾을 수 있고 없으면 만들 수 있음

 

- 배포 워크플로우 표준화

  > Resource: 프로바이더가 정의하는 인스턴스, 네트워크 같은 인프라 단위   

  > Module: 서로 다른 프로바이더에서 제공되는 리소스를 조합

 

- 배포 워크플로우

1 Scope 프로젝트에 필요한 인프라를 식별
2 Author 인프라의 구성 작성
3 Initialize 인프라 관리에 필요한 플러그인 설치
4 Plan 변경사항이 설정과 일치한지 확인
5 Apply 변경사항을 실제로 적용

 

 - 인프라 상태 관리하기

  > 실제 인프라의 상태를 State File로 관리

  > State File로 실제 인프라가 설정과 일치하기 위한 변경 사항을 식별

 

 - 협업 (HCP Terraform)

  > TerraformBackends를 통해 인프라 구성에 대해 협업가능

  > 최대 5명까지 무료

  > 팀원과 상태를 공유, Terraform이 안정적인 환경에서 실행되게 함

  > 여러 명이 동시에 변경할 때 발생하는 경쟁 상태를 방지

  > GitHub, GitLab에 연결하면 설정 변경 사항을 VCS에 커밋할 때,
   
인프라 변경사항을 자동으로 제안할 수 있음

 

 

 


 

 

 

(2) Install Terraform: Windows

: 가이드 준대로 chocolatey로 설치했다.

 

choco install terraform

 

 

 


 

 

(3) Build infrastructure: GCP

 - Prerequisites

  > The gcloud CLI installed locally.

  > Terraform 1.2.0+ installed locally.

업그레이드 시도했으나 윈도우 최신 버전이 1.11.2라서 그냥 해보고자 함

 

 

 

- Write configuration

 1) deploy-to-gcp.tf 생성

 2) configuration 작성

terraform {
  required_providers {
    google = {
      source = "hashicorp/google"
      version = "6.8.0"
    }
  }
}

provider "google" {
  project = "<PROJECT_ID>"
  region  = "us-central1"
  zone    = "us-central1-c"
}

resource "google_compute_network" "vpc_network" {
  name = "terraform-network"
}

  쓰는 김에 extension도 다운받음 : HashiCorp Terraform

 

 - https://developer.hashicorp.com/terraform/tutorials/gcp-get-started/google-cloud-platform-build

 - https://developer.hashicorp.com/terraform/language/providers/configuration

 

 

 

 

 - Authenticate to Google Cloud

 : 구글 클라우드 로그인 과정

gcloud auth application-default login

 

 

 

 

 - Initialize the directory

 : downloads the providers defined in the configuration

  > provider를 다운로드하여 `.terraform`에 설치 후 provider 버전 출력

  > `.terraform.lock.hcl`를 생성

terraform init

 

 

* .terraform.lock.hcl

 - 역할

  > 잠금: Provider의 정확한 버전을 잠금해서, 항상 똑같은 버전을 쓰게 함

  > 차이: required_providers에서는 허용 가능 버전 범위 지정

 

 - 검증

  > 내부에 내가 지정한 provider와 버전, 제약조건, 해시값이 존재한다

  > 동일 버전임에도 해시 값을 통한 결과가 다르다면 경고 메시지를 줌

  => 이렇게 충돌되면 버전 드리프트 혹은 버전 충돌이라고 부름

 

 - 없다면 생길 수 있는 문제

  1) 버전 드리프트(Version Drift)

  : 처음에 버전을 설정했는데 실수/자동으로 업그레이드되며 충돌

  2) 버전 충돌(Version Conflict)

  : 서로 다른 모듈이 다른 버전을 요청하면 실행 자체를 막고 경고를 띄움

 

 

 

 

 

 

- Format and validate the configuration

terraform fmt

 > 코드 인덴트, 줄바꿈 규칙 같은 형태를 terraform 공식으로 맞춰줌

> 변경된 파일이 존재한다면, 해당 파일의 이름을 반환한다.

 

terraform validate

> 잘 작성했는지 검증(문법, 리소스 참조, 필수 속성 누락, 타입/제약조건)

 

 

=> 코드 실행 전 terraform validate && terraform fmt 실행하면 깔끔!

 

 

 

 

 

- Format and validate the configuration

terraform apply

 > 설정 적용

 > + 표시된게 이번에 추가되는 리소스

 

 

 

 > 잉 나는 에러 났다.

Error: Error creating Network: googleapi: Error 403: Compute Engine API has not been used in project terraform-study-250325 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/compute.googleapis.com/overview?project=terraform-study-250325 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.

 > GCP를 처음 만든 프로젝트에서 리소스를 사용할 때,
  
보안을 위해 해당 API를 먼저 활성화 해야함.

 > Terraform으로 처음 시도했기 때문에, 아직 API가 활성화되지 않았음

 > 아래의 API 설정이 완료된 이후 정상적으로 적용됨을 확인 할 수 있다.

 

 

 

 

- Inspect state

terraform show

 > terraform.tfstate
  
: Terraform
이 관리하는 리소스(VM, 네트워크 등)의 현재 상태를 기록

 

 

 

 


 

 

(3-1) Google Cloud API 활성화

: GCP에서 보안을 위해 GUI에서 먼저 리소스를 생성하거나 API를 활성화해주어야 한다.

  나는 그렇지 않았고 API를 활성화 하고자 한다.

 

- API 비활성화되어 있는 모습

 

 

 

 

1) API 및 서비스 사용 설정 진입

 - 이곳에서 Compute Engine API를 검색한다.

 

 

 

2) API 및 서비스 사용 설정 진입

 

 - 사용을 누르자

 

 

 

3) 슬프다

 - 다행히 별 설정 없이 내 결제 계정이라고 지정만 하니 되었다.

 

 

 

 

 

4) 기다림의 미덕

👉

 

 

 


 

 

(4) Change infrastructure

 - 이전 수행 내용

  > (3)의 과정에서 VPC를 만들었고 확인할 수 있다.

  > 이번에는 내 설정을 수정하고, 새로운 리소스를 배포해보도록 하자

 

 

 

 

 

 - Create a new resource

 : 기존 tf파일에 vm을 생성하는 새로운 리소스를 정의하자

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 validate && terraform fmt

 

> 적용

terraform apply

 > VM이 뿅 생겼다.

 

 

 

 

- Modify configuration

 : "vm_instance" resource tags를 추가하고 적용해보자

tags = ["web", "dev"]

 

 

> 적용

terraform apply

 > 변경될 태그 정보가 나온다

> 해당 VM 상세 정보에 이렇게 변경된 태그가 표출된다.

 

 

 

 

 

 - Introduce destructive changes

 : 이제 기존의 소소한 변화가 아닌 이미지를 바꾸는 큰 변화를 줘보자

  boot_disk {
    initialize_params {
      # image = "debian-cloud/debian-11"
      image = "cos-cloud/cos-stable"
    }
  }

 > debian에서 구글의 컨테이너 최적화 os로 변경되었다.

 

> 적용

terraform apply

 

 

 

 

 


 

 

 

 

(5) Destroy infrastructure

 : 이제 필요를 다한 VM을 삭제해보자

 

- Destroy

terraform destroy

 > 리소스 삭제이기 때문에 삭제됨을 강조해주는 모습을 볼 수 있다.

 

 

 

 

 

 

 


 

 

 

 

 

(6) Define input variables

 : 지금까지 정적 환경을 정의했는데, 이번에는 동적으로 환경을 선언해보자

 

1) variables.tf 라는 새 파일을 생성했다.

variable "project" {}

variable "region" {
  default = "us-central1"
}

variable "zone" {
  default = "us-central1-c"
}

 > {} : 빈 블록은 값이 없기에 실행 시 질문

 > default : 값을 묻지 않고 기본값을 바로 사용

 

 * Terraform .tf로 된 모든 파일을 자동으로 읽는다.

 

 

 

 

1-1) 아래 명령어를 통해 이런 값이 필요한 내용들을 모두 질의 받을 수 있음

terraform plan

 

 

 

 

1-2) 파일 분리팁

 - variables.tf: 모든 변수를 모아둠

 - terraform.tfvars: 실제 입력하는 값만 따로 저장 (자동으로 불러옴)

project          = "terraform-study-250325"
credentials_file = "./my-key.json"

 * 당연히 terraform.tfvars git에 올리지 않음

 

 

 

 

2) Use variables in configuration

 : 이렇게 정의한 변수는 아래처럼 쓸 수 있다

provider "google" {
  # project = "terraform-study-250325"
  # region  = "us-central1"
  # zone    = "us-central1-c"
  project = var.project
  region  = var.region
  zone    = var.zone
}

 

 

 

 

 

 


 

 

 

 

 

(7) Query data with output values

 : 여기까지 진행하며 apply와 같이 명령을 하면, 출력이 굉장히 많음을
 
알 수 있을 텐데, 이러한 출력을 조정할 수 있는 ouput 속성이 있다.

 

1) variables.tf 생성

output "ip" {
  value = google_compute_instance.vm_instance.network_interface.0.network_ip
}

 - ip 라는 출력 변수를 지정한 모습

 - 변수 이름이 다른 모듈의 입력으로 쓰일 때는 명명 규칙을 따라야 함

 - 현재 value는 인스턴스 네트워크의 0번째 요소인 network_ip를 칭함

 - 당연히 여러 변수를 지정할 수 있음

 

 

 

2) 테스트를 위한 배포

terraform apply

 

 

 

 

 

3) 확인하고픈 정보 출력

terraform output

> 배포가 완료될 때도 내가 설정한 output 정보가 나온다

> 특별히 따로 확인할 수도 있다.

 

 


 

작성한 학습지

 

 

댓글