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.
- Estimated time: 30 minutes
- Recommended operating systems: macOS, Ubuntu
- Terraform CLI:
1.14.0or later - KakaoCloud Terraform Provider:
0.4.5 - Prerequisites
- IAM access key and resource management permissions in the target project
- Existing VPC and subnet
- Registered key pair
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:
- Define the Provider and input variables and look up an existing subnet, image, and instance type.
- Reference the lookup results in the VM resource, review the execution plan, and create the VM.
- Check the VM using outputs and state, then change its name with an input variable.
- 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.
- macOS
- Ubuntu
Run these commands on a system with Homebrew installed.
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
Add the HashiCorp package repository and install Terraform.
sudo apt-get update
sudo apt-get install -y gnupg curl lsb-release
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt-get update
sudo apt-get install -y 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.
- In KakaoCloud Console, go to Profile > Account settings > Credentials > IAM access keys at the top right.
- Click [Create IAM access key] and select the project where you will create the VM.
- Store the Access key ID and Secret access key securely.
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.
- Go to KakaoCloud Console > Networking > VPC.
- In Subnets, select the subnet where you will create the VM.
- 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.
- Go to KakaoCloud Console > Compute > Beyond Compute Service > Virtual Machine.
- 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
-
Specify the Terraform and KakaoCloud Provider versions in
versions.tf.versions.tfterraform {
required_version = ">= 1.14.0"
required_providers {
kakaocloud = {
source = "kakaoenterprise/kakaocloud"
version = "0.4.5"
}
}
}
provider "kakaocloud" {}Do not enter credentials directly in the
providerblock. The Provider uses the environment variables you set in a later step. -
Define the variables for VM creation in
variables.tf.variables.tfvariable "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"
} -
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 invariables.tfand assign values for the lab environment interraform.tfvars.terraform.tfvarssubnet_id = "{SUBNET_ID}"
key_pair_name = "{KEY_PAIR_NAME}" -
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
-
In
main.tf, define data sources to look up the existing subnet, instance type, and image, and define the VM resource.main.tfdata "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_terminationtotruedeletes the root volume created in this lab when you delete the VM. -
Define the values to check after creation in
outputs.tf.outputs.tfoutput "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
-
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}" -
Initialize the working directory and install the Provider.
terraform init -
Check the formatting and syntax of the configuration files.
terraform fmt
terraform fmt -check
terraform validate -
Generate an execution plan.
terraform plan -out=tfplanCheck for this summary showing one VM resource to create. The root volume is created through the VM's
volumesargument, so the plan does not show it as a separate Terraform resource.Plan: 1 to add, 0 to change, 0 to destroy.
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
-
Review the saved plan with
terraform show tfplan, then apply it.terraform show tfplan
terraform apply tfplanCheck for
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.. -
Check the VM ID, name, state, and private IPs using outputs.
terraform output
terraform output -raw instance_idCompare
instance_idwith the VM ID in the console and record it. You will use it to verify that the renamed VM is the same VM. -
Check the resources recorded in Terraform state.
terraform state listVerify that these entries are included.
data.kakaocloud_images.selected
data.kakaocloud_instance_flavors.selected
data.kakaocloud_subnets.selected
kakaocloud_instance.tutorial
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.
- Go to KakaoCloud Console > Compute > Beyond Compute Service > Virtual Machine > Instances.
- Verify that
terraform-tutorial-vmisACTIVE. 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.
-
Add this value to
terraform.tfvars. Keep the subnet ID and key pair name unchanged.Add to terraform.tfvarsinstance_name = "terraform-tutorial-vm-renamed" -
Save the change plan to a new file.
terraform plan -out=rename.tfplan
terraform show rename.tfplanVerify that only
namechanges onkakaocloud_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. -
Apply the plan and verify the result.
terraform apply rename.tfplan
terraform output -raw instance_name
terraform output -raw instance_id
terraform planThe 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.
-
Preview the resources to delete.
terraform plan -destroy -
Delete the resources.
terraform destroy -
Review the execution plan and enter
yeswhen prompted to confirm deletion. -
In Virtual Machine > Instances, verify that
terraform-tutorial-vm-renamedhas been deleted. -
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
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.04invariables.tf - The instance type
m2a.largeinvariables.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.
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.