Terraform provider

Describe your servers, keys, firewalls and private networks in code with the kasadaai/kasada provider.

Configure the provider

main.tf
terraform {
  required_providers {
    kasada = {
      source  = "kasadaai/kasada"
      version = "~> 0.1"
    }
  }
}

provider "kasada" {
  # or set KHOST_TOKEN in the environment
  token = var.khost_token
}

A complete example

servers.tf
resource "kasada_ssh_key" "laptop" {
  name       = "laptop"
  public_key = file("~/.ssh/id_ed25519.pub")
}

resource "kasada_network" "backend" {
  name   = "backend"
  region = "us-east"
  cidr   = "10.10.0.0/24"
}

resource "kasada_firewall" "web" {
  name = "web"

  rule {
    direction   = "in"
    protocol    = "tcp"
    ports       = "22"
    sources     = ["203.0.113.4/32"]
    action      = "accept"
    description = "SSH from office"
  }

  rule {
    direction = "in"
    protocol  = "tcp"
    ports     = "80,443"
    sources   = ["0.0.0.0/0", "::/0"]
    action    = "accept"
  }
}

resource "kasada_server" "web" {
  count        = 2
  name         = "web-${count.index + 1}"
  plan         = "K2"
  image        = "ubuntu-24.04"
  region       = "us-east"
  ssh_key_ids  = [kasada_ssh_key.laptop.id]
  firewall_ids = [kasada_firewall.web.id]
  network_ids  = [kasada_network.backend.id]
  backups      = true
  user_data    = file("cloud-config.yaml")
  labels       = { role = "web" }
}

output "web_ips" {
  value = kasada_server.web[*].ipv4_address
}
bash
export KHOST_TOKEN=khst_xxxxxxxxxxxxxxxxxxxxxxxx
terraform init
terraform plan
terraform apply

Resources

ResourceKey arguments
kasada_servername, plan, image, region, ssh_key_ids, user_data, backups, ipv6_only, firewall_ids, network_ids, labels
kasada_ssh_keyname, public_key
kasada_firewallname, rule blocks (direction, protocol, ports, sources, action, description)
kasada_networkname, region, cidr

Server attributes include id, status, ipv4_address, ipv6_address and hostname (for example vm-ab12cd34.us-east.kasadavps.net). Regions are us-east (US East, the default), eu-central (EU Central) and us-west (US West).

Changes that replace a server

Changing image or user_data rebuilds the server (erasing its disk). Changing plan to a bigger plan resizes it in place; a smaller plan isn't possible.
Charges are hourly, so terraform destroy stops billing for those servers straight away.