# Automation / IaC FAQ

Source: https://docs.quake.ai/docs/automation/faq
Markdown: https://docs.quake.ai/docs/automation/faq.md
> Frequently asked questions about Infrastructure as Code on Quake AI: OpenTofu, Terraform, Heat orchestration, Ansible configuration management, state management, templates, CI/CD integration, multi-environment patterns, and migration from CloudFormation, Hetzner, and Docker Compose.

---

{/*
--- FAQ: Automation / IaC service ---
Every question is tagged with a confidence tier:

  T1  High-confidence: answer is a direct restatement of existing canonical
      content. Ship after light review.

  T2  Medium-confidence: answer synthesized across multiple concept/how-to
      pages. Needs a PM/eng pass before publish.

  T3  Validation-needed: pricing, quotas, SLA, and support questions answered
      as skeletons. Confirm with responsible team before publish.

Every answer ends with a "Source:" line linking to the canonical doc(s)
it is drawn from.
*/}

# Automation / IaC FAQ

Frequently asked questions about Infrastructure as Code on Quake AI. For step-by-step instructions, see the [Automation how-to guides](/docs/automation). For deeper background, see the [concept pages](/docs/automation/concepts/iac-comparison). For ready-to-deploy patterns, browse the [template library](/resources/iac-templates). For migrating from another tool or provider, see the [migration guides](/docs/automation/migration).

## Getting started





### Q: What is the recommended IaC tool for Quake AI? [T1]


**OpenTofu** is the recommended Infrastructure as Code tool for Quake AI. It is fully open source (MPL-2.0), maintained by the Linux Foundation, and compatible with every Terraform provider, module, and state file. All Quake AI templates and documentation use OpenTofu.

If your team already uses **Terraform**, every Quake AI template works without modification, replace `tofu` with `terraform` in commands.





### Q: How do I install OpenTofu and deploy my first resource? [T1]


Install OpenTofu for your platform:

- **macOS:** `brew install opentofu`
- **Linux (apt):** `curl -fsSL https://get.opentofu.org/install-opentofu.sh | sudo bash -s -- --install-method deb`
- **Linux (snap):** `snap install opentofu --classic`

Verify with `tofu --version`. Then:

1. Create an `openrc.sh` file with your Quake AI credentials and `source` it.
2. Write a `main.tf` declaring an `openstack_compute_instance_v2` resource.
3. Run `tofu init` → `tofu plan` → `tofu apply`.

The [getting started guide](/docs/automation/how-to/getting-started-iac) walks through every step, including a complete working `main.tf` example.





### Q: What OpenStack resources does the provider manage? [T1]


The [OpenStack provider](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest) maps Quake AI services to HCL resource types. The most commonly used are:

| Category | Resource types |
|---|---|
| Compute | `openstack_compute_instance_v2`, `openstack_compute_keypair_v2`, `openstack_compute_servergroup_v2` |
| Network | `openstack_networking_network_v2`, `openstack_networking_subnet_v2`, `openstack_networking_router_v2`, `openstack_networking_floatingip_v2`, `openstack_networking_secgroup_v2`, `openstack_networking_secgroup_rule_v2` |
| Block storage | `openstack_blockstorage_volume_v3`, `openstack_compute_volume_attach_v2` |
| Heat (legacy) | `openstack_orchestration_stack_v1` |

For S3-compatible object storage, the template library uses the AWS provider (`aws_s3_bucket`) with the Quake AI S3 endpoint.





## Core concepts





### Q: What is the difference between Heat (HOT YAML) and OpenTofu/Terraform: and when should I use each? [T1]


Both tools declare infrastructure as code and apply changes as a unit, but they differ in scope and capability:

| | OpenTofu / Terraform | Heat (HOT YAML) |
|---|---|---|
| **Template format** | HCL (`.tf` files) | HOT YAML |
| **State management** | Client-side state file (local or remote S3) | Server-side (OpenStack manages state) |
| **Change preview** | `tofu plan` shows diff before any change | No plan step, apply is immediate |
| **Provider scope** | Multi-provider (OpenStack + AWS S3 + DNS + others) | OpenStack-native resources only |
| **Module ecosystem** | Terraform Registry (community modules) | None |
| **Rollback** | Manual (restore state or re-apply) | Automatic on creation failure (configurable) |
| **Quake AI status** | **Recommended for new projects** | Supported for existing stacks (legacy path) |

**Use OpenTofu** for any new project, multi-cloud configurations, or when you need a pre-apply plan review.

**Keep Heat** only if you already have Heat stacks deployed in production. They continue to work. For new resources, use OpenTofu alongside them.





### Q: How do I configure the OpenStack provider for Quake AI? [T1]


Declare the provider in `main.tf` with an empty block, credentials come from environment variables:

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

provider "openstack" {}
```

Source your application credential file before running any `tofu` command:

```bash
source ~/openrc.sh   # sets OS_AUTH_URL, OS_APPLICATION_CREDENTIAL_ID, OS_APPLICATION_CREDENTIAL_SECRET
tofu plan
```

For CI/CD environments where sourcing a file is impractical, pass credentials explicitly via variables (never hardcode them in `.tf` files):

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


Do not mix environment variables with explicit provider credentials. If both are present, explicit values take precedence and can cause authentication scope mismatches.






### Q: OpenTofu vs. Terraform: are there any functional differences for Quake AI? [T1]


No functional differences for Quake AI usage. Both tools use the same OpenStack provider, the same HCL syntax, and the same state file format. Every Quake AI template runs with `terraform` in place of `tofu` without modification.

The difference is licensing and governance: OpenTofu is MPL-2.0 (open source, no usage restrictions); Terraform is BSL 1.1 (source available, restricts competitive use). OpenTofu also reads and writes Terraform state files, so migration between tools is a binary swap, no state migration required.





### Q: How does OpenTofu state management work, and how do I store state remotely? [T1]


OpenTofu 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 plan and drift detection.

By default, state is stored locally in the working directory. For team use or CI/CD, store state in Quake AI object storage (S3-compatible):

```hcl
terraform {
  backend "s3" {
    bucket = "my-project-tfstate"
    key    = "production/terraform.tfstate"
    region = "us-east-1"   # required by the backend; not meaningful for Quake AI

    endpoints = {
      s3 = "https://object.YOUR_REGION.rumble.cloud"
    }

    skip_credentials_validation = true
    skip_metadata_api_check     = true
    skip_region_validation      = true
    skip_requesting_account_id  = true
    use_path_style              = true
  }
}
```

Export your Quake AI S3 credentials as `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` before running `tofu init`.

**State locking:** The Quake AI S3-compatible endpoint does not provide DynamoDB-compatible locking. Mitigate concurrent writes by serializing applies in CI/CD (`max-parallel: 1`) and enabling bucket versioning to allow state recovery.





### Q: How do I integrate OpenTofu with a CI/CD pipeline? [T1]


The recommended pattern is **plan on pull request, apply on merge**.

**GitHub Actions**: use the `opentofu/setup-opentofu@v1` action. Store all nine `OS_*` and `AWS_*` credentials as repository secrets and inject them as environment variables. The plan job runs `tofu plan -no-color -out=plan.out` on pull requests and posts the diff as a PR comment. The apply job runs `tofu apply -auto-approve` only when changes merge to `main`.

**GitLab CI**: use the `ghcr.io/opentofu/opentofu:latest` Docker image. Store credentials as masked CI/CD variables. Run plan on merge requests, then require a manual click to apply on the default branch (`when: manual`).

Key best practices:
- Never auto-apply on pull requests; always review the plan output first.
- Use `max-parallel: 1` (GitHub) or `resource_group` (GitLab) to prevent concurrent state writes.
- Pin provider versions with `version = "~> 2.0"` to avoid unexpected upgrades.
- Cache the `.terraform/providers/` directory between runs to accelerate `tofu init`.





### Q: How do I manage multiple environments (dev, staging, production)? [T1]


Two approaches, depending on team size and environment divergence:

**Approach 1: Variable files (recommended for most teams)**

Keep a single set of `.tf` files and use per-environment `.tfvars` files (`envs/dev.tfvars`, `envs/production.tfvars`). Use a separate state key per environment:

```bash
tofu init -backend-config="key=dev/terraform.tfstate"
tofu plan -var-file=envs/dev.tfvars
tofu apply -var-file=envs/dev.tfvars
```

This keeps environments in sync by default while isolating state.

**Approach 2: Directory per environment**

Place a separate `main.tf` in `environments/dev/`, `environments/staging/`, and `environments/production/`, each calling a shared module from `modules/`. Each directory has its own state file. Use this when production and development have fundamentally different resource configurations.

| Factor | Variable files | Directory per environment |
|---|---|---|
| State isolation | Same config, separate state keys | Fully separate state and config |
| Drift between environments | Environments stay in sync | Can diverge intentionally |
| Best for | Small-to-medium teams | Large teams, architecturally different envs |





### Q: What is the plan/apply workflow? [T1]


Every infrastructure change follows the same four-step cycle:

1. **`tofu init`**: download the OpenStack provider plugin and configure the backend. Run once per project or when you change providers.
2. **`tofu plan`**: compare `.tf` files against the state file and print a diff. Look for `forces replacement` to identify changes that will destroy and recreate a resource.
3. **`tofu apply`**: execute the planned changes after confirmation.
4. **`tofu destroy`**: tear down all resources managed by the current configuration.

Review the plan output before applying. Replacements can cause downtime; in-place updates do not.





## Templates





### Q: Is there a starter template for my use case? [T1]


The template library contains fourteen OpenTofu templates (one uses HOT YAML).

| Template | What it provisions | Difficulty |
|---|---|---|
| [Simple VM with Floating IP](/resources/iac-templates/simple-vm) | Single instance, floating IP, SSH + HTTP security group | Beginner |
| [WordPress + MySQL](/resources/iac-templates/wordpress-mysql) | WordPress + MySQL on two instances, block storage, private network | Intermediate |
| [Full-Stack Application](/resources/iac-templates/full-stack-app) | Web, app, and DB instances on a private network with floating IP and block storage | Advanced |
| [Three-Tier Application](/resources/iac-templates/three-tier-app) | Classic 3-tier with subnet-level isolation (web → app → DB) | Advanced |
| [Edge Reverse Proxy](/resources/iac-templates/edge-reverse-proxy) | Public Caddy proxy with a floating IP and private upstream routing | Intermediate |
| [Kubernetes Cluster Bootstrap](/resources/iac-templates/k8s-cluster) | Control plane + worker nodes via kubeadm, private network, floating IP | Advanced |
| [Monitoring Stack](/resources/iac-templates/monitoring-stack) | Prometheus + Grafana on dedicated instances with block storage | Advanced |
| [Self-Managed PostgreSQL](/resources/iac-templates/self-managed-postgres) | PostgreSQL instance with block storage, WAL archiving to object storage | Intermediate |
| [Private Network + VPN](/resources/iac-templates/private-network-vpn) | WireGuard VPN gateway on a private network | Advanced |
| [API Gateway](/resources/iac-templates/api-gateway) | API routing and policy controls on a public gateway instance | Intermediate |
| [Development Environment](/resources/iac-templates/dev-environment) | Multiple dev VMs + bastion host + shared NFS volume | Intermediate |
| [S3 Storage with ACLs](/resources/iac-templates/s3-storage-acl) | S3-compatible object storage bucket with ACL, versioning, and CORS | Beginner |
| [Heat Simple Stack](/resources/iac-templates/heat-simple-stack) | Single instance via HOT YAML (Heat legacy path) | Beginner |
| [Dev Environment](/resources/iac-templates/dev-environment) | See above | Intermediate |

Start with [Simple VM](/resources/iac-templates/simple-vm) if you are new to IaC on Quake AI, or browse the full [template library](/resources/iac-templates).





### Q: What does the Simple VM template do, and when should I use it? [T1]


The [Simple VM with Floating IP](/resources/iac-templates/simple-vm) template is the minimal useful pattern for a publicly accessible instance. It provisions:

- A compute instance (default: `s1a.small`, `Ubuntu-24.04`)
- A floating IP for SSH and application access
- A security group allowing SSH (port 22) and HTTP (port 80)
- An SSH key pair

Default parameters: `flavor_name = s1a.small`, `image_name = Ubuntu-24.04`, `instance_name = simple-vm`.

Use this template as the starting point for any single-instance workload, or as a reference for learning the OpenStack provider resource types.





### Q: What does the Three-Tier Application template do? [T1]


The [Three-Tier Application](/resources/iac-templates/three-tier-app) template provisions a classic web/app/database architecture with strict network isolation:

- **Web tier**: public-facing instances on a dedicated subnet with a floating IP (HTTP, HTTPS, SSH from anywhere)
- **Application tier**: business logic instances on a private subnet; accessible from the web subnet only (port 8080, SSH)
- **Database tier**: data instances on an isolated subnet with attached block storage; accessible from the app subnet only (MySQL port 3306, PostgreSQL port 5432, SSH)

Default instance counts: 2 web, 2 app, 1 DB. No direct public access to the application or database tiers.





### Q: What does the Kubernetes Cluster Bootstrap template do? [T1]


The [Kubernetes Cluster Bootstrap](/resources/iac-templates/k8s-cluster) template provisions the infrastructure for a self-managed Kubernetes cluster:

- Control plane node(s) initialized with kubeadm (default: 1, flavor `m2a.xlarge`)
- Worker nodes joined to the cluster (default: 3, flavor `s1a.medium`)
- Dedicated private network for cluster communication
- Security groups for the Kubernetes API, etcd, kubelet, and NodePort ranges
- Optional floating IP for external API access

Kubernetes installation is handled by cloud-init scripts embedded in the template. Default Kubernetes version: `1.31`, pod CIDR: `10.244.0.0/16`.





### Q: What does the WordPress + MySQL template do? [T1]


The [WordPress + MySQL](/resources/iac-templates/wordpress-mysql) template provisions a two-instance WordPress stack:

- WordPress instance with Nginx and PHP-FPM, public floating IP, security group for SSH/HTTP/HTTPS
- MySQL instance on the same private network with no public access
- Block storage volume for the MySQL data directory (default: 20 GB)
- Security groups restricting MySQL (port 3306) to traffic from the private subnet only

Default flavors: `s1a.small` (WordPress), `m2a.large` (MySQL). This template is also the recommended starting point for migrating Docker Compose workloads.





### Q: What is the Heat Simple Stack template for? [T1]


The [Heat Simple Stack](/resources/iac-templates/heat-simple-stack) template is a HOT YAML template for teams already using the Heat orchestration engine. It provisions a single compute instance with a security group for SSH, using OpenStack Heat resource types (`OS::Nova::Server`, `OS::Neutron::SecurityGroup`).


Heat is a legacy orchestration path. For new infrastructure, use the [Simple VM OpenTofu template](/resources/iac-templates/simple-vm) instead.






## Operations and lifecycle





### Q: What happens if I modify infrastructure outside OpenTofu (drift)? [T1]


When resources are modified through the console, CLI, or another tool, the state file falls out of sync with reality. The next `tofu plan` will report unexpected changes.

**To accept external changes:** run `tofu apply -refresh-only` to update the state file to match the current real-world state without modifying infrastructure.

**To revert to the OpenTofu definition:** run a normal `tofu apply` to push the `.tf` configuration back to the infrastructure.

Avoid mixing console changes with OpenTofu-managed resources; automated pipelines and manual edits conflict.





### Q: What are the most common OpenTofu errors and how do I fix them? [T1]


| Error | Cause | Fix |
|---|---|---|
| `Unauthorized` (401) | Token expired during a long apply | Use application credentials instead of token-based auth |
| `Resource not found` / 404 on data source | Referenced network, image, or flavor does not exist | Run `openstack network list`, `openstack image list`, `openstack flavor list` to verify |
| `Quota exceeded` (403/413) | Project quota exhausted | Free resources or request a quota increase |
| `Conflict` (409) | Resource is in a transitional state | Wait and retry, the resource may be building or attaching |
| `Could not find any suitable endpoint` | Wrong region or misconfigured service catalog | Verify `OS_REGION_NAME` and `OS_INTERFACE` (typically `public`) |
| State lock error | A previous apply crashed and left the lock | Verify no other process is running, then `tofu force-unlock <LOCK_ID>` |

Enable `TF_LOG=DEBUG` to see the full HTTP request/response cycle, including the actual API error message when Terraform output is unhelpful.





### Q: How do I create and manage a Heat stack? [T1]


Heat stacks can be created from the console or CLI.

**Console:** Select **Automation** > **Heat Stacks** > **Create Stack**. Paste or upload your HOT YAML template, add any environment variables, set a stack name and creation timeout, and select **Confirm**.

**CLI:**
```bash
openstack stack create --template YOUR_TEMPLATE.yaml \
  --parameter "key_name=YOUR_KEY" \
  YOUR_STACK_NAME
```

After creation, verify the stack reached `CREATE_COMPLETE`:
```bash
openstack stack show YOUR_STACK_NAME -c stack_status -c stack_status_reason
```

Stack status values include `CREATE_IN_PROGRESS`, `CREATE_COMPLETE`, `CREATE_FAILED`, `UPDATE_*`, `DELETE_*`, `ROLLBACK_*`, `SUSPEND_*`, `RESUME_*`, and `SNAPSHOT_*`.





### Q: What does the `Fail Rollback` field on the Create Stack wizard control? [T2]


The `Fail Rollback` radio pair on page 2 of the Console **Create Stack** wizard controls what Heat does when stack creation fails:

| Selection | Behavior when `CREATE_FAILED` |
|---|---|
| `Enable` (default) | Heat deletes the partial resources it created so the project returns to a clean state. |
| `Disable` | Heat retains the partial resources so you can inspect what was created before the failure. |

`Enable` is the default and is the right choice for most workflows; the failed stack disappears and no orphan resources remain. Pick `Disable` only when you are actively debugging a stack-creation failure and want the partial resources kept around for inspection.

The underlying Heat API parameter uses the inverse convention: the wizard's `Enable` maps to `disable_rollback=false`, and `Disable` maps to `disable_rollback=true`. On the CLI, pass `--disable-rollback` (the flag's presence is `true`):

```bash
# Default: rollback enabled, partial resources deleted on failure
openstack stack create --template stack.yaml MY_STACK

# Disable rollback, retain partial resources on failure
openstack stack create --template stack.yaml --disable-rollback MY_STACK
```





### Q: How should I structure a multi-file OpenTofu project? [T1]


OpenTofu loads all `.tf` files in the working directory automatically. A typical Quake AI project splits configuration by concern:

```text
project/
  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)
```

Never commit `terraform.tfstate` or `.tfvars` files to version control. Add both to `.gitignore`.





## Ansible





### Q: Does Quake AI support Ansible? [T1]


Yes. Quake AI runs OpenStack Antelope (2023.1), and the upstream `openstack.cloud` Ansible collection (2.x series, 2.5.0 latest) is compatible with that release. Authenticate with `clouds.yaml` plus application credentials, the same auth pattern the OpenTofu docs use.

The recommended scope for Ansible on Quake AI is **configuration management** above OpenTofu provisioning. Reach for OpenTofu first to create VMs, then Ansible to configure them. The [getting-started how-to](/docs/automation/how-to/getting-started-ansible) walks through installation and a first playbook.





### Q: When should I use Ansible instead of OpenTofu? [T1]


Use OpenTofu for provisioning (Day 0): create VMs, networks, security groups, floating IPs, and block volumes. OpenTofu is declarative and stateful, so `tofu plan` shows you what will change before any resource moves.

Use Ansible for configuration management (Day 1 and Day 2): install packages, harden SSH, deploy applications, rotate credentials, run drift correction against existing hosts. Ansible is idempotent at the task level, so a rerun converges a host without a global state file.

Most production workflows use both: OpenTofu provisions, Ansible configures. The [combined template](/resources/iac-templates/ansible-provision-and-configure) wires the two together with a single `make deploy`.





### Q: How do I authenticate Ansible to Quake AI? [T1]


The recommended path is `clouds.yaml` with application credentials. Generate the credentials in the Quake AI console, place them in `~/.config/openstack/clouds.yaml` as a named cloud, then reference that name from playbook tasks:

```yaml
- name: Create a server
  openstack.cloud.server:
    cloud: rumble
    name: web-01
    image: Ubuntu-24.04
    flavor: m2a.large
```

The `OS_*` environment variables sourced from an `openrc.sh` file also work. Avoid hardcoding credentials in playbook files; commit only the cloud name to version control.





### Q: Can I use Ansible with dynamic inventory on Quake AI? [T1]


Yes. The `openstack.cloud` collection ships an inventory plugin that queries Quake AI and builds Ansible inventory from running instances. Configure it in an `openstack.yml` file under your inventory directory:

```yaml
plugin: openstack.cloud.openstack
clouds:
  - rumble
keyed_groups:
  - key: openstack.metadata.role
    prefix: role
  - key: openstack.metadata.environment
    prefix: env
```

The plugin groups instances by metadata tags, region, flavor, and image. Set OpenStack instance metadata at create time (in OpenTofu or via `openstack.cloud.server`) and Ansible can target those groups directly. The [dynamic inventory how-to](/docs/automation/how-to/ansible-dynamic-inventory) covers caching, filtering, and the full set of plugin options.





### Q: Can I use Ansible to create VMs directly, without OpenTofu? [T1]


Yes, but it is rarely the right choice. The `openstack.cloud.server` module creates instances; combined with `openstack.cloud.network`, `openstack.cloud.security_group`, and `openstack.cloud.floating_ip`, a playbook can stand up a small environment without any OpenTofu.

The trade-off is that Ansible has no plan step, no state file, and no native dependency graph for provisioning. For anything beyond a one-off, OpenTofu is a better provisioning layer. Use Ansible-only provisioning for short-lived environments (CI runners, demos) where the simpler workflow outweighs the lack of plan/state. The [provision-with-Ansible how-to](/docs/automation/how-to/ansible-provision-instance) shows the pattern and names the limits.





### Q: Which Ansible collections do I need for Quake AI playbooks? [T1]


Three Ansible collections cover the playbooks the platform's templates ship:

| Collection | Used for |
|---|---|
| `openstack.cloud` | Provisioning (servers, networks, floating IPs, security groups) |
| `ansible.posix` | Managing SSH `authorized_keys` |
| `community.general` | UFW firewall configuration |

Install all three at once with a `requirements.yml`:

```yaml
---
collections:
  - name: openstack.cloud
    version: ">=2.5.0"
  - name: ansible.posix
  - name: community.general
```

Then run:

```bash
ansible-galaxy collection install -r requirements.yml
```

A playbook that fails with `couldn't resolve module/action 'ansible.posix.authorized_key'` or `'community.general.ufw'` is missing one of these collections. The platform's [ansible-configure-vm template](/resources/iac-templates/ansible-configure-vm) and the combined [ansible-provision-and-configure template](/resources/iac-templates/ansible-provision-and-configure) depend on all three.





## Migration





### Q: How do I migrate from AWS CloudFormation to OpenTofu on Quake AI? [T1]


CloudFormation and OpenTofu serve the same purpose but differ in execution:

| Concept | CloudFormation | OpenTofu on Quake AI |
|---|---|---|
| Template format | JSON or YAML | HCL (`.tf` files) |
| State management | Server-side (AWS manages) | Client-side state file |
| Change preview | Change Sets | `tofu plan` |
| Rollback | Automatic on failure | Manual |

**Resource mapping:**

| CloudFormation resource | Quake AI OpenTofu resource |
|---|---|
| `AWS::EC2::Instance` | `openstack_compute_instance_v2` |
| `AWS::EC2::VPC` + subnets | `openstack_networking_network_v2` + `openstack_networking_subnet_v2` |
| `AWS::EC2::SecurityGroup` | `openstack_networking_secgroup_v2` + rules |
| `AWS::EC2::EIP` | `openstack_networking_floatingip_v2` |
| `AWS::ElasticLoadBalancingV2::LoadBalancer` | Self-managed reverse proxy or API gateway instance with a floating IP |
| `AWS::RDS::DBInstance` | `openstack_compute_instance_v2` + cloud-init ([Self-Managed PostgreSQL](/resources/iac-templates/self-managed-postgres)) |
| `AWS::S3::Bucket` | `aws_s3_bucket` with Quake AI S3 endpoint |
| `AWS::EC2::Volume` | `openstack_blockstorage_volume_v3` |
| `AWS::CloudFormation::Stack` (nested) | OpenTofu `module` blocks |

**Migration workflow:** audit stacks, map resources, write OpenTofu HCL, configure remote state, then apply networking, storage, compute, and edge routing in dependency order.

**Key differences from AWS:** self-managed databases use the [Self-Managed PostgreSQL](/resources/iac-templates/self-managed-postgres) template, and ALB listeners translate into routes on a self-managed [edge reverse proxy](/resources/iac-templates/edge-reverse-proxy) or [API gateway](/resources/iac-templates/api-gateway). Authentication uses OpenStack Keystone application credentials. Quake AI uses fixed monthly pricing.





### Q: How do I migrate from Hetzner Cloud to Quake AI? [T1]


If you already use OpenTofu or Terraform with the Hetzner Cloud provider, migration is a provider swap with resource remapping:

| Hetzner Cloud | Quake AI |
|---|---|
| `hetznercloud/hcloud` provider | `terraform-provider-openstack/openstack` provider |
| `hcloud_server` | `openstack_compute_instance_v2` |
| `hcloud_ssh_key` | `openstack_compute_keypair_v2` |
| `hcloud_floating_ip` | `openstack_networking_floatingip_v2` |
| `hcloud_firewall` | `openstack_networking_secgroup_v2` + rules |
| `hcloud_volume` | `openstack_blockstorage_volume_v3` |
| `hcloud_network` + `hcloud_network_subnet` | `openstack_networking_network_v2` + `openstack_networking_subnet_v2` |
| `hcloud_load_balancer` | Self-managed reverse proxy or API gateway instance with a floating IP |
| `hcloud_placement_group` | `openstack_compute_servergroup_v2` |

**Key differences from Hetzner:** Hetzner uses a single API token; Quake AI uses OpenStack Keystone with `OS_*` environment variables. Hetzner auto-assigns a public IPv4; Quake AI requires explicit floating IP association. Hetzner firewalls are standalone resources; Quake AI security groups attach per-rule as separate HCL resources.





### Q: How do I migrate from Docker Compose to OpenTofu on Quake AI? [T1]


Docker Compose manages containers on a single host. Moving to Quake AI shifts you from container orchestration to infrastructure provisioning: OpenTofu creates the VMs, networks, and volumes; cloud-init starts your containers on first boot. Your `docker-compose.yml` travels unchanged inside the VM.

**Concept mapping:**

| Docker Compose | Quake AI OpenTofu |
|---|---|
| `services:` | `openstack_compute_instance_v2` + cloud-init to install Docker and run containers |
| `ports:` | `openstack_networking_secgroup_rule_v2` + floating IP |
| `volumes:` | `openstack_blockstorage_volume_v3` |
| `networks:` | `openstack_networking_network_v2` + subnet |
| `depends_on:` | OpenTofu resource `depends_on` |
| `.env` file | `terraform.tfvars` or CI/CD secrets |

**Topology choices:**
- All services on one host → Single VM (simplest migration); use [Simple VM](/resources/iac-templates/simple-vm) + cloud-init
- Web + DB → [WordPress + MySQL template](/resources/iac-templates/wordpress-mysql)
- Multi-tier → [Full-Stack Application template](/resources/iac-templates/full-stack-app)

Transfer data with `rsync` or `scp`; for database dumps, use `mysqldump` / `pg_dump` and restore on the new instance.





## Pricing, quotas, availability, and support





### Q: What regions is the Automation service available in? [T2]


The Automation service (both OpenTofu against the OpenStack APIs and Heat) runs in all three Quake AI regions: `us-east-1`, `us-east-2`, and `us-west-1`. Authentication is region-scoped, the Keystone URL takes the form `https://keystone.<region>.rumble.cloud/v3`, and OpenTofu's S3 backend accepts any of the three region strings. Each region is an independent failure domain; Heat stacks are scoped to a single region. See [Regions](/docs/platform#regions) for the current region table and console URLs.





### Q: Is there an SLA for the Automation service? [T2]


Heat is an OpenStack orchestration service running on the same infrastructure as Compute and Network. Its availability is therefore tied to the platform-wide SLA. The contractual availability target and credit schedule are published as part of Quake AI's commercial terms at [rumble.cloud/legal](https://rumble.cloud/legal); the [Service Level Agreement page](/docs/account/sla) explains how to read those terms and how to file a credit claim. OpenTofu runs in your own environment and is not covered by the SLA; what is covered is the OpenStack API surface OpenTofu calls.





### Q: How do I get help if OpenTofu or Heat is broken? [T2]


For most problems, start with the guides:

- [How to debug Terraform errors](/docs/automation/how-to/terraform-error-handling): authentication failures, quota errors, state lock recovery, drift, import errors.
- [Automation API error reference](/reference/automation/api-errors): Heat API status codes and the stack state machine.

Enable `TF_LOG=DEBUG` to see the full HTTP request/response cycle against the OpenStack API. For state-related issues, use `tofu state list`, `tofu state show`, and `tofu force-unlock` as needed.

If the guide does not resolve the issue, [open a support ticket](https://rumble.cloud/support) with the stack name or resource ID, the region, and the UTC time window of the failure, plus the standard evidence from [Support ticket evidence collection](/docs/operate/troubleshooting/support-ticket-evidence). [Get help](/docs/get-help) is the canonical decision tree for picking the right starting point based on the symptom.





## See also

- [Automation overview](/docs/automation): service description, tool comparison, and full guide index
- [IaC on Quake AI: OpenTofu and Terraform](/docs/automation/concepts/iac-comparison): detailed feature comparison and tool selection guidance
- [Terraform and OpenTofu on Quake AI](/docs/automation/concepts/terraform): provider setup, resource types, and best practices
- [Cloud Automation and Orchestration](/docs/automation/concepts/cloud-automation): concept introduction for teams new to IaC
- [Infrastructure Templates](/resources/iac-templates): validated, ready-to-deploy OpenTofu templates
- [How to get started with Infrastructure as Code](/docs/automation/how-to/getting-started-iac): step-by-step first deployment
- [How to manage OpenTofu state with Quake AI S3](/docs/automation/how-to/state-management): remote state setup
- [How to integrate OpenTofu with CI/CD](/docs/automation/how-to/cicd-integration): GitHub Actions and GitLab CI configurations
- [How to manage multiple environments](/docs/automation/how-to/multi-environment): variable files and directory-per-environment patterns
- [How to debug Terraform errors](/docs/automation/how-to/terraform-error-handling): error catalogue and recovery procedures
- [Migration guides](/docs/automation/migration): from AWS CloudFormation, Hetzner Cloud, and Docker Compose
- [Coming from AWS: Automation](/resources/migration/coming-from-aws): CloudFormation → Heat / OpenTofu service mapping
