How to provision a production-ready VM
Coming from another cloud?
▸AWS·EC2 Instances
EC2 Instances
- Uses EC2 RunInstances API instead of Nova servers.create.
- Requires predefined instance type selection.
- Supports per-second On-Demand billing and Spot/Reserved options.
- Includes hibernation state not standard in OpenStack.
▸Azure·Virtual Machines
Virtual Machines
- Uses Azure Resource Manager (ARM) REST API at /providers/Microsoft.Compute/virtualMachines instead of OpenStack Nova API at /v2.1/servers.
- Tightly integrated with Azure services like Azure Active Directory for authentication, unlike OpenStack's Keystone.
- VM creation requires specifying size from predefined series with hardware-specific features (e.g., AMD/Intel/ARM), not custom flavor configs.
- Billed per second with complex pricing tiers based on series/reservation options, vs OpenStack's typically hourly or usage-based.
▸DigitalOcean·Droplets
Droplets
- API surface is DigitalOcean’s proprietary REST/CLI/Terraform tooling rather than OpenStack Nova/Neutron/Glance APIs (Droplets are managed via DigitalOcean UI/CLI/API/Terraform).
- Billing is usage-based with per-second billing (60-second minimum and monthly cap) rather than the typical per-hour, quota-based charge model users often see in OpenStack-based clouds.
- Droplets include a bundled outbound transfer allowance with each plan (starting at 500 GiB/month) rather than a separate bandwidth quota/metering model users often encounter in OpenStack deployments.
- Droplets are described as Linux-based VMs on virtualized hardware with local SSD storage, whereas OpenStack deployments commonly expose distinct block storage (Cinder) and image services (Glance) and may not bundle bandwidth/monitoring/firewalls into the instance offering.
▸Google Cloud·VM instances
VM instances
- Uses REST API 'instances.insert' instead of Nova 'servers.create' with different auth via service accounts vs Keystone.
- Supports bare metal instances (no hypervisor), not in standard OpenStack Nova.
- Network interfaces tied to VPC subnets; differs from Neutron ports/floating IPs.
▸Hetzner·Cloud Servers
Cloud Servers
- Servers provisioned individually via Hetzner API (hcloud), not OpenStack Nova flavors; fixed instance types like CX11 (1 vCPU, 2GB RAM, 20GB NVMe).
- No flavor customization; choose from predefined shared/dedicated vCPU series.
- Billing hourly with monthly cap per server (e.g., €3.29/mo cap for CX11), charged even when powered off until deleted, unlike typical OpenStack stop-to-pause billing.
- Custom REST API at api.hetzner.cloud/v1/servers instead of OpenStack Nova /v2.1/servers (different auth, payloads, response formats).
How to provision a production-ready VM
Walk through the decisions and steps to launch a virtual machine you can run a workload on: pick sizing, attach SSH access, place the instance on the right network, pass first-boot configuration, and confirm you can connect.
This guide orchestrates the primitive how-tos below. Use them when you need full detail on a single step:
- Create a virtual machine instance
- Create a VM on a private network
- Create a VM on a public network
- Set a password on a virtual machine instance (console access alternative, not the primary path for production)
Prerequisites
- ConsoleLogged in to the Quake AI console
- CLIOpenStack CLI installed and authenticated (
clouds.yamloropenrcsourced) - APIAPI token generated with
$OS_TOKENand service endpoint variables set - TerraformOpenTofu installed with Quake AI provider configured
Windows: CLI examples use bash. Set up a Linux CLI environment on Windows before proceeding.
- An SSH key pair uploaded to your account
- A project with quota for at least one instance, one boot volume, and (for the private-network path) one floating IP
Step 1. Choose a flavor and image#
Right-size the instance before you create it. Start with the smallest flavor that meets your workload's CPU, memory, and disk needs, then scale up if monitoring shows sustained pressure.
| Decision | Guidance |
|---|---|
| Flavor family | General-purpose flavors (m2a.*) suit most web and API workloads. Pick compute-optimized (c2a.*) for CPU-bound jobs and memory-optimized (r2a.*) for in-memory caches or analytics. |
| Shared vs dedicated vCPU | Shared flavors (s1a.*) work for dev and light traffic. Dedicated flavors give predictable CPU for production services. |
| Image | Use a current LTS image such as Ubuntu-22.04 unless your workload requires another supported image. |
| Boot disk | All Quake AI flavors have disk=0; you must boot from a volume. Size the volume for the OS plus application data (10 GiB is a common starting point for Linux). |
List available flavors and images from the CLI:
openstack flavor list --long
openstack image listStep 2. Create or select an SSH key pair#
Production VMs should authenticate with SSH keys, not password-only login.
If you need password-based console access as a fallback, configure it after creation with set a password on a virtual machine instance. Do not rely on passwords as the only login method.
Step 3. Place the VM on the right network#
For production workloads, place the instance on a private network with a router to the public internet. Allocate one floating IP only when you need inbound SSH or HTTP/HTTPS from the internet.
For quick tests, you can use a public network instead. That path assigns a public address automatically and does not require a floating IP.
Before you launch the instance, create a security group that allows only the ports your workload needs. At minimum, allow SSH (TCP 22) from your admin IP range rather than 0.0.0.0/0 when you can.
Step 4. Pass cloud-init user data#
Cloud-init runs on first boot. Use it to create a non-root sudo user, apply package updates, and set the hostname. See cloud-init and first-boot configuration for how the first-boot model works, and How to configure a VM with cloud-init for module reference, launch methods, and debugging.
Save this template as cloud-init.yaml and replace the placeholder values:
#cloud-config
hostname: PROD_HOSTNAME
users:
- name: deploy
groups: sudo
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
ssh_authorized_keys:
- YOUR_SSH_PUBLIC_KEY
package_update: true
package_upgrade: trueIn the Console, paste the YAML into Advanced Options > User Data on the System Config step of the Create Instance wizard.
Step 5. Create the instance#
Launch the VM on the private network with your key pair, security group, and user data.
Step 6. Verify access#
Confirm the instance booted, cloud-init finished, and SSH works as the non-root user.
If the workload exposes HTTP or HTTPS, curl the service port from your workstation:
curl -I http://FLOATING_IPOpen only the ports your application needs in the security group.
Next steps#
Continue the VM lifecycle cluster:
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.
For the full policy, see Usage Guidelines.
Last validated: 10.07.2026
Quick answers
- Why does `openstack image save` write a 0-byte file for my boot-from-volume instance?CLI
- Why does `openstack server create` fail with "Only volume-backed servers are allowed for flavors with zero disk"?CLIAPITerraform
- Why does my project still have a 10 GiB Cinder volume after I deleted my instance?CLIAPI