Skip to content

Terraform and OpenTofu on Quake AI

Explanation · Updated Jun 2026

Coming from another cloud?

▸AWS·Stacks

Stackshigh

  • Quake AI offers Heat (legacy OpenStack orchestration) and recommends OpenTofu for new IaC work; EKS uses declarative console/CLI.
  • EKS Auto Mode automates data plane; Quake AI uses OpenTofu modules for infrastructure provisioning.
  • CloudFormation stacks are managed via AWS-specific REST API (e.g., cloudformation.us-east-1.amazonaws.com) requiring AWS SigV4 auth, while Heat (legacy) uses OpenStack Identity API v3 (keystoneauth) and OpenTofu uses the OpenStack provider with application credentials. Migrators notice different endpoint discovery and auth flows.
  • Stacks support StackSets for cross-region/account deployment; Heat has no equivalent. OpenTofu workspaces offer a different multi-environment pattern.
AWS docs ↗
▸Azure·Resource Manager deployment (deployment)

Azure Resource Manager deployment (deployment)high

  • Authoring format differs: ARM templates are JSON documents for Azure Resource Manager deployments, whereas Quake AI offers Heat (legacy, HOT/YAML format) and recommends OpenTofu (HCL) for new infrastructure automation.
  • Deployment target/scope differs: ARM templates can deploy at multiple scopes (resource group, subscription, management group, tenant) via Azure Resource Manager's management layer, while Heat orchestrates within a single OpenStack project/tenant. OpenTofu can target multiple projects via provider configuration.
  • Change-preview behavior differs: ARM supports a built-in “what-if” style preview of changes via Resource Manager deployments, while OpenTofu provides `tofu plan` for change previews. Heat relies on stack update events (legacy workflow).
  • Resource coverage lifecycle differs: ARM templates support Azure resource types exposed by Azure resource providers; OpenTofu covers OpenStack resource types via the OpenStack provider, and Heat (legacy) supports a narrower set via built-in resource plugins.
Azure docs ↗
▸Google Cloud·Deployment Manager

Deployment Managerhigh

  • Uses YAML configurations with optional Jinja2/Python templates expanded server-side; Quake AI offers Heat (legacy, HOT/YAML) and recommends OpenTofu (HCL) for new work.
  • Resource types named as service.v1.resource (e.g., compute.v1.instance) tied to GCP APIs, vs OpenStack prefixed types like OS::Nova::Server.
  • Single integrated GCP service (no separate API/engine processes); Heat has a multi-service architecture (heat-api, heat-engine) but is legacy. OpenTofu runs client-side with no server component.
  • No additional service fee; bills only for deployed GCP resources, same as OpenStack resources billing via provider.
Google Cloud docs ↗

Terraform and OpenTofu on Quake AI

Terraform and OpenTofu use HashiCorp Configuration Language (HCL) to define infrastructure as code. You describe the resources you want (instances, networks, volumes, security groups) in .tf files, and the tool creates, updates, or destroys them to match your declared state. Both tools use the same OpenStack provider and produce identical results on Quake AI.

For a comparison of OpenTofu and Terraform, see IaC on Quake AI. This page focuses on how Terraform and OpenTofu work with Quake AI specifically: provider configuration, authentication, state management, and the resource types available.

The OpenStack provider#

Terraform and OpenTofu interact with Quake AI through the OpenStack provider. The provider translates HCL resource definitions into OpenStack API calls.

Declare the provider in your main.tf:

HCL
terraform {
  required_providers {
    openstack = {
      source  = "terraform-provider-openstack/openstack"
      version = "~> 2.0"
    }
  }
}

provider "openstack" {}

The empty provider "openstack" {} block tells the provider to read credentials from environment variables, which is the recommended approach.

Authentication#

The provider supports two authentication methods. Both use application credentials generated in the Quake AI console.

Source your application credential file before running any Terraform command:

bash
source ~/openrc.sh
terraform plan

The provider reads OS_AUTH_URL, OS_APPLICATION_CREDENTIAL_ID, and OS_APPLICATION_CREDENTIAL_SECRET from the environment. This keeps credentials out of your .tf files and version control.

Explicit provider configuration#

For CI/CD pipelines or environments where sourcing a file is impractical, pass credentials directly:

HCL
provider "openstack" {
  auth_url                      = "https://keystone.rumble.cloud/v3"
  application_credential_id     = var.credential_id
  application_credential_secret = var.credential_secret
}

Use Terraform variables or a secrets manager to inject the values; never hardcode credentials in .tf files.

State management#

Terraform tracks the real-world state of your infrastructure in a state file (terraform.tfstate). This file maps each HCL resource to the corresponding OpenStack resource ID, enabling Terraform to detect drift and plan changes accurately.

Local state (default)#

By default, the state file lives in the working directory. This works for personal projects but breaks down when multiple people or CI pipelines manage the same infrastructure.

Remote state on Quake AI#

Store state in Quake AI object storage for team access and state locking:

HCL
terraform {
  backend "s3" {
    bucket   = "terraform-state"
    key      = "production/terraform.tfstate"
    endpoint = "https://object.us-east-1.rumble.cloud"  # replace with your region
    region   = "us-east-1"                         # us-east-1 | us-east-2 | us-west-1

    skip_credentials_validation = true
    skip_metadata_api_check     = true
    skip_region_validation      = true
    force_path_style            = true
  }
}

Generate S3 credentials through the console (see Create S3 credentials) and export them as AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY before running terraform init.

Common resource types#

The OpenStack provider maps Quake AI services to Terraform resource types. These are the resources you use most frequently:

Compute#

ResourcePurpose
openstack_compute_instance_v2Create and manage virtual machine instances
openstack_compute_keypair_v2Import SSH public keys for instance access
openstack_compute_servergroup_v2Define affinity and anti-affinity placement policies
openstack_images_image_v2 (data source)Look up available OS images by name
openstack_compute_flavor_v2 (data source)Look up instance sizes by name

Network#

ResourcePurpose
openstack_networking_network_v2Create private networks
openstack_networking_subnet_v2Define subnets with CIDR ranges and DNS
openstack_networking_router_v2Create routers for internet and inter-network routing
openstack_networking_router_interface_v2Connect subnets to routers
openstack_networking_floatingip_v2Allocate public IP addresses
openstack_networking_secgroup_v2Create security groups
openstack_networking_secgroup_rule_v2Define firewall rules
openstack_networking_port_v2Create network ports with fixed IPs

Storage#

ResourcePurpose
openstack_blockstorage_volume_v3Create block storage volumes
openstack_compute_volume_attach_v2Attach volumes to instances

Public application entry points#

ResourcePurpose
openstack_networking_port_v2Create a dedicated port for an edge proxy or API gateway instance
openstack_networking_floatingip_v2Allocate a stable public address for the edge instance
openstack_networking_floatingip_associate_v2Associate the public address with the edge instance port
openstack_networking_secgroup_rule_v2Allow HTTP, HTTPS, and restricted administration traffic

Automation (legacy Heat)#

ResourcePurpose
openstack_orchestration_stack_v1Manage existing Heat stacks from OpenTofu

The plan/apply workflow#

OpenTofu/Terraform plan-apply-destroy lifecycleA project moves from init through repeated plan and apply cycles, with destroy as the explicit teardown path

tofu init

tofu plan

tofu apply

edit .tf

tofu destroy

Init

Planned

Applied

Destroyed

Click to zoom
Lifecycle of a Terraform/OpenTofu project: init once, then loop plan and apply; destroy is the explicit teardown

Each infrastructure change follows the same cycle:

  1. terraform init: download the OpenStack provider plugin and configure the backend. Run once per project or when you change providers.
  2. terraform plan: compare the declared state in your .tf files against the real state in terraform.tfstate. Terraform prints a diff showing what it creates, modifies, or destroys.
  3. terraform apply: execute the planned changes. Terraform prompts for confirmation before making any API calls.
  4. terraform destroy: tear down all resources managed by the current configuration. Use this to clean up test environments.

Review the plan output before applying. Terraform distinguishes between in-place updates (modifying a resource's attributes) and replacements (destroying and recreating a resource). Replacements can cause downtime; look for forces replacement in the plan output.

Project structure#

A typical Quake AI Terraform project splits configuration across files by concern:

.
├── main.tf           # Provider configuration
├── variables.tf      # Input variables
├── data.tf           # Data sources (images, networks, flavors)
├── compute.tf        # Instance definitions
├── network.tf        # Networks, subnets, routers, security groups
├── storage.tf        # Volumes and attachments
├── outputs.tf        # Output values (IPs, IDs)
└── terraform.tfvars  # Variable values (not committed to version control)

Terraform loads all .tf files in the working directory automatically; the file names are for human organization, not tool requirements.

Operational best practices#

Pin the provider version. Use version = "~> 2.0" to allow patch updates while preventing breaking changes. Run terraform init -upgrade when you want to pick up a new minor version.

Use variables for everything that changes between environments. Instance counts, flavors, network CIDRs, and image names should be variables. Hardcoded values create drift between staging and production.

Use terraform.tfvars for environment-specific values. Keep one .tfvars file per environment and pass it with terraform plan -var-file=production.tfvars.

Never commit terraform.tfstate or .tfvars files. The state file contains resource IDs and may contain sensitive attributes. The .tfvars file may contain credentials. Add both to .gitignore.

Use anti-affinity server groups. When deploying multiple instances of the same role, place them in a soft-anti-affinity server group. This distributes instances across physical hosts for fault tolerance.

Tag resources consistently. Use the tags attribute on networks, ports, and other resources that support it. Tags make it possible to identify Terraform-managed resources in the console and CLI.

Further reading#

On this platform:

External resources:

Related content

Pages

deployment

Templates

Was this page helpful?