Skip to content

How to migrate from Linode (Akamai) to Quake AI with OpenTofu

Migration · Updated Jun 2026

Coming from another cloud?

▸Linode·s (Compute Instances), Block Storage Volumes, VPC, Cloud Firewalls, NodeBalancers

Linodes (Compute Instances)high

  • Provisioned via the Linode API v4 (/v4/linode/instances) instead of OpenStack Nova /v2.1/servers; auth is a Personal Access Token rather than a Keystone token.
  • Plan selection is fixed (Shared, Dedicated, High Memory, Premium, GPU, Accelerated) with predefined vCPU/RAM/storage; OpenStack flavors can be cloud-defined.
  • Billing is hourly with a monthly cap per plan; powered-off Linodes continue to bill until deleted, unlike pause/suspend semantics common in OpenStack stop-billing setups.
  • Distribution images and StackScripts are first-class; OpenStack uses Glance images and arbitrary userdata.
Linode docs ↗

Block Storage Volumeshigh

  • Managed via /v4/volumes on the Linode API; OpenStack uses Cinder /v3/{project_id}/volumes.
  • Volumes are region-scoped and cannot move between data centers without detach + recreate; OpenStack Cinder volumes are likewise AZ-scoped but the explicit no-cross-region migration is documented at Akamai.
  • Size increases only (no shrink); same restriction exists on OpenStack but Linode enforces it as a hard API rule.
  • Throughput and IOPS limits are plan-implicit and not separately tunable per volume.
Linode docs ↗

VPChigh

  • VPCs are region-scoped and isolate Linodes from the public internet and from other customers; OpenStack networks are project-scoped Neutron networks.
  • A VPC contains one or more subnets, each with a CIDR block defined at create time; routing between subnets is implicit within the VPC.
  • Linodes attach to a VPC by configuration interface rather than via Neutron ports; trunking is not the same model.
  • VLANs and VPCs are distinct products; OpenStack collapses these into Neutron network types (vlan, vxlan, geneve).
Linode docs ↗

Cloud Firewallshigh

  • Cloud Firewalls are a managed stateful firewall service attached to Linodes and NodeBalancers; OpenStack uses Neutron security groups per port.
  • Rules are evaluated as inbound and outbound policy sets per firewall, not as additive security group memberships.
  • Default policy can be set to ACCEPT or DROP per direction at the firewall level; OpenStack security groups default-deny inbound.
  • Cloud Firewalls are free; OpenStack security groups are also free but have different rule semantics (port + protocol + remote group).
Linode docs ↗

NodeBalancershigh

  • NodeBalancers are a managed L4/L7 load balancer product. Quake AI workloads use a self-managed reverse proxy or Kubernetes LoadBalancer Service.
  • A NodeBalancer contains one or more port and protocol configurations plus backend nodes. Self-managed Quake AI edges define listeners and upstreams in proxy or ingress configuration.
  • NodeBalancers configure TLS termination with an inline certificate and key. Quake AI users manage TLS on the self-managed edge.
  • Linode prices NodeBalancers separately. Size the compute used by a self-managed Quake AI edge instead.
Linode docs ↗

How to migrate from Linode (Akamai) to Quake AI with OpenTofu

Linode (now branded Akamai Cloud Computing) and Quake AI attract similar audiences: cost-conscious engineers who self-manage infrastructure. If you already use Terraform or OpenTofu with the linode provider, 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:

ConceptLinode (linode provider)Quake AI (OpenStack)
Providerlinode/linodeterraform-provider-openstack/openstack
Compute Instancelinode_instanceopenstack_compute_instance_v2
Plang6-nanode-1, g6-standard-2, g6-dedicated-4, etc.s1a.small, m2a.large, c2a.xlarge, r2a.large, etc.
SSH keylinode_sshkeyopenstack_compute_keypair_v2
Reserved IP / Floating IP(Reserved IPs managed in Cloud Manager)openstack_networking_floatingip_v2
Cloud Firewalllinode_firewallopenstack_networking_secgroup_v2 + rules
Block Storage Volumelinode_volumeopenstack_blockstorage_volume_v3
VPClinode_vpc + linode_vpc_subnetopenstack_networking_network_v2 + openstack_networking_subnet_v2
NodeBalancerlinode_nodebalancer + linode_nodebalancer_config + linode_nodebalancer_nodeSelf-managed reverse proxy or API gateway instance with a floating IP
Object Storage bucketlinode_object_storage_bucketopenstack_objectstorage_container_v1 (Swift) or S3 client via aws_s3_bucket against the Quake AI endpoint
LKE Clusterlinode_lke_clusteropenstack_containerinfra_cluster_v1 (Magnum) is the primary equivalent; self-managed RKE2 or k3s on Nova is the alternative. See migrate from LKE.
ImageLinode public images (linode/ubuntu24.04, etc.)Quake AI images (Ubuntu-24.04, etc.)

Resource translation examples#

Compute Instance#

Linode:

HCL
resource "linode_instance" "web" {
  label  = "web-1"
  region = "us-east"
  type   = "g6-standard-2"
  image  = "linode/ubuntu24.04"

  authorized_keys = [linode_sshkey.main.ssh_key]
}

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"
  }
}

Cloud Firewall to security group#

Linode:

HCL
resource "linode_firewall" "web" {
  label = "web-firewall"

  inbound_policy  = "DROP"
  outbound_policy = "ACCEPT"

  inbound {
    label    = "allow-http"
    action   = "ACCEPT"
    protocol = "TCP"
    ports    = "80"
    ipv4     = ["0.0.0.0/0"]
  }

  inbound {
    label    = "allow-https"
    action   = "ACCEPT"
    protocol = "TCP"
    ports    = "443"
    ipv4     = ["0.0.0.0/0"]
  }

  linodes = [linode_instance.web.id]
}

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.

Block Storage Volume#

Linode:

HCL
resource "linode_volume" "data" {
  label  = "data-vol"
  region = "us-east"
  size   = 50
}

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#

Linode bundles a VPC and a single subnet through two resources; Quake AI exposes network and subnet independently.

Linode:

HCL
resource "linode_vpc" "main" {
  label  = "main-vpc"
  region = "us-east"
}

resource "linode_vpc_subnet" "private" {
  vpc_id = linode_vpc.main.id
  label  = "private"
  ipv4   = "10.0.0.0/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
}

NodeBalancer to a self-managed edge proxy#

Replace a NodeBalancer 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 provides a Caddy-based starting point, while the API Gateway template adds API routing and policy controls.

Linode:

HCL
resource "linode_nodebalancer" "web" {
  label  = "web-lb"
  region = "us-east"
}

resource "linode_nodebalancer_config" "http" {
  nodebalancer_id = linode_nodebalancer.web.id
  port            = 80
  protocol        = "tcp"
  algorithm       = "roundrobin"
}

resource "linode_nodebalancer_node" "web1" {
  nodebalancer_id = linode_nodebalancer.web.id
  config_id       = linode_nodebalancer_config.http.id
  label           = "web-1"
  address         = "${linode_instance.web.private_ip_address}:80"
  weight          = 100
}

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 Linode state. Run tofu show (or terraform show) to document current resources.
  2. Map Linode plans to Quake AI flavors. Compare vCPU/RAM specs between Linode plan SKUs and Quake AI flavors. See migrate from Linode (compute) for a per-family mapping.
  3. Rewrite the provider block. Replace linode/linode 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 Linode Object Storage.
  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 Linode#

  • Authentication. The Linode provider takes a single API token. The OpenStack provider uses Keystone with username, password, project, and domain set via environment variables (or application credentials, which are the recommended path for CI).
  • Networking model. Linode auto-assigns a public IPv4 to every Linode. Quake AI uses Floating IPs that you allocate explicitly and associate with a port.
  • Firewall vs security group. Linode Cloud Firewalls are standalone resources attached to a Linode or NodeBalancer. Quake AI security groups attach to ports/instances with individual rules as separate resources.
  • Object storage. Both Linode and Quake AI expose S3-compatible object storage; for IaC, see the S3 Storage with ACLs template.
  • Managed Kubernetes. Map linode_lke_cluster to openstack_containerinfra_cluster_v1 (Magnum) for the closest LKE-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 LKE.
  • Pricing model. Linode 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. Compare plan and add-on costs in the Akamai pricing page and the Quake AI dashboard before you commit.

See also#

Usage Guidelines

The sample code, software libraries, command line tools, proofs of concept, templates, and other related technology on this page (including any of the foregoing that is provided by Quake AI personnel) is provided to you as Quake AI Content under the Quake AI Customer Agreement, or the relevant written agreement between you and Quake AI (whichever applies). Do not use this Quake AI Content in your production accounts, or on production or other critical data. You are responsible for testing, securing, and optimizing the Quake AI Content (such as sample code) as appropriate for production grade use based on your specific quality control practices and standards. Deploying Quake AI Content may incur Quake AI charges for creating or using Quake AI chargeable resources, such as running Compute instances or storing data in Object Storage. Your use is also subject to the Acceptable Use Policy.

Comparisons to third-party providers in this material reflect publicly documented behavior as of the validation date below. Pricing, quotas, service limits, and feature availability change frequently on every cloud. Verify provider-specific claims against the provider's own current documentation before relying on them for a procurement, architecture, or migration decision.

For the full policy, see Usage Guidelines.

Last validated: 19.06.2026

Was this page helpful?