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,idTerraform
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-atlasTerraform
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 applycurl
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_IPTerraform
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
- VM stuck in
Starting→ Troubleshooting: VM stuck pending - SSH times out → Troubleshooting: Can’t SSH to VM
- API call returns 401 → Check your API key + secret are valid; see Get API credentials.
curltimes out → Confirm the firewall rule allows TCP 80 and the port-forward maps the public IP to the VM.