Authoring IaC templates for Quake AI
Coming from another cloud?
▸AWS·Stacks
Stacks
- 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.
▸Azure·Resource Manager deployment (deployment)
Azure Resource Manager deployment (deployment)
- 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.
▸Google Cloud·Deployment Manager
Deployment Manager
- 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.
Authoring IaC templates for Quake AI
You write OpenTofu or Terraform templates against the OpenStack provider the same way you would on any Antelope-era cloud. Quake AI adds a small, fixed catalog of flavors, networks, and volume types, a second AWS provider path for S3-compatible object storage, and Magnum behaviors that differ from generic OpenStack tutorials. This page collects those rules so a new template matches the infrastructure template library and passes CI validation.
If you are new to IaC on the platform, start with Get started with IaC and IaC on Quake AI. If you know OpenStack but not Quake AI branding, read How Quake AI uses OpenStack first.
What is different on Quake AI#
Quake AI runs Antelope (2023.1). The OpenStack provider resource names (openstack_compute_instance_v2, openstack_networking_port_v2, and the rest) are standard. The differences show up in catalog literals (which flavor and network names resolve), auth (application credentials plus separate S3 keys), and platform limits (Magnum trust rules and no managed VPN).
The platform keeps the decision space small on purpose: 26 public flavors in four families, one boot volume type, two shared external networks, and project-scoped roles instead of IAM policies. Templates that hard-code those literals correctly are easier to validate and less likely to fail tofu plan in a new project.
Authentication and providers#
OpenStack provider#
Authenticate with application credentials, not username and password in HCL. Export the variables from the file you generate in Generate app credentials:
export OS_AUTH_URL="https://keystone.rumble.cloud/v3"
export OS_AUTH_TYPE="v3applicationcredential"
export OS_APPLICATION_CREDENTIAL_ID="YOUR_APP_CREDENTIAL_ID"
export OS_APPLICATION_CREDENTIAL_SECRET="YOUR_APP_CREDENTIAL_SECRET"
export OS_REGION_NAME="us-east-1"Declare an empty provider block and keep secrets out of .tf files:
terraform {
required_providers {
openstack = {
source = "terraform-provider-openstack/openstack"
version = "~> 2.0"
}
}
}
provider "openstack" {}Regions: us-east-1, us-east-2, us-west-1. Parameterize the region in endpoint examples when your template README shows object storage URLs.
AWS provider for object storage#
Object storage buckets use the AWS provider pointed at Quake AI's S3-compatible endpoint. The OpenStack application credential does not satisfy the AWS provider. Mint EC2-compatible credentials with the OpenStack CLI and export AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY before tofu plan. The S3 storage template README documents the bootstrap; mirror that pattern in any template that creates buckets.
provider "aws" {
region = var.s3_region
skip_credentials_validation = true
skip_metadata_api_check = true
skip_requesting_account_id = true
endpoints {
s3 = var.s3_endpoint
}
}Catalog literals#
These values come from the live platform catalog. Wrong defaults produce empty data sources on tofu plan even when tofu validate passes.
| Literal | Use in templates | Common mistake |
|---|---|---|
| Image | Ubuntu-24.04 (hyphenated Glance name) | Ubuntu 24.04 with a space |
| Flavors | m2a.*, c2a.*, r2a.*, s1a.* only | Fabricated names or other clouds' size IDs |
| External network | PublicEphemeral or PublicStatic | PublicNetwork, ext-net, or external |
| Volume type | Boot from Cinder volume; platform storage is NVMe (Flash_Premium) | Picking a volume type that does not exist in the project |
| Object endpoint | https://object.{region}.rumble.cloud | Global s3.* hostnames that do not match the region |
Link flavor choice to Compute flavors and capacity planning. Shared vCPU sizes (s1a.*) suit demos; dedicated families (m2a, c2a, r2a) suit production workloads.
External network policy#
Quake AI exposes two shared external networks. Pick the default in variables.tf based on what the template teaches:
| Class | Default | Use when |
|---|---|---|
| Throwaway / quickstart-aligned | PublicEphemeral | Single-VM demos, labs, or templates that mirror the quickstart ephemeral path |
| Production / multi-tier | PublicStatic | Persisted floating IPs, edge reverse proxies, multi-tier stacks, and workloads that must retain an address across instance rebuilds |
Readers can override either value in terraform.tfvars. Document which class your template belongs to in the README.
Recommended template skeleton#
Most compute templates in the library follow the same Neutron shape: private network, router on the external network, security group rules, port with security groups attached by ID, boot-from-volume instance, optional floating IP.
data "openstack_images_image_v2" "os" {
name = var.image_name
most_recent = true
}
data "openstack_networking_network_v2" "external" {
name = var.external_network
}
resource "openstack_networking_network_v2" "private" {
name = "${var.instance_name}-net"
admin_state_up = true
}
resource "openstack_networking_subnet_v2" "private" {
network_id = openstack_networking_network_v2.private.id
cidr = var.private_cidr
ip_version = 4
}
resource "openstack_networking_router_v2" "main" {
external_network_id = data.openstack_networking_network_v2.external.id
}
resource "openstack_networking_router_interface_v2" "private" {
router_id = openstack_networking_router_v2.main.id
subnet_id = openstack_networking_subnet_v2.private.id
}
resource "openstack_networking_secgroup_v2" "app" {
name = "${var.instance_name}-sg"
}
resource "openstack_networking_port_v2" "app" {
network_id = openstack_networking_network_v2.private.id
security_group_ids = [openstack_networking_secgroup_v2.app.id]
depends_on = [openstack_networking_router_interface_v2.private]
}
resource "openstack_compute_instance_v2" "app" {
flavor_name = var.flavor_name
key_pair = var.key_name
block_device {
uuid = data.openstack_images_image_v2.os.id
source_type = "image"
destination_type = "volume"
volume_size = 20
boot_index = 0
delete_on_termination = true
}
network {
port = openstack_networking_port_v2.app.id
}
}
resource "openstack_networking_floatingip_v2" "app" {
pool = var.external_network
}
resource "openstack_networking_floatingip_associate_v2" "app" {
floating_ip = openstack_networking_floatingip_v2.app.address
port_id = openstack_networking_port_v2.app.id
}Conventions embedded in that skeleton:
- Attach security groups to the port with
security_group_ids = [....id]. Avoidsecurity_groups = [....name]on the instance; Nova name lookup can match multiple groups after partial applies. - Prefix security group and network resource names with
var.instance_nameor a dedicated prefix variable so repeated applies do not collide with orphaned groups. - Use
openstack_networking_floatingip_associate_v2, not the deprecatedopenstack_compute_floatingip_associate_v2resource. - Wait for the router interface before creating ports that need routing (
depends_onas shown).
The simple-vm template in iac/templates/simple-vm/ is the canonical reference implementation.
Variables, secrets, and cloud-init#
Standard variables#
Expose a consistent surface so readers can reuse terraform.tfvars patterns across templates:
| Variable | Required | Typical default |
|---|---|---|
key_name | Yes | none (must exist in the project) |
image_name | No | Ubuntu-24.04 |
flavor_name (or tier-specific flavors) | No | size appropriate to the workload |
external_network | No | per network policy table above |
private_cidr | No | unused /24 in the project |
instance_name | No | template slug |
Document every variable from variables.tf on the template reference page Parameters table.
SSH keypairs#
Require an existing project keypair via var.key_name. Do not create openstack_compute_keypair_v2 in new templates unless the template explicitly owns key lifecycle and the README states that the private key lands in Terraform state. Prefer the import-key flow from Add an SSH key.
Secrets#
Never commit passwords, API keys, or credential defaults in HCL. Accept secrets through terraform.tfvars (gitignored), CI secret stores, or generated values on the instance via cloud-init.
cloud-init and templatefile#
Use templatefile() for user-data. Do not pass computed resource attributes (for example a floating IP address) into templatefile() variables when that creates a dependency cycle; render those values on the instance or split the bootstrap script.
Platform quirks for template authors#
| Area | What to encode in templates |
|---|---|
| Public application entry points | Attach a floating IP to a self-managed reverse proxy or API gateway instance. Use the Edge Reverse Proxy, API Gateway, or Edge WAF template as a starting point. |
| Kubernetes (Magnum) | Magnum provisions cluster infrastructure; you operate the control plane. Application credentials cannot satisfy Magnum trust delegation; password-scoped sessions are required for openstack coe cluster create. See Kubernetes FAQ. Self-managed Kubernetes on Nova via OpenTofu is the path documented for new clusters in IaC comparison. |
| Heat | CLI validation uses openstack orchestration template validate, not openstack stack template validate. |
| VPN | No managed VPNaaS. Use the private network + VPN template or your own WireGuard stack. |
| Volume backups | Cinder backup creation is not available; use snapshots or clones for data protection callouts in README prose. |
| Quotas | CLI quota output uses names like public_ip; older docs may say floatingip. Size templates against Resource tiers. |
| Authorization | admin, member, and reader at project scope only. Split environments by project, not by IAM-style resource policies. |
For the full OpenStack mapping and Console naming, see How Quake AI uses OpenStack.
Validation expectations#
Every template in the library passes tofu validate in CI before it ships. That check confirms the HCL parses and matches the provider schema. It does not mean the template was applied in your project or that your quotas allow the default flavors.
Treat validated OpenTofu templates as a correct starting point. Run tofu plan in your project, adjust flavors and counts for your tier, then apply. For the full validation program, see How the platform validates its content.
See also#
Related content
Pages
How-tos
How to add a block volume to a template
Automation
How to customize a template's image and flavor
Automation
How to debug Terraform errors
Automation
How to deploy a multi-tier application with Terraform
Automation
How to deploy an application to a Quake AI VM from CI
Automation
How to deploy VMs with Terraform (simple example)
Automation
How to emulate a branchable Postgres workflow
Automation
How to integrate OpenTofu with CI/CD
Automation
How to launch a Windows Server VM
Compute
How to manage multiple environments with OpenTofu
Automation
How to manage OpenTofu state with Quake AI S3
Automation
How to parameterize a template with a tfvars file
Automation
How to restore PostgreSQL from a self-managed-postgres backup
Automation
Tutorials
Explanations
Overviews
migration
How to migrate from AWS CloudFormation to OpenTofu on Quake AI
Automation
How to migrate from Docker Compose to OpenTofu on Quake AI
Automation
How to migrate from Hetzner Cloud to Quake AI with OpenTofu
Automation
How to migrate from Linode (Akamai) to Quake AI with OpenTofu
Automation
How to migrate from Vultr to Quake AI with OpenTofu
Automation
Migrate a Docker container app from AWS to Quake AI
Compute
Migration Guides
Automation
deployment
Deploy a private container registry with OpenTofu
Automation
Deploy a self-hosted git forge and CI with OpenTofu
Automation
Deploy an inference gateway with OpenTofu
Automation
Deploy the audio post-production worker template with OpenTofu
Automation
Deploy the CPU render-farm worker pool template with OpenTofu
Automation
Deploy the Creator-AI inference worker template with OpenTofu
Automation
Deploy the development environment template with OpenTofu
Automation
Deploy the full-stack application template with OpenTofu
Automation
Deploy the Kubernetes cluster bootstrap template with OpenTofu
Automation
Deploy the live RTMP/SRT ingest and restream template with OpenTofu
Automation
Deploy the monitoring stack template with OpenTofu
Automation
Deploy the MySQL/MariaDB database template with OpenTofu
Automation
Deploy the private network + VPN template with OpenTofu
Automation
Deploy the S3 Storage with ACLs template with OpenTofu
Automation
Deploy the self-managed PostgreSQL template with OpenTofu
Automation
Deploy the Simple VM template with OpenTofu
Automation
Deploy the three-tier application template with OpenTofu
Automation
Deploy the WordPress + MySQL template with OpenTofu
Automation