In about five minutes you’ll have a running VM on Atlas Cloud, reachable from the public internet, returning hello-world over HTTP.

This page is your single canonical entry point. Pick the interface you prefer — every step is shown for Console, CLI (cmk), Terraform, and curl (raw CloudStack API). They are equivalent; you do not need to switch between them mid-way.

Prerequisite. You need an Atlas Cloud account with API credentials. See Get API credentials for the 2-minute setup.

1. Pick a Compute Offering and Template

A Compute Offering is a VM size. Atlas offerings follow the pattern Atlas.a4 (smallest) through Atlas.a8w (large Windows). A Template is the OS image. For this quickstart pick Atlas.a4 (1 vCPU / 4 GiB) and Ubuntu 24.04 LTS.

Console

Log in at https://sky.runatlas.is. The compute offering names and templates are listed in the New Instance form — you’ll see them in step 4.

CLI

cmk list serviceofferings filter=name,id,cpunumber,memory
# Atlas.a4 = 1 vCPU / 4 GiB; Atlas.a5 = 2 vCPU / 8 GiB; Atlas.a6 = 4 vCPU / 16 GiB; Atlas.a7 = 8 vCPU / 32 GiB
cmk list templates templatefilter=featured name="Ubuntu 24.04 LTS" filter=name,id

Terraform

data "cloudstack_service_offering" "small" {
  filter { name = "name", value = "Atlas.a4" }
}
 
data "cloudstack_template" "ubuntu" {
  filter { name = "name", value = "Ubuntu 24.04 LTS" }
}

curl

See the upstream CloudStack listServiceOfferings and listTemplates endpoints, signed and sent to https://sky.runatlas.is/client/api. Request signing is non-trivial; most users start with the CLI or Terraform tabs.

2. Create a Guest Network (if you don’t have one)

A Guest Network is the L2/L3 network your VM lives on. If you already have one, skip to step 3.

Console

In the Console: Network → Guest networks → Add network. Use the default offering. Name it default.

CLI

cmk create network name=default displaytext=default \
  networkofferingid=$(cmk list networkofferings filter=name,id | grep -i 'DefaultIsolatedNetworkOffering' | awk '{print $1}') \
  zoneid=$(cmk list zones name=is1 filter=id | tail -1)

Terraform

resource "cloudstack_network" "default" {
  name               = "default"
  display_text       = "default"
  cidr               = "10.1.1.0/24"
  network_offering   = "DefaultIsolatedNetworkOfferingWithSourceNatService"
  zone               = "is1"
}

curl

See createNetwork — see step 1 note on signing.

3. Add an SSH key

So you can log into the VM.

Console

Compute → SSH key pairs → Add SSH key pair. Paste your ~/.ssh/id_ed25519.pub. Name it mykey.

CLI

cmk register sshkeypair name=mykey publickey="$(cat ~/.ssh/id_ed25519.pub)"

Terraform

resource "cloudstack_ssh_keypair" "mykey" {
  name       = "mykey"
  public_key = file("~/.ssh/id_ed25519.pub")
}

curl

See registerSSHKeyPair.

4. Launch the VM

Console

Compute → Instances → Add instance. Pick the Template, Compute Offering, Network, and SSH key from the previous steps. Click Launch instance. Wait ~30 seconds.

CLI

# Look up the IDs once
SO=$(cmk list serviceofferings name=Atlas.a4 | jq -r '.serviceoffering[0].id')
TEMPLATE=$(cmk list templates templatefilter=featured name="Ubuntu 24.04 LTS" | jq -r '.template[0].id')
NETWORK=$(cmk list networks name=my-network | jq -r '.network[0].id')   # use your network's name
ZONE=$(cmk list zones name=is1 | jq -r '.zone[0].id')
 
# Deploy
cmk deploy virtualmachine \
  serviceofferingid=$SO \
  templateid=$TEMPLATE \
  networkids=$NETWORK \
  zoneid=$ZONE \
  keypair=mykey \
  name=hello-atlas

Terraform

resource "cloudstack_instance" "hello" {
  name             = "hello-atlas"
  service_offering = data.cloudstack_service_offering.small.name
  template         = data.cloudstack_template.ubuntu.name
  network_id       = cloudstack_network.default.id
  zone             = "is1"
  keypair          = cloudstack_ssh_keypair.mykey.name
  expunge          = true
}
terraform apply

curl

See deployVirtualMachine.

5. Reach the VM

Grab a public IP, forward port 80 to your VM, and curl it.

Console

Network → Public IP addresses → Acquire new IP. Open the IP, Configuration → Firewall: allow TCP 80. Port forwarding: forward public 80 → VM private 80. SSH into the VM, install nginx (sudo apt update && sudo apt install -y nginx), then from your laptop: curl http://<public-ip>.

CLI

ZONE=$(cmk list zones name=is1 | jq -r '.zone[0].id')
VM=$(cmk list virtualmachines name=hello-atlas | jq -r '.virtualmachine[0].id')
 
# Allocate a Public IP
PUBLIC_IP_ID=$(cmk associate ipaddress zoneid=$ZONE | jq -r '.ipaddress.id')
 
# Open port 80 and forward it to the VM
cmk create firewallrule ipaddressid=$PUBLIC_IP_ID protocol=tcp startport=80 endport=80 cidrlist=0.0.0.0/0
cmk create portforwardingrule ipaddressid=$PUBLIC_IP_ID protocol=tcp publicport=80 privateport=80 virtualmachineid=$VM
 
PUBLIC_IP=$(cmk list publicipaddresses id=$PUBLIC_IP_ID | jq -r '.publicipaddress[0].ipaddress')
ssh -i ~/.ssh/id_ed25519 ubuntu@$PUBLIC_IP "sudo apt update && sudo apt install -y nginx"
curl http://$PUBLIC_IP

Terraform

resource "cloudstack_ipaddress" "public" {
  zone = "is1"
}
 
resource "cloudstack_firewall" "http" {
  ip_address_id = cloudstack_ipaddress.public.id
  rule {
    cidr_list = ["0.0.0.0/0"]
    protocol  = "tcp"
    ports     = ["80"]
  }
}
 
resource "cloudstack_port_forward" "http" {
  ip_address_id = cloudstack_ipaddress.public.id
  forward {
    protocol           = "tcp"
    private_port       = 80
    public_port        = 80
    virtual_machine_id = cloudstack_instance.hello.id
  }
}
 
output "public_ip" {
  value = cloudstack_ipaddress.public.ip_address
}
terraform apply
ssh ubuntu@$(terraform output -raw public_ip) "sudo apt update && sudo apt install -y nginx"
curl http://$(terraform output -raw public_ip)

curl

See associateIpAddress, createFirewallRule, createPortForwardingRule.

You should see nginx’s “Welcome to nginx!” HTML.

You’re done

You have a public-IP-reachable VM running nginx on Atlas Cloud. From here:

  • Add a domain with DNS pointing at the public IP.
  • Take a snapshot so you can roll back.
  • Replace the Guest Network with a VPC for multi-tier architectures.
  • Add an S3 bucket for static assets.

Common failures