Manage VMs with Terraform¶
Terraform can create, resize and delete VMs through the console's IaC API
(/api/iac/vms) over HTTPS. Nothing is installed on the console or the
hosts. Terraform authenticates with an API key.
Before you start¶
- Terraform 1.3 or later, on a machine that can reach the console's URL.
- An API key with Full scope, owned by a user who can manage VMs (for example Super Admin, Tenant Admin or Compute Admin). Use an expiry, and treat the key like a password.
- A template that already exists in the Content Library, for example
rocky9.
Configuration¶
This uses the community
Mastercard/restapi
provider, so there's nothing to build.
providers.tf:
terraform {
required_version = ">= 1.3"
required_providers {
restapi = {
source = "Mastercard/restapi"
version = "~> 1.20"
}
}
}
provider "restapi" {
uri = var.mfcloud_url
insecure = var.mfcloud_insecure
write_returns_object = true
id_attribute = "vm_name"
headers = {
X-API-Key = var.mfcloud_api_key
Content-Type = "application/json"
}
create_method = "POST"
update_method = "PUT"
destroy_method = "DELETE"
}
variables.tf:
variable "mfcloud_url" {
type = string
description = "Console URL, e.g. https://console.example.com"
}
variable "mfcloud_api_key" {
type = string
sensitive = true
}
variable "mfcloud_insecure" {
type = bool
default = false # true only for a self-signed console certificate
}
variable "vms" {
type = map(object({
template_name = string
vcpus = number
memory_mb = number
disk_gb = optional(number, 20)
target_host = optional(string, "auto")
network_name = optional(string, "default")
os_type = optional(string, "linux") # linux | windows
}))
default = {}
}
main.tf:
resource "restapi_object" "vm" {
for_each = var.vms
path = "/api/iac/vms"
id_attribute = "vm_name"
data = jsonencode({
vm_name = each.key
template_name = each.value.template_name
vcpus = each.value.vcpus
memory_mb = each.value.memory_mb
disk_gb = each.value.disk_gb
target_host = each.value.target_host
network_name = each.value.network_name
os_type = each.value.os_type
})
}
output "vms" {
value = { for name, obj in restapi_object.vm : name => jsondecode(obj.api_response) }
}
terraform.tfvars (keep it out of version control):
mfcloud_url = "https://console.example.com"
mfcloud_api_key = "paste-your-key"
vms = {
"tf-web-01" = { template_name = "rocky9", vcpus = 2, memory_mb = 2048, disk_gb = 30 }
"tf-web-02" = { template_name = "rocky9", vcpus = 2, memory_mb = 2048, disk_gb = 30 }
}
Run it¶
terraform init
terraform plan
terraform apply
terraform output vms # placement, sizing and guest IP as the console reports them
terraform destroy deletes the VMs.
Things to know¶
- Create is asynchronous.
applyreturns once the console has accepted and recorded the VM; the guest finishes building in the background. Watch Recent Tasks in the console. The guest IP appears interraform outputonce the guest agent reports it. - Placement.
target_host = "auto"lets the console place the VM, the same as Automatic in the deploy dialog. Set a host IP to pin it. - Changed in place:
vcpus,memory_mb,network_name. -
Needs a replace:
template_name,disk_gb,target_host,os_type. The console ignores a change to one of these on an existing VM, so replace the VM explicitly: -
Quotas and protection apply. Creates go through the same quota, tenant limit and license checks as the console. A VM with delete protection on refuses
destroy. - State. For team use, keep state in a remote backend (S3, Terraform Cloud and so on), not on a laptop.