Skip to main content

Provision and update VM with Terraform

Create a VM in an existing subnet with the KakaoCloud Terraform Provider, verify a name change using execution plans and outputs, and delete the VM.

Basic information
Related tutorial

After practicing VM creation and updates in this tutorial, continue with Build MySQL-based 3-Tier web service with Terraform to configure networks, servers, load balancers, and a database together.

About this scenario​

This tutorial helps first-time Terraform users practice create → verify → update → delete with a small configuration. It uses an existing subnet and key pair and creates only a VM and its root volume.

Because it does not create a public IP or a separate security group for access, you verify results using Terraform and the console. The default configuration uses the Ubuntu 24.04 image, the m2a.large instance type, and a 20 GB root volume.

In this lab, you perform these tasks:

  1. Define the Provider and input variables and look up an existing subnet, image, and instance type.
  2. Reference the lookup results in the VM resource, review the execution plan, and create the VM.
  3. Check the VM using outputs and state, then change its name with an input variable.
  4. Compare the VM ID before and after the change, then delete the resources you created.

This lab shows how key Terraform concepts appear in configuration files and commands.

Before you start​

Verify that you have permissions to create, view, update, and delete VMs and view VPCs and images in the target project. Then prepare the execution environment and existing resources in the following order.

Install and verify Terraform​

Follow the official Terraform installation guide to install Terraform CLI 1.14.0 or later. You can use the same CLI version for both tutorials, but use the Provider version specified in each example's versions.tf.

Run these commands on a system with Homebrew installed.

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

Verify the installed version. If it is 1.13.x or earlier, upgrade before continuing.

terraform version

Prepare IAM access key​

The Terraform Provider needs an IAM access key ID and secret access key to call KakaoCloud APIs.

  1. In KakaoCloud Console, go to Profile > Account settings > Credentials > IAM access keys at the top right.
  2. Click [Create IAM access key] and select the project where you will create the VM.
  3. Store the Access key ID and Secret access key securely.
Protect IAM access key

The secret access key is displayed only immediately after creation. Do not store access keys in Terraform configuration files, terraform.tfvars, or Git repositories.

Check subnet ID​

Find the ID of the existing subnet for the VM.

  1. Go to KakaoCloud Console > Networking > VPC.
  2. In Subnets, select the subnet where you will create the VM.
  3. Check ID on the Details tab.

If you do not have a VPC and subnet, prepare them by following Create VPC and Create subnet. The network you look up in this lab must be in the VM's project and the kr-central-2 region.

Check key pair name​

Find the name of the key pair for the VM.

  1. Go to KakaoCloud Console > Compute > Beyond Compute Service > Virtual Machine.
  2. In Key pairs, check the name of the key pair to use.

If you do not have a key pair, follow Create key pair. You can download the private key only once, when you create it, so store it securely.

Getting started​

Prepare a working directory and configuration files, create a VM, change its name, and verify the result. After the lab, delete the VM and root volume you created.

Step 1. Create working directory​

Create a directory dedicated to this lab. Although the .tf files are separated by purpose, Terraform reads the files in the current directory as one configuration. Run all subsequent commands in this directory.

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

Step 2. Define Provider and variables​

  1. Specify the Terraform and KakaoCloud Provider versions in versions.tf.

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

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

    provider "kakaocloud" {}

    Do not enter credentials directly in the provider block. The Provider uses the environment variables you set in a later step.

  2. Define the variables for VM creation in variables.tf.

    variables.tf
    variable "subnet_id" {
    description = "ID of the subnet for the VM"
    type = string
    }

    variable "key_pair_name" {
    description = "Name of the key pair for the VM"
    type = string
    }

    variable "instance_name" {
    description = "Name of the VM to create"
    type = string
    default = "terraform-tutorial-vm"
    }

    variable "instance_flavor" {
    description = "VM instance type"
    type = string
    default = "m2a.large"
    }

    variable "image_name" {
    description = "VM image name"
    type = string
    default = "Ubuntu 24.04"
    }
  3. Enter the subnet ID and key pair name you checked earlier in terraform.tfvars. Replace {SUBNET_ID} and {KEY_PAIR_NAME} with actual values. Declare variables in variables.tf and assign values for the lab environment in terraform.tfvars.

    terraform.tfvars
    subnet_id     = "{SUBNET_ID}"
    key_pair_name = "{KEY_PAIR_NAME}"
  4. Add Terraform's local working files and variable file to .gitignore.

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

Step 3. Connect lookup results to VM resource​

  1. In main.tf, define data sources to look up the existing subnet, instance type, and image, and define the VM resource.

    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
    }
    ]
    }

    Setting is_delete_on_termination to true deletes the root volume created in this lab when you delete the VM.

  2. Define the values to check after creation in outputs.tf.

    outputs.tf
    output "instance_id" {
    description = "ID of the created VM"
    value = kakaocloud_instance.tutorial.id
    }

    output "instance_name" {
    description = "Name of the created VM"
    value = kakaocloud_instance.tutorial.name
    }

    output "instance_state" {
    description = "State of the created VM"
    value = kakaocloud_instance.tutorial.vm_state
    }

    output "private_ips" {
    description = "Private IP addresses assigned to the VM"
    value = [for address in kakaocloud_instance.tutorial.addresses : address.private_ip]
    }

Use data blocks for existing resources you look up and a resource block for the VM you create. The VM's image_id and flavor_id reference lookup results, so Terraform creates the VM after those lookups finish. outputs.tf exposes selected results by name.

For complete resource and argument descriptions, see the KakaoCloud Provider documentation.

Step 4. Initialize Terraform and review execution plan​

  1. Set the IAM access key ID and secret access key as environment variables.

    export KAKAOCLOUD_APPLICATION_CREDENTIAL_ID="{IAM_ACCESS_KEY_ID}"
    export KAKAOCLOUD_APPLICATION_CREDENTIAL_SECRET="{IAM_SECRET_ACCESS_KEY}"
  2. Initialize the working directory and install the Provider.

    terraform init
  3. Check the formatting and syntax of the configuration files.

    terraform fmt
    terraform fmt -check
    terraform validate
  4. Generate an execution plan.

    terraform plan -out=tfplan

    Check for this summary showing one VM resource to create. The root volume is created through the VM's volumes argument, so the plan does not show it as a separate Terraform resource.

    Plan: 1 to add, 0 to change, 0 to destroy.
Review execution plan

A saved plan can contain sensitive values. terraform apply tfplan applies the saved plan without another approval prompt, so review the plan first. Regenerate the plan if you change the configuration or variable values.

Before running terraform apply, verify the VM name, image, instance type, subnet, and root volume size.

Step 5. Create and verify VM​

  1. Review the saved plan with terraform show tfplan, then apply it.

    terraform show tfplan
    terraform apply tfplan

    Check for Apply complete! Resources: 1 added, 0 changed, 0 destroyed..

  2. Check the VM ID, name, state, and private IPs using outputs.

    terraform output
    terraform output -raw instance_id

    Compare instance_id with the VM ID in the console and record it. You will use it to verify that the renamed VM is the same VM.

  3. Check the resources recorded in Terraform state.

    terraform state list

    Verify that these entries are included.

    data.kakaocloud_images.selected
    data.kakaocloud_instance_flavors.selected
    data.kakaocloud_subnets.selected
    kakaocloud_instance.tutorial
Protect Terraform state

terraform.tfstate stores infrastructure configuration information. It connects the configuration in this working directory to the actual VM. Deleting the file prevents Terraform from tracking the existing VM, so do not manually modify or delete it or upload it to a public repository.

Include .terraform.lock.hcl, which records Provider versions, in version control.

  1. Go to KakaoCloud Console > Compute > Beyond Compute Service > Virtual Machine > Instances.
  2. Verify that terraform-tutorial-vm is ACTIVE. Its state may take time to change immediately after creation.

Step 6. Rename VM with input variable​

Change the existing VM's name using the same edit configuration → review plan → apply workflow as creation.

  1. Add this value to terraform.tfvars. Keep the subnet ID and key pair name unchanged.

    Add to terraform.tfvars
    instance_name = "terraform-tutorial-vm-renamed"
  2. Save the change plan to a new file.

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

    Verify that only name changes on kakaocloud_instance.tutorial. The expected summary is:

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

    If the plan shows deletion and recreation (-/+) or changes to other resources, do not apply it. Check the input values you changed.

  3. Apply the plan and verify the result.

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

    The name should be terraform-tutorial-vm-renamed, and the VM ID should match the value recorded earlier. Verify that the final plan shows no additional changes. Check that the same VM has the new name in the console.

Step 7. Clean up resources​

After the lab, delete the VM and root volume created with Terraform.

  1. Preview the resources to delete.

    terraform plan -destroy
  2. Delete the resources.

    terraform destroy
  3. Review the execution plan and enter yes when prompted to confirm deletion.

  4. In Virtual Machine > Instances, verify that terraform-tutorial-vm-renamed has been deleted.

  5. In Storage > Block Storage > Volumes, verify that the VM's root volume no longer exists.

After deletion, verify that terraform state list no longer includes kakaocloud_instance.tutorial. If the terminal is dedicated to this lab, unset the credential environment variables.

unset KAKAOCLOUD_APPLICATION_CREDENTIAL_ID KAKAOCLOUD_APPLICATION_CREDENTIAL_SECRET
Existing resources remain

The resources Terraform creates in this lab are the VM and its root volume. The existing subnet and key pair referenced through input values remain after terraform destroy.

Troubleshooting​

Authentication errors​

If you see 401, 403, or Unauthorized, check these items:

  • Verify the environment variable names and values.
  • Verify that the project selected when issuing the IAM access key matches the project where you create the VM.
  • Verify that the user who issued the access key has project roles required to look up and create VMs, VPCs, and images.
  • Verify that the IAM access key has not expired or been deleted.

Use these commands to check whether the environment variables are set. Do not print the actual secret access key.

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

Empty lookup results​

If you see Invalid index or an error about empty lookup results, check these values:

  • The subnet ID in terraform.tfvars
  • The image name Ubuntu 24.04 in variables.tf
  • The instance type m2a.large in variables.tf
  • Whether the subnet, image, and instance type are available in the current project and availability zone

If you use a different image or instance type, override the defaults in terraform.tfvars.

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

VM creation does not complete​

Check the instance state and events in the console. If the image requires a disk larger than 20 GB, increase volumes.size in main.tf to match the image requirements and run terraform plan again.

If a Terraform command is interrupted, do not immediately delete the resource in the console. First check whether the VM is recorded in Terraform state.

terraform state list

If state includes kakaocloud_instance.tutorial, clean up with terraform destroy. If the VM or volume exists in the console but is not in state, inspect and delete the resource in the console.

Next step​

In this tutorial, you created a VM in an existing subnet, verified a name change using execution plans and outputs, and deleted the resources. To configure a network, servers, load balancers, and MySQL together, continue with Build MySQL-based 3-Tier web service with Terraform.

Before starting the 3-Tier lab, delete the VM created in this tutorial and prepare a new working directory for the example. Each lab uses its own directory and state file.