본문으로 건너뛰기

Terraform으로 VM 프로비저닝 및 변경

KakaoCloud Terraform Provider로 기존 서브넷에 VM을 생성하고, 실행 계획과 출력값으로 이름 변경을 확인한 뒤 삭제합니다.

기본 정보
연계 튜토리얼

이 튜토리얼에서 VM의 생성·변경 과정을 익힌 뒤, Terraform으로 MySQL 기반 3-Tier 웹 서비스 구축에서 네트워크·서버·로드 밸런서·데이터베이스를 함께 구성하는 과정을 확인할 수 있습니다.

시나리오 소개​

이 튜토리얼은 Terraform을 처음 사용하는 사용자가 작은 구성으로 생성 → 확인 → 변경 → 삭제 과정을 익힐 수 있도록 안내합니다. 기존 서브넷과 키 페어를 사용하고, VM과 루트 볼륨만 새로 생성합니다.

접속용 퍼블릭 IP나 별도 보안 그룹을 생성하지 않으므로 결과는 Terraform과 콘솔에서 확인합니다. 기본 구성은 Ubuntu 24.04 이미지, m2a.large 인스턴스 유형과 20 GB 루트 볼륨을 사용합니다.

실습에서는 다음 작업을 수행합니다.

  1. Provider와 입력 변수를 정의하고 기존 서브넷·이미지·인스턴스 유형을 조회합니다.
  2. 조회 결과를 VM 리소스에서 참조하고, 실행 계획을 확인한 뒤 VM을 생성합니다.
  3. 출력값과 상태 파일에서 VM을 확인하고, 입력 변수로 이름을 변경합니다.
  4. 변경 전후의 VM ID를 비교한 뒤 생성한 리소스를 삭제합니다.

이 실습에서는 Terraform의 주요 개념이 실제 구성과 명령에 어떻게 사용되는지 확인합니다.

시작하기 전에​

대상 프로젝트에서 VM을 생성·조회·변경·삭제하고 VPC와 이미지를 조회할 수 있는 권한을 확인한 뒤, 아래 순서로 실행 환경과 기존 리소스를 준비합니다.

Terraform 설치 및 버전 확인​

Terraform 공식 설치 가이드에 따라 Terraform CLI 1.14.0 이상을 설치합니다. 두 튜토리얼에서는 같은 CLI 버전을 사용할 수 있지만, Provider는 각 예제의 versions.tf에 지정한 버전을 사용합니다.

Homebrew가 설치된 환경에서 다음 명령을 실행합니다.

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

설치 후 버전을 확인합니다. 1.13.x 이하이면 업그레이드한 뒤 진행하세요.

terraform version

IAM 액세스 키 준비​

Terraform Provider가 카카오클라우드 API를 호출하려면 IAM 액세스 키 ID와 보안 액세스 키가 필요합니다.

  1. 카카오클라우드 콘솔 우측 상단의 프로필 > 계정 설정 > 자격 증명 > IAM 액세스 키로 이동합니다.
  2. [IAM 액세스 키 생성] 버튼을 클릭하고 VM을 생성할 프로젝트를 선택합니다.
  3. 생성된 액세스 키 ID와 보안 액세스 키를 안전한 위치에 보관합니다.
IAM 액세스 키 보안

보안 액세스 키는 생성 직후에만 확인할 수 있습니다. 액세스 키를 Terraform 구성 파일, terraform.tfvars, Git 저장소에 저장하지 마세요.

서브넷 ID 확인​

VM을 연결할 기존 서브넷의 ID를 확인합니다.

  1. 카카오클라우드 콘솔 > Networking > VPC로 이동합니다.
  2. 서브넷 메뉴에서 VM을 생성할 서브넷을 선택합니다.
  3. 세부 정보 탭에서 ID를 확인합니다.

VPC와 서브넷이 없다면 VPC 생성과 서브넷 생성을 참고해 먼저 준비하세요. 이번 실습에서 조회할 네트워크는 VM과 같은 프로젝트의 kr-central-2 리전에 있어야 합니다.

키 페어 이름 확인​

VM에 적용할 키 페어의 이름을 확인합니다.

  1. 카카오클라우드 콘솔 > Compute > Beyond Compute Service > Virtual Machine으로 이동합니다.
  2. 키 페어 메뉴에서 사용할 키 페어의 이름을 확인합니다.

키 페어가 없다면 키 페어 생성을 참고해 먼저 생성해 주세요. 프라이빗 키는 생성할 때 한 번만 다운로드할 수 있으므로 안전하게 보관해야 합니다.

시작하기​

작업 디렉터리와 구성 파일을 준비한 뒤, VM을 생성하고 이름을 변경해 결과를 확인합니다. 실습을 마치면 생성한 VM과 루트 볼륨을 삭제합니다.

Step 1. 작업 디렉터리 생성​

이 실습 전용 디렉터리를 생성합니다. .tf 파일은 역할별로 나누지만, Terraform은 현재 디렉터리의 파일을 하나의 구성으로 읽습니다. 이후의 모든 명령은 이 디렉터리에서 실행합니다.

mkdir ~/terraform-kakaocloud-vm
cd ~/terraform-kakaocloud-vm
touch versions.tf variables.tf main.tf outputs.tf terraform.tfvars .gitignore

Step 2. Provider와 변수 정의​

  1. versions.tf에 Terraform과 KakaoCloud Provider 버전을 정의합니다.

    versions.tf
    terraform {
    required_version = ">= 1.14.0"

    required_providers {
    kakaocloud = {
    source = "kakaoenterprise/kakaocloud"
    version = "0.4.5"
    }
    }
    }

    provider "kakaocloud" {}

    provider 블록에 인증 정보를 직접 입력하지 않습니다. 이후 단계에서 설정하는 환경 변수를 Provider가 사용합니다.

  2. variables.tf에 VM 생성에 사용할 변수를 정의합니다.

    variables.tf
    variable "subnet_id" {
    description = "VM을 연결할 서브넷 ID"
    type = string
    }

    variable "key_pair_name" {
    description = "VM에 적용할 키 페어 이름"
    type = string
    }

    variable "instance_name" {
    description = "생성할 VM 이름"
    type = string
    default = "terraform-tutorial-vm"
    }

    variable "instance_flavor" {
    description = "VM 인스턴스 유형"
    type = string
    default = "m2a.large"
    }

    variable "image_name" {
    description = "VM 이미지 이름"
    type = string
    default = "Ubuntu 24.04"
    }
  3. terraform.tfvars에 앞에서 확인한 서브넷 ID와 키 페어 이름을 입력합니다. {SUBNET_ID}와 {KEY_PAIR_NAME}을 실제 값으로 바꾸세요. 변수 선언은 variables.tf, 실습 환경의 값은 terraform.tfvars에 작성합니다.

    terraform.tfvars
    subnet_id     = "{SUBNET_ID}"
    key_pair_name = "{KEY_PAIR_NAME}"
  4. .gitignore에 Terraform의 로컬 작업 파일과 변수 파일을 추가합니다.

    .gitignore
    .terraform/
    *.tfstate
    *.tfstate.*
    *.tfplan
    tfplan
    rename.tfplan
    crash.log
    terraform.tfvars

Step 3. 조회 결과와 VM 리소스 연결​

  1. main.tf에 기존 서브넷, 인스턴스 유형, 이미지를 조회하는 Data Source와 VM 리소스를 정의합니다.

    main.tf
    data "kakaocloud_subnets" "selected" {
    filter = [
    {
    name = "id"
    value = var.subnet_id
    }
    ]
    }

    data "kakaocloud_instance_flavors" "selected" {
    filter = [
    {
    name = "instance_type"
    value = "vm"
    },
    {
    name = "name"
    value = var.instance_flavor
    }
    ]
    }

    data "kakaocloud_images" "selected" {
    filter = [
    {
    name = "instance_type"
    value = "vm"
    },
    {
    name = "name"
    value = var.image_name
    }
    ]
    }

    resource "kakaocloud_instance" "tutorial" {
    name = var.instance_name
    description = "VM created with Terraform"
    flavor_id = data.kakaocloud_instance_flavors.selected.instance_flavors[0].id
    image_id = data.kakaocloud_images.selected.images[0].id
    key_name = var.key_pair_name

    subnets = [
    {
    id = data.kakaocloud_subnets.selected.subnets[0].id
    }
    ]

    volumes = [
    {
    size = 20
    is_delete_on_termination = true
    }
    ]
    }

    is_delete_on_termination을 true로 설정하면 VM을 삭제할 때 이 튜토리얼에서 생성한 루트 볼륨도 함께 삭제됩니다.

  2. outputs.tf에 생성 결과로 확인할 값을 정의합니다.

    outputs.tf
    output "instance_id" {
    description = "생성된 VM ID"
    value = kakaocloud_instance.tutorial.id
    }

    output "instance_name" {
    description = "생성된 VM 이름"
    value = kakaocloud_instance.tutorial.name
    }

    output "instance_state" {
    description = "생성된 VM 상태"
    value = kakaocloud_instance.tutorial.vm_state
    }

    output "private_ips" {
    description = "VM에 할당된 프라이빗 IP 목록"
    value = [for address in kakaocloud_instance.tutorial.addresses : address.private_ip]
    }

조회한 기존 리소스는 data 블록으로, 새로 생성할 VM은 resource 블록으로 구분합니다. VM의 image_id와 flavor_id가 조회 결과를 참조하므로 Terraform은 조회가 끝난 뒤 VM을 생성하도록 순서를 계산합니다. outputs.tf는 그 결과 중 확인할 값을 이름으로 제공합니다.

전체 리소스와 인자에 대한 설명은 KakaoCloud Provider 문서를 참고해 주세요.

Step 4. Terraform 초기화 및 실행 계획 확인​

  1. IAM 액세스 키 ID와 보안 액세스 키를 환경 변수로 설정합니다.

    export KAKAOCLOUD_APPLICATION_CREDENTIAL_ID="{IAM_ACCESS_KEY_ID}"
    export KAKAOCLOUD_APPLICATION_CREDENTIAL_SECRET="{IAM_SECRET_ACCESS_KEY}"
  2. 작업 디렉터리를 초기화하고 Provider를 설치합니다.

    terraform init
  3. 구성 파일의 형식과 문법을 확인합니다.

    terraform fmt
    terraform fmt -check
    terraform validate
  4. 실행 계획을 생성합니다.

    terraform plan -out=tfplan

    VM 리소스 1개가 생성되는 다음 요약을 확인합니다. 루트 볼륨은 VM의 volumes 인자로 생성하므로 계획에 별도 Terraform 리소스로 표시되지 않습니다.

    Plan: 1 to add, 0 to change, 0 to destroy.
실행 계획 확인

저장한 계획에는 민감한 값이 포함될 수 있습니다. terraform apply tfplan은 저장한 계획을 추가 승인 없이 적용하므로, 적용 전에 계획을 검토해야 합니다. 구성이나 변수값을 수정했다면 계획도 다시 생성하세요.

terraform apply를 실행하기 전에 VM 이름, 이미지, 인스턴스 유형, 서브넷, 루트 볼륨 크기가 의도한 값인지 확인해 주세요.

Step 5. VM 생성 및 결과 확인​

  1. terraform show tfplan으로 저장한 계획을 검토한 뒤 적용합니다.

    terraform show tfplan
    terraform apply tfplan

    Apply complete! Resources: 1 added, 0 changed, 0 destroyed. 메시지가 표시되는지 확인합니다.

  2. 출력값으로 VM ID, 이름, 상태와 프라이빗 IP를 확인합니다.

    terraform output
    terraform output -raw instance_id

    instance_id를 콘솔의 VM ID와 비교하고 기록해 둡니다. 이름 변경 후 같은 VM인지 확인할 때 사용합니다.

  3. Terraform State에 기록된 리소스를 확인합니다.

    terraform state list

    다음 항목이 포함되어 있는지 확인합니다.

    data.kakaocloud_images.selected
    data.kakaocloud_instance_flavors.selected
    data.kakaocloud_subnets.selected
    kakaocloud_instance.tutorial
Terraform State 보안

terraform.tfstate에는 인프라 구성 정보가 저장됩니다. 상태 파일은 이 작업 디렉터리의 구성과 실제 VM을 연결합니다. 파일을 삭제하면 Terraform이 기존 VM을 추적할 수 없게 되므로, 임의로 수정·삭제하거나 공개된 저장소에 업로드하지 마세요.

Provider 버전을 기록한 .terraform.lock.hcl은 버전 관리에 포함합니다.

  1. 카카오클라우드 콘솔 > Compute > Beyond Compute Service > Virtual Machine > 인스턴스로 이동합니다.
  2. terraform-tutorial-vm 인스턴스의 상태가 ACTIVE인지 확인합니다. 생성 직후에는 상태가 변경되는 데 시간이 걸릴 수 있습니다.

Step 6. 입력 변수로 VM 이름 변경​

기존 VM의 이름을 바꾸며 생성할 때와 같은 구성 수정 → 계획 확인 → 적용 흐름을 경험합니다.

  1. terraform.tfvars에 다음 값을 추가합니다. 서브넷 ID와 키 페어 이름은 유지합니다.

    terraform.tfvars에 추가
    instance_name = "terraform-tutorial-vm-renamed"
  2. 변경 계획을 새 파일로 저장합니다.

    terraform plan -out=rename.tfplan
    terraform show rename.tfplan

    kakaocloud_instance.tutorial의 name만 변경되는지 확인합니다. 기대하는 요약은 다음과 같습니다.

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

    삭제·재생성(-/+)이 표시되거나 다른 리소스가 변경되면 적용하지 말고 수정한 입력값을 확인하세요.

  3. 계획을 적용하고 변경 결과를 확인합니다.

    terraform apply rename.tfplan
    terraform output -raw instance_name
    terraform output -raw instance_id
    terraform plan

    이름은 terraform-tutorial-vm-renamed로 바뀌고 VM ID는 앞에서 기록한 값과 같아야 합니다. 마지막 계획에서 추가 변경이 없는지 확인합니다. 콘솔에서도 동일한 VM의 이름이 변경되었는지 확인하세요.

Step 7. 리소스 정리​

실습을 마치면 Terraform으로 생성한 VM과 루트 볼륨을 삭제합니다.

  1. 삭제할 리소스를 미리 확인합니다.

    terraform plan -destroy
  2. 리소스를 삭제합니다.

    terraform destroy
  3. 삭제 확인 메시지가 표시되면 실행 계획을 확인한 뒤 yes를 입력합니다.

  4. 카카오클라우드 콘솔의 Virtual Machine > 인스턴스에서 terraform-tutorial-vm-renamed가 삭제되었는지 확인합니다.

  5. Storage > Block Storage > 볼륨에서 VM의 루트 볼륨이 남아 있지 않은지 확인합니다.

삭제 후 terraform state list에 kakaocloud_instance.tutorial이 남아 있지 않은지 확인합니다. 실습 전용 터미널이라면 다음 명령으로 인증 환경 변수를 해제합니다.

unset KAKAOCLOUD_APPLICATION_CREDENTIAL_ID KAKAOCLOUD_APPLICATION_CREDENTIAL_SECRET
기존 리소스는 삭제되지 않음

이 튜토리얼에서 Terraform이 생성한 리소스는 VM과 루트 볼륨입니다. 입력값으로 참조한 기존 서브넷과 키 페어는 terraform destroy 실행 후에도 유지됩니다.

문제 해결​

인증 오류가 발생하는 경우​

401, 403, Unauthorized 오류가 발생하면 다음 항목을 확인합니다.

  • 환경 변수 이름과 값이 올바른지 확인합니다.
  • IAM 액세스 키를 발급할 때 선택한 프로젝트와 VM을 생성할 프로젝트가 같은지 확인합니다.
  • 액세스 키를 발급한 사용자에게 VM, VPC, 이미지 조회 및 생성에 필요한 프로젝트 역할이 있는지 확인합니다.
  • 만료되거나 삭제된 IAM 액세스 키가 아닌지 확인합니다.

환경 변수 설정 여부는 다음 명령으로 확인할 수 있습니다. 보안 액세스 키의 실제 값은 출력하지 마세요.

test -n "$KAKAOCLOUD_APPLICATION_CREDENTIAL_ID" && echo "credential ID is set"
test -n "$KAKAOCLOUD_APPLICATION_CREDENTIAL_SECRET" && echo "credential secret is set"

조회 결과가 없어 오류가 발생하는 경우​

Invalid index 또는 빈 조회 결과와 관련된 오류가 발생하면 다음 값을 확인합니다.

  • terraform.tfvars의 서브넷 ID
  • variables.tf의 이미지 이름 Ubuntu 24.04
  • variables.tf의 인스턴스 유형 m2a.large
  • 서브넷, 이미지, 인스턴스 유형이 현재 프로젝트와 가용 영역에서 사용 가능한지 여부

사용할 이미지나 인스턴스 유형이 다르면 terraform.tfvars에서 기본값을 재정의할 수 있습니다.

terraform.tfvars
subnet_id       = "{SUBNET_ID}"
key_pair_name = "{KEY_PAIR_NAME}"
image_name = "{IMAGE_NAME}"
instance_flavor = "{INSTANCE_FLAVOR}"

VM 생성이 완료되지 않는 경우​

카카오클라우드 콘솔에서 인스턴스 상태와 이벤트를 확인합니다. 이미지의 최소 디스크 크기가 20 GB보다 크다면 main.tf의 volumes.size를 이미지 요구 사항에 맞게 늘린 뒤 다시 terraform plan을 실행해 주세요.

Terraform 명령이 중단되었더라도 콘솔에서 리소스를 바로 삭제하지 마세요. 먼저 다음 명령으로 Terraform State에 VM이 기록되었는지 확인합니다.

terraform state list

State에 kakaocloud_instance.tutorial이 있으면 terraform destroy로 정리합니다. State에는 없지만 콘솔에 VM이나 볼륨이 생성되어 있다면 해당 리소스를 콘솔에서 직접 확인하고 삭제해 주세요.

다음 단계​

이 튜토리얼에서는 기존 서브넷에 VM을 생성하고, 실행 계획과 출력값으로 이름 변경을 확인한 뒤 리소스를 삭제했습니다. 네트워크·서버·로드 밸런서·MySQL을 함께 구성하려면 Terraform으로 MySQL 기반 3-Tier 웹 서비스 구축을 진행하세요.

3-Tier 실습을 시작하기 전에 이 튜토리얼에서 생성한 VM을 삭제하고, 예제용 작업 디렉터리를 새로 준비하세요. 두 실습은 각각 별도의 디렉터리와 상태 파일을 사용합니다.