# How to migrate from Vultr to Quake AI with OpenTofu

Source: https://docs.quake.ai/docs/automation/migration/from-vultr
Markdown: https://docs.quake.ai/docs/automation/migration/from-vultr.md

---

# How to migrate from Vultr to Quake AI with OpenTofu

Vultr and Quake AI attract similar audiences: cost-conscious engineers who self-manage infrastructure. If you already use Terraform or OpenTofu with the [vultr provider](https://registry.terraform.io/providers/vultr/vultr/latest), migrating to Quake AI is a provider swap with resource remapping.

## Conceptual mapping

Both platforms offer similar primitives, but the APIs and resource names differ:

| Concept | Vultr (vultr provider) | Quake AI (OpenStack) |
|---|---|---|
| Provider | `vultr/vultr` | `terraform-provider-openstack/openstack` |
| Compute Instance | `vultr_instance` | `openstack_compute_instance_v2` |
| Bare Metal | `vultr_bare_metal_server` | No equivalent (use `openstack_compute_instance_v2` on the closest virtualized flavor). |
| Plan | `vc2-1c-1gb`, `vhf-2c-4gb`, `vhp-4c-8gb`, etc. | `s1a.small`, `m2a.large`, `c2a.xlarge`, `r2a.large`, etc. |
| SSH key | `vultr_ssh_key` | `openstack_compute_keypair_v2` |
| Reserved IP / Floating IP | `vultr_reserved_ip` | `openstack_networking_floatingip_v2` |
| Firewall Group | `vultr_firewall_group` + `vultr_firewall_rule` | `openstack_networking_secgroup_v2` + `openstack_networking_secgroup_rule_v2` |
| Block Storage | `vultr_block_storage` | `openstack_blockstorage_volume_v3` |
| VPC 2.0 | `vultr_vpc2` | `openstack_networking_network_v2` + `openstack_networking_subnet_v2` |
| Load Balancer | `vultr_load_balancer` (single resource with inline forwarding rules) | Self-managed reverse proxy or API gateway instance with a floating IP |
| Object Storage | `vultr_object_storage` (subscription) | `openstack_objectstorage_container_v1` (Swift) or S3 client via `aws_s3_bucket` against the Quake AI endpoint |
| VKE Cluster | `vultr_kubernetes` | `openstack_containerinfra_cluster_v1` (Magnum) is the primary equivalent; self-managed RKE2 or k3s on Nova is the alternative. See [migrate from VKE](/docs/kubernetes/migration/migrate-from-vke). |
| Image | Vultr OS list (`387` for Ubuntu 22.04, etc.) | Quake AI images (`Ubuntu-24.04`, etc.) |

## Resource translation examples

### Compute Instance

Vultr:

```hcl
resource "vultr_instance" "web" {
  label    = "web-1"
  region   = "ewr"
  plan     = "vc2-2c-4gb"
  os_id    = 1743
}
```

Quake AI:

```hcl
resource "openstack_compute_instance_v2" "web" {
  name        = "web-1"
  image_name  = "Ubuntu-24.04"
  flavor_name = "m2a.large"

  key_pair = openstack_compute_keypair_v2.main.name

  network {
    name = "PublicStatic"
  }
}
```

### Firewall Group to security group

Vultr:

```hcl
resource "vultr_firewall_group" "web" {
  description = "web-firewall"
}

resource "vultr_firewall_rule" "http" {
  firewall_group_id = vultr_firewall_group.web.id
  protocol          = "tcp"
  ip_type           = "v4"
  subnet            = "0.0.0.0"
  subnet_size       = 0
  port              = "80"
}

resource "vultr_firewall_rule" "https" {
  firewall_group_id = vultr_firewall_group.web.id
  protocol          = "tcp"
  ip_type           = "v4"
  subnet            = "0.0.0.0"
  subnet_size       = 0
  port              = "443"
}
```

Quake AI:

```hcl
resource "openstack_networking_secgroup_v2" "web" {
  name = "web-secgroup"
}

resource "openstack_networking_secgroup_rule_v2" "http" {
  security_group_id = openstack_networking_secgroup_v2.web.id
  direction         = "ingress"
  ethertype         = "IPv4"
  protocol          = "tcp"
  port_range_min    = 80
  port_range_max    = 80
  remote_ip_prefix  = "0.0.0.0/0"
}

resource "openstack_networking_secgroup_rule_v2" "https" {
  security_group_id = openstack_networking_secgroup_v2.web.id
  direction         = "ingress"
  ethertype         = "IPv4"
  protocol          = "tcp"
  port_range_min    = 443
  port_range_max    = 443
  remote_ip_prefix  = "0.0.0.0/0"
}
```

Apply the security group to instances via the `security_groups` argument on `openstack_compute_instance_v2`. Note that Vultr Firewall Groups attach to instances by reference (no IaC join resource); Neutron security groups attach via the `security_groups` argument on the compute instance.

### Block Storage

Vultr:

```hcl
resource "vultr_block_storage" "data" {
  label    = "data-vol"
  size_gb  = 50
  region   = "ewr"
}
```

Quake AI:

```hcl
resource "openstack_blockstorage_volume_v3" "data" {
  name = "data-vol"
  size = 50
}
```

Volume attachment and formatting happen through `openstack_compute_volume_attach_v2` and cloud-init, respectively.

### VPC 2.0

Vultr VPC 2.0 is a single resource that bundles network and CIDR; Quake AI exposes network and subnet independently.

Vultr:

```hcl
resource "vultr_vpc2" "main" {
  region         = "ewr"
  description    = "main-vpc"
  ip_type        = "v4"
  ip_block       = "10.0.0.0"
  prefix_length  = 24
}
```

Quake AI:

```hcl
resource "openstack_networking_network_v2" "main" {
  name = "main-network"
}

resource "openstack_networking_subnet_v2" "private" {
  name       = "private"
  network_id = openstack_networking_network_v2.main.id
  cidr       = "10.0.0.0/24"
  ip_version = 4
}
```

### Vultr Load Balancer to a self-managed edge proxy

Replace a Vultr Load Balancer with a Caddy, Nginx, HAProxy, or API gateway instance on a private network. Attach one floating IP to the edge instance, terminate TLS there, and route requests to backend instance ports over private addresses. The [Edge Reverse Proxy template](/resources/iac-templates/edge-reverse-proxy) provides a Caddy-based starting point, while the [API Gateway template](/resources/iac-templates/api-gateway) adds API routing and policy controls.

Vultr:

```hcl
resource "vultr_load_balancer" "web" {
  region              = "ewr"
  label               = "web-lb"
  balancing_algorithm = "roundrobin"

  forwarding_rules {
    frontend_protocol = "tcp"
    frontend_port     = 80
    backend_protocol  = "tcp"
    backend_port      = 80
  }

  attached_instances = [vultr_instance.web.id]
}
```

Model the replacement in OpenTofu as:

- One `openstack_compute_instance_v2` edge instance running the proxy.
- One `openstack_networking_port_v2` on the application subnet.
- One `openstack_networking_floatingip_v2` associated with the edge port.
- Security group rules for ports 80 and 443 on the edge, with backend ports restricted to the edge instance's private address.
- Proxy configuration that lists each backend private address and its health-check path.

## Migration workflow

1. **Export your Vultr state.** Run `tofu show` (or `terraform show`) to document current resources.
2. **Map Vultr plans to Quake AI flavors.** Compare vCPU/RAM specs between Vultr plan SKUs and Quake AI flavors. See [migrate from Vultr (compute)](/docs/compute/migration/migrate-from-vultr) for a per-family mapping.
3. **Rewrite the provider block.** Replace `vultr/vultr` with `terraform-provider-openstack/openstack`. Authenticate via standard `OS_*` environment variables (or `cloud:` blocks).
4. **Translate resources.** Start with a single instance and security group, then add networking and storage.
5. **Set up data migration.** For volumes, use `rsync` or `scp` to copy data between instances. For S3-compatible storage, use `rclone`. See [migrate from Vultr Object Storage](/docs/object/migration/migrate-from-vultr).
6. **Test with `tofu plan`.** Validate the configuration before applying.
7. **Apply and verify.** Deploy on Quake AI and confirm services are reachable.

## Key differences from Vultr

- **Authentication.** The Vultr provider takes a single API key. The OpenStack provider uses Keystone with username, password, project, and domain set via environment variables (or [application credentials](/docs/identity/how-to/create-application-credential), which are the recommended path for CI).
- **Networking model.** Vultr auto-assigns a public IPv4 to every instance. Quake AI uses Floating IPs that you allocate explicitly and associate with a port.
- **Firewall vs security group.** Vultr Firewall Groups are account-level standalone resources attached to instances by reference. Quake AI security groups attach to ports/instances with individual rules as separate resources.
- **Object storage.** Both Vultr and Quake AI expose S3-compatible object storage; for IaC, see the [S3 Storage with ACLs template](/resources/iac-templates/s3-storage-acl).
- **Managed Kubernetes.** Map `vultr_kubernetes` to `openstack_containerinfra_cluster_v1` (Magnum) for the closest VKE-like experience; the platform provides the cluster template, control plane, and load-balanced API endpoint. If you need a custom CNI, kubelet flags, CRI, or a Kubernetes version outside the template catalog, provision Nova instances with OpenTofu and bootstrap with `kubeadm`, `k3s`, or `rke2` instead. See [migrate from VKE](/docs/kubernetes/migration/migrate-from-vke).
- **Pricing model.** Vultr bills hourly with a monthly cap; Quake AI uses fixed monthly plans tied to a resource tier, with a small list of per-resource add-ons. See the [pricing model](/docs/platform#pricing). Compare plan and add-on costs in the [Vultr pricing page](https://www.vultr.com/pricing/) and the Quake AI dashboard before you commit.

## See also

- [Migration Explorer](/resources/migration): interactive service comparison across cloud providers
- [IaC on Quake AI](/docs/automation/concepts/iac-comparison)
- [Simple VM template](/resources/iac-templates/simple-vm)
- [Infrastructure Templates](/resources/iac-templates)
- [How to get started with Infrastructure as Code on Quake AI](/docs/automation/how-to/getting-started-iac)
