OpenStack Instance Deployment Guide
This guide details the standard procedure for deploying virtual machine (VM) instances through the project dashboard. The workflow is split into three sections based on the availability zone of the instance:
Compute Instance Deployment - standard CPU workloads.
GPU Instance Deployment - GPU / AI workloads.
Radio Instance Deployment - wireless / SDR workloads (includes USRP booking).
Every user follows the same path: read Before You Start, log in, create your network and router once, set up Terminal Access (ZeroTier), then launch whichever instance type you need and finish with the common post-launch steps.
Before You Start
Read this section before launching anything - these are the points that most often trip up new users.
Create your network first: A brand-new project has no usable network. You must create your own network and router before any instance can be launched (see Set Up Your Network and Router). You only do this once per project.
Choose the right availability zone:
computefor CPU workloads,gpufor GPU/AI workloads, andradiofor SDR/wireless workloads.Watch your quotas: Instance, VCPU, RAM, and volume limits are shown on the Overview tab. New instances will fail to create once a quota is hit.
Terminal access is over ZeroTier: There is no public SSH and no floating IP. You reach every instance - compute, GPU, or radio - over the project’s ZeroTier network (see Terminal Access (ZeroTier)).
GPU flavors need approval: Request the GPU flavor from the admin team before attempting a GPU launch, or the launch will fail.
Book USRPs first: A radio VM cannot reach an SDR unit that has not been reserved for the matching time slot.
Persistent vs ephemeral storage: Set Create New Volume = Yes to keep data across rebuilds; ephemeral disks are wiped when the instance is deleted.
Change default credentials: Update the default image password (
CCI@2025) on first login for any production workload.Free up resources: Delete unused instances and volumes to stay within quota and free them for other project members.
Onboarding & Logging In
New users do not receive login credentials by email. Access is granted through CILogon / authentik once your account is approved.
Log in: Open the OpenStack application from authentik. In the login dropdown, choose Authenticate with authentik, then select the domain named in your welcome email.
Resource Quotas: The Overview tab displays the project’s limits. For example, a project may be restricted to 10 instances, 20 VCPUs, and 50 GB of RAM.
Quota Management: Once these limits are reached, the system prevents the creation of new instances until you free resources.
Note
Default image credentials for all Ubuntu-based images in this guide are
Username: ubuntu / Password: CCI@2025. These log you into the
instance itself - they are not OpenStack credentials and not SSH keys.
Change the password on first login for production workloads.
Set Up Your Network and Router
A new project has no private network of its own. Before launching any instance, create one network and one router that bridges it to the provider network. You only need to do this once per project - the same network and router are reused by every instance you launch.
Create a Network
Navigate to Network → Networks and click + Create Network. The wizard has three tabs:
Network tab:
Network Name:
external-network-<firstname>(for example,external-network-JohnDoe).Leave Enable Admin State and Create Subnet checked.
MTU: set to
1450.
Subnet tab:
Subnet Name:
external-subnet-<firstname>.Network Address Source: keep Enter Network Address manually.
Network Address: a private CIDR, for example
10.120.0.0/24.Leave IP Version as
IPv4and leave Gateway IP blank to accept the default (the first address in the range). Do not tick Disable Gateway.
Subnet Details tab: enable DHCP, then click Create.
Create a Router
Navigate to Network → Routers and click + Create Router.
Router Name: give it a name (for example,
Internal-Project-<Firstname>-Router).Leave Enable Admin State checked.
External Network: select
Main-Internet-Network.Click Create Router.
Add an Interface
Connect your subnet to the router so your private network can reach the external network:
From Network → Routers, click your newly created router to open it.
Go to the Interfaces tab and click + Add Interface.
In the Subnet dropdown, select
external-subnet-<firstname>.Leave IP Address (optional) blank.
Click Submit.
The new internal interface appears in the list with a fixed IP and a status of
Active.
Verify the Topology
Open Network → Network Topology to confirm the layout: your router should
be linked to Main-Internet-Network on one side and to your
external-subnet-<firstname> on the other. Radio users will also see the
USRP networks here once an interface is attached.
Note
This section will be expanded with a walkthrough video.
Tip
Once the network and router exist, they are reused for every instance you launch in the project - you only create them once.
Terminal Access (ZeroTier)
There is no public SSH access and no floating IP in this testbed. You reach every instance - compute, GPU, and radio - over the project’s ZeroTier overlay network. You install and authorize ZeroTier once on your local machine and once on each instance.
Note
The project’s 16-digit ZeroTier network ID and device authorization are managed by the CCI admin team. Request the network ID and have your devices authorized before you begin.
Install ZeroTier
Install ZeroTier on both your local machine and the instance. For the instance, open a shell through the OpenStack dashboard Console (noVNC) tab for this one-time setup - after this you will connect over ZeroTier:
curl -s https://install.zerotier.com | sudo bash
sudo systemctl enable --now zerotier-one
Join the Project Network
sudo zerotier-cli join <network-id>
Replace <network-id> with the 16-digit hexadecimal ID from the admin team.
Confirm Your Assigned IP
Once authorized, list your networks and note the assigned ZeroTier IP:
sudo zerotier-cli listnetworks
The network status changes to OK and an IP address is listed.
Connect
From your authorized local machine, SSH to the instance’s ZeroTier IP using the
image credentials (ubuntu / CCI@2025):
ssh ubuntu@<instance-zerotier-ip>
Important
ZeroTier needs UDP port 9993 open and ICMP allowed in the
default security group. See
Network Connectivity & Security.
Compute Instance Deployment
How to Create a Compute Node
Launch Procedure
Navigate to Project → Compute → Instances and click Launch Instance.
Details: Enter an Instance Name (e.g.,
test_compute). Set the Availability Zone tocompute.Source:
Set Select Boot Source to Instance Snapshot (or Volume, if you are booting from a volume you created - see Volume Management).
Set Create New Volume to No (ephemeral, wiped on delete) for standard testing, or Yes (persistent, saved to Cinder storage) to keep critical data.
Select your desired snapshot or volume and click the Up Arrow (↑) to move it into Allocated.
Flavor: Choose a flavor (e.g.,
m4.4.32) and click the Up Arrow (↑).Networks: Allocate your own network,
external-network-<firstname>.Security Groups: Allocate the
defaultsecurity group.Launch: Click Launch Instance and wait for the status to change to
Activeand power state toRunning.
Once the instance is active, set up Terminal Access (ZeroTier) to get a shell, then see Common Post-Launch Procedures for storage and security steps.
Tip
Monitor the instance row through the sequence
Build → Spawning → Active. If it stalls on Build for more
than a few minutes, check your project quotas on the Overview tab.
GPU Instance Deployment
How to Create and Configure a GPU Node
Important
Before creating a GPU instance, you must request a GPU flavor by specifying the required GPU version via a ticket to the admin team on Email. Without an approved flavor, the launch step below will fail.
Launch Procedure
Navigate to Project → Compute → Instances and click Launch Instance.
Details: Enter an Instance Name (e.g.,
test_gpu). Set the Availability Zone togpu.Source: Choose Instance Snapshot from the dropdown menu (or a Volume you created). Select your source and click the Up Arrow (↑).
Note
Use Persistent storage (Create New Volume = Yes) if you plan to retain large datasets across instance rebuilds.
Flavor: Choose your approved GPU flavor and click the Up Arrow (↑).
Networks: Allocate your own network,
external-network-<firstname>.Security Groups: Allocate the
defaultsecurity group.Launch: Click Launch Instance and wait for the status to change to
Active.
Once active, set up Terminal Access (ZeroTier) to connect, then continue with the GPU configuration below.
GPU Configuration & Validation
Install Drivers
Install the kernel headers, build tools, and NVIDIA driver stack (version 535):
sudo apt install -y linux-headers-$(uname -r) \
linux-modules-extra-$(uname -r) \
build-essential dkms ubuntu-drivers-common
sudo apt install -y nvidia-driver-535 nvidia-dkms-535 \
nvidia-utils-535 libnvidia-compute-535
sudo dkms autoinstall -k $(uname -r)
sudo update-initramfs -u
sudo reboot
Important
The instance must reboot after driver installation. Reconnect over
ZeroTier once it returns to Active.
Verify Drivers
After reconnecting, confirm the GPU is detected:
nvidia-smi
Expected output: a table listing the GPU model (e.g., Tesla V100), driver version 535.x, and CUDA version.
Install PyTorch and Validate CUDA
sudo apt update
sudo apt install -y python3-pip
python3 -m pip install --upgrade pip numpy
python3 -m pip install torch --index-url https://download.pytorch.org/whl/cu121
Quick sanity check:
python3 - <<'PY'
import torch
print("CUDA available:", torch.cuda.is_available())
print("GPU name:", torch.cuda.get_device_name(0))
PY
GPU Stress Test
Execute a 5-minute matrix multiplication loop to verify hardware stability:
python3 - <<'PY'
import torch, time
assert torch.cuda.is_available(), "CUDA is not available"
device = "cuda"
print("GPU:", torch.cuda.get_device_name(0))
size = 12000
a = torch.randn(size, size, device=device)
b = torch.randn(size, size, device=device)
end = time.time() + 300
count = 0
while time.time() < end:
c = torch.matmul(a, b)
torch.cuda.synchronize()
count += 1
print("Completed matrix multiplications:", count)
PY
In a second terminal, monitor utilization and check for hardware errors:
watch -n 1 nvidia-smi
sudo dmesg | grep -i "xid"
Note
A successful test returns no output from the xid grep, meaning
zero Xid errors were detected. GPU utilization should stay between
90-100 % during the run.
Radio Instance Deployment
How to Create a Radio Node
Deploying a radio instance is a two-stage process:
Book a USRP on the CCI xG Testbed booking portal (see below).
Launch a Radio VM in the
radioavailability zone to act as the host for the booked USRP.
Important
You must complete the USRP booking before launching the radio VM. The VM will not be able to communicate with an SDR unit you have not reserved.
Booking USRP Resources (SDR Booking)
Reserve - and cancel - USRP nodes from the booking portal. The portal uses a tabbed layout: Book USRP, My Reservations, USRP & GPU Access, OpenStack Quota, and Resources.
How to Book a USRP
Prerequisites
An approved CCI xG account and your OpenStack project name (e.g.,
External-Project-<firstname>).
Open the Booking Portal
Sign in to the CCI xG dashboard at https://authentik.ccixgtestbed.org/ and open the booking portal, then select the Book USRP tab (or click Start booking on the landing page).
Validate Your OpenStack Project
A pop-up prompts you to Enter Your OpenStack Project. Type your project name, click Validate, then Continue.
Note
The project name is case-sensitive and must match your OpenStack project exactly. If validation fails, double-check it against your OpenStack dashboard. (Screenshot showing where to find the project name to be added.)
Select Date Range, Mode, and USRP
On the Book USRP page, under Select Date Range and Time:
USRP Selection: choose Single USRP or Multiple USRPs.
Pick a From Date and To Date.
Bookings are issued in fixed 4-hour time blocks: 12 AM-4 AM, 4 AM-8 AM, 8 AM-12 PM, 12 PM-4 PM, 4 PM-8 PM, and 8 PM-12 AM (Eastern Time).
Your project limit is shown alongside the controls (e.g.,
1 of 3 USRPs currently reserved).
Scroll to Available USRPs. Nodes are arranged by their physical row/radio
position, each tile showing the node number, model (e.g., X310 or
N310), and a Book action. Tiles are colour-coded:
Green - Available.
Yellow - Partially Available (some slots in the range are taken).
Red - Fully Booked.
Grey - Disabled or under Maintenance.
Click Book on an available node to open its reservation dialog.
Configure the Cellular Plan and Confirm
The Book USRP <id> dialog opens a Cellular plan form. Only FCC-safe, bookable bands are shown.
Radio standard: e.g.,
5G NRorLTE 4G.Duplex mode:
TDDorFDD.Band: e.g.,
NR n78 (TDD).Bandwidth (MHz): up to
20MHz (the SDR-based UE maximum).Carrier input: choose Downlink center frequency or Downlink ARFCN, then enter the value.
The backend calculates the uplink/downlink carrier ranges from the band, duplex mode, and bandwidth, enforces a 5 MHz guard band between users, and shows any occupied slices and free windows for the band.
Tick I agree to the Acceptable Use Policy.
Click Review Booking to see the summary (project, USRP, dates, time, radio plan, bandwidth, and computed downlink/uplink ranges).
Click Confirm Booking. A confirmation email is sent immediately.
Warning
Operating outside the approved cellular plan, or changing radio settings without approval, may result in a ban from using testbed devices. See the Acceptable Use Policy for details.
Tip
Need a longer experiment? Book consecutive 4-hour blocks on the same node. For several radios at once, use Multiple USRPs in the selection step.
Managing Reservations (View, Cancel, Change)
Open the My Reservations tab to manage active bookings. Each row lists the Booking ID, USRP, project, band, start/end time, status, and Port. Ports are created automatically when the reservation starts; until then the Port column shows Pending with an Attach guide link. Once active, attach the port to your instance following the SDR network configuration steps below.
Cancel: tick the reservation’s checkbox, then click Cancel selected (only possible before the reservation starts).
Request a change: click the calendar action icon to open Request Reservation Change. Set Request type (e.g.,
Modify time), enter the Proposed start/Proposed end and a Reason, then Submit Request.
Launch Procedure (Radio VM)
Once your USRP is booked, launch the radio host instance:
Navigate to Project → Compute → Instances and click Launch Instance.
Details: Enter an Instance Name. Set the Availability Zone to
radio.Source: Choose Instance Snapshot from the dropdown menu (or a Volume you created). Select your source and click the Up Arrow (↑).
Flavor: Choose an appropriate radio flavor and click the Up Arrow (↑).
Networks: Allocate your own network,
external-network-<firstname>.Security Groups: Allocate the
defaultsecurity group.Launch: Click Launch Instance and wait for the status to change to
Active.
Once active, set up Terminal Access (ZeroTier), then continue with the SDR network configuration below.
SDR Network Configuration
Because the USRP nodes exist on an isolated private network, you must manually attach the radio network to your instance and configure the internal routing before you can interact with the SDR. Connect to the instance over ZeroTier first.
Step A: Attach the USRP Interface
In the OpenStack dashboard, navigate to Project → Compute → Instances.
Click the dropdown arrow next to your Radio instance and select Attach Interface.
Change the “Way to specify an interface” dropdown to by Port.
Select the specific USRP port you booked (e.g.,
USRP-110) from the dropdown list.Click Attach Interface.
Check your Instances list. Your VM should now display two IP addresses (e.g., your network IP and your USRP Network IP, such as
192.168.110.7). Take note of this USRP IP address.
Step B: Configure Netplan
Connected over ZeroTier, configure Ubuntu to recognize the newly attached
radio interface (usually ens4).
Run
ip ato verify the new interface name. You should seeens4listed without an IP address.Open the network configuration file. The filename may vary - run
ls /etc/netplan/first, as it is often50-cloud-init.yamlon cloud images:sudo nano /etc/netplan/00-installer-config.yaml
Add your
ens4interface and the USRP IP address you noted from the OpenStack dashboard (append/24to it). The file should look like this:network: ethernets: ens3: dhcp4: true ens4: addresses: [192.168.110.7/24] version: 2
Save and exit the file (Ctrl+O, Enter, Ctrl+X).
Apply the new network configuration:
sudo netplan apply
Step C: SDR Verification
Once the network is applied, verify connectivity to the USRP unit. The SDR is
typically located at the .2 address of your subnet (e.g., if your IP is
192.168.110.7, the radio is at 192.168.110.2) - confirm the exact
address for your booked node.
ping 192.168.110.2 # verify reachability to the radio node
uhd_find_devices # discover the booked USRP node
Note
uhd_find_devices should list the USRP unit you reserved in the
booking section. If it returns nothing, confirm
your booking is still active in the My Reservations tab of the booking
portal, and verify that your netplan configuration has the correct IP
address.
Booking Portal: Other Tabs
Besides booking USRPs, the portal at https://authentik.ccixgtestbed.org/ exposes three more tabs for requesting capacity and checking status.
USRP & GPU Access
Use this tab to request additional radio or GPU capacity for your project beyond your current allocation. Fill in the request form and submit it; your submissions and their status appear under My USRP Requests / My GPU Requests. This is also where you request the GPU flavor referenced in GPU Instance Deployment.
OpenStack Quota
Use this tab to request increases to your OpenStack compute quota (instances, VCPUs, RAM, volumes). The form shows recommended values and deployment guidance, and your prior requests appear in the request history. Your current limits are visible on the OpenStack Overview tab (see Before You Start).
Resources
Use this tab to check live testbed status: GPU availability, maintenance windows (including any that overlap your selected booking range), operational notices, and links to the deployment guides.
Common Post-Launch Procedures
The following procedures apply to all instance types (compute, GPU, and
radio) once the VM is Active.
Expanding Instance Storage
If you launched with a disk size larger than the default Instance Snapshot, you must manually expand the storage:
sudo apt update
sudo apt install -y cloud-guest-utils lvm2
sudo growpart /dev/vda 3
sudo pvresize /dev/vda3
sudo lvextend -r -l +100%FREE /dev/mapper/ubuntu--vg-ubuntu--lv
Network Connectivity & Security
All terminal access is over ZeroTier (see Terminal Access (ZeroTier)), so the
default security group only needs the rules that let ZeroTier and your
workload through.
ZeroTier transport: Navigate to Network → Security Groups and click Manage Rules for the
defaultgroup. Add the following:Custom UDP Rule - Port
9993(ZeroTier’s default transport port).All ICMP - to allow
pingfor reachability checks across the ZeroTier network.
SSH over ZeroTier: Add an SSH (TCP
22) rule, but restrict the CIDR to the project’s ZeroTier subnet rather than0.0.0.0/0so the port is not exposed to the public internet.Additional protocols: Add any application-specific ports your experiment needs (e.g., HTTP/HTTPS, custom TCP/UDP ranges).
Warning
Never open SSH to 0.0.0.0/0. There is no public access path in this
testbed - keep all access scoped to the ZeroTier overlay.
Volume Management
Volumes let you boot instances from persistent storage and keep data across rebuilds. You can select a volume as the boot Source in any launch procedure.
Creating a Volume
Navigate to the left-hand sidebar and select Volumes, then click on Volumes from the dropdown.
Click the + Create Volume button located near the top right of the dashboard.
Provide a name for the volume in the designated field.
Select your Volume Source. If you are building from a backup like in the video, select Volume Snapshot and choose the specific snapshot from the dropdown.
Specify the desired capacity in the Size (GiB) field (e.g.,
128).Click the blue Create Volume button to initialize the storage.
Extending a Volume (Increasing Size)
From the Volumes list, locate the specific volume you want to resize.
Click the dropdown arrow next to Edit Volume in the Actions column.
Select Extend Volume from the menu.
Enter the new, larger capacity in the New Size (GiB) field (for example, upgrading from
32to128).Click Extend Volume to apply the new size limit.
Attaching a Volume (Connecting to an Instance)
From the Volumes list, locate the volume you want to connect.
Click the dropdown arrow in the Actions column for that volume.
Select Manage Attachments.
Choose the target instance from the dropdown menu where you want the volume mounted.
Click Attach Volume to link the storage to your virtual machine.