Skip to main content

Terraform cheatsheet

Common commands

terraform init # download providers
terraform plan # preview changes
terraform apply # apply
terraform apply -auto-approve # apply without confirmation
terraform destroy # destroy everything
terraform show # show current state
terraform output # show output values
terraform fmt # format HCL
terraform validate # validate syntax/types

# Recreate a single resource (e.g. reallocate after reclamation)
terraform apply -replace="eci_virtual_machine_allocation.run"

# Destroy a single resource (stop the VM by removing only the allocation)
terraform destroy -target="eci_virtual_machine_allocation.run"

# Remove from state (the actual resource is kept)
terraform state rm eci_virtual_machine.vm

# Import an existing resource (bring portal-created resources into code)
terraform import eci_virtual_machine.vm <UUID>

Provider config (required)

terraform {
required_version = ">= 1.0"
required_providers {
eci = {
source = "elice-dev/eci"
}
}
}

provider "eci" {
api_endpoint = "https://portal.elice.cloud/api"
api_access_token = var.api_access_token # TF_VAR_api_access_token env var
zone_id = var.zone_id
}

Common data sources

# Instance types
data "eci_instance_type" "h100_1" { name = "G-NHHS-80" }
data "eci_instance_type" "h100_8" { name = "G-NHHS-640" }
data "eci_instance_type" "cpu_8" { name = "C-8" }
data "eci_instance_type" "mem_8" { name = "M-8" }

# Pricing (name + pricing_type)
data "eci_pricing" "vm_ondemand" { name = "G-NHHS-80", pricing_type = "ondemand" }
data "eci_pricing" "vm_spot" { name = "G-NHHS-80", pricing_type = "spot" }
data "eci_pricing" "vm_reserved" { name = "G-NHHS-80", pricing_type = "reserved" }
data "eci_pricing" "storage" { name = "Block Storage", pricing_type = "ondemand" }
data "eci_pricing" "public_ip" { name = "Public IP", pricing_type = "ondemand" }

# OS image
data "eci_block_storage_image" "ubuntu" {
name = "Ubuntu 22.04 LTS (20250116)"
}

# Zone / region
data "eci_zone" "primary" { name = "<zone-name>" }
data "eci_region" "main" { name = "central-01" }

Common resources

Virtual network + subnet

resource "eci_virtual_network" "vnet" {
name = "prod-vnet"
network_cidr = "192.168.0.0/16" # only 172.16.0.0/14 or 192.168.0.0/16 are allowed
tags = { env = "prod" }
}

resource "eci_subnet" "subnet" {
attached_network_id = eci_virtual_network.vnet.id
name = "prod-subnet"
purpose = "virtual_machine"
network_gw = "192.168.0.1/24"
tags = { env = "prod" }
}

Virtual machine (definition + allocation)

# 1) VM definition
resource "eci_virtual_machine" "vm" {
name = "prod-vm-01"
instance_type_id = data.eci_instance_type.h100_1.id
pricing_id = data.eci_pricing.vm_ondemand.id
username = "elice"
password = var.vm_password
on_init_script = "#!/bin/bash\nset -e\n# init"
always_on = false # must be false for spot
dr = false # must be false for spot
tags = { env = "prod" }
}

# 2) Run (allocation)
resource "eci_virtual_machine_allocation" "run" {
machine_id = eci_virtual_machine.vm.id
tags = { env = "prod" }
depends_on = [eci_block_storage.boot, eci_network_interface.ni]
}

Block storage (boot disk / data disk / snapshot restore)

# Boot disk (image_id specified)
resource "eci_block_storage" "boot" {
attached_machine_id = eci_virtual_machine.vm.id
name = "prod-vm-01-boot"
size_gib = 100
pricing_id = data.eci_pricing.storage.id
image_id = data.eci_block_storage_image.ubuntu.id
dr = false
tags = { env = "prod" }
}

# Data disk (no image_id or snapshot_id)
resource "eci_block_storage" "data" {
attached_machine_id = eci_virtual_machine.vm.id
name = "prod-vm-01-data"
size_gib = 500
pricing_id = data.eci_pricing.storage.id
dr = false
}

# Restore from a snapshot
resource "eci_block_storage" "from_snapshot" {
name = "restored-disk"
size_gib = 500
pricing_id = data.eci_pricing.storage.id
snapshot_id = "<snapshot-uuid>"
dr = false
}

# Create a snapshot
resource "eci_block_storage_snapshot" "snap" {
block_storage_id = eci_block_storage.data.id
name = "data-snap-2026-05"
dr = false
}

Network interface + public IP

resource "eci_network_interface" "ni" {
attached_subnet_id = eci_subnet.subnet.id
attached_machine_id = eci_virtual_machine.vm.id
name = "prod-vm-01-ni"
dr = false
}

resource "eci_public_ip" "ip" {
attached_network_interface_id = eci_network_interface.ni.id
pricing_id = data.eci_pricing.public_ip.id
dr = false # for DDoS options, see the provider's separate field
}

Instance type code reference

CodeDeviceNotes
G-NHHS-80H100 80GB SXM × 1Single GPU
G-NHHS-640H100 80GB SXM × 8Max per node
G-NAHP-80A100 80GB PCIe × 1
G-NAHP-320A100 80GB PCIe × 4
G-NBTHS-180B200 180GB SXM × 1
G-NBTHS-1440B200 180GB SXM × 8
C-2C-32CPU vCore (2/4/8/16/32)Memory = vCore × 2
M-2M-16Memory-optimized (2/4/8/16 vCore)Memory = vCore × 4

NPU code names (Rebellions ATOM, Furiosa) are provided by sales/support. For the full list, see Infrastructure > Instance Types in the portal or the instance type guide.


Common mistakes

SymptomCause / fix
Provider produced inconsistent resultRun terraform refresh and retry. Check whether the resource was changed outside Terraform
SPOT_ALWAYS_ON_NOT_ALLOWED when creating a spot VMSet always_on = false
SPOT_DR_NOT_ALLOWED when creating a spot VMSet dr = false
NIC error when deleting a VMInclude the NIC and block storage in the destroy target, or check the depends_on direction
Token expiredReissue under Admin > User Access Tokens in the portal and refresh the env var
CIDR outside the allowed rangeOnly 172.16.0.0/14 or 192.168.0.0/16 are allowed

References