Your First Project

This section assumes that you have our free jump host machine and the scripts that were installed. We are assuming that you are using the OpenStack CLI to perform all of these functions. We typically don’t suggest using the Web UI for real work, except to visually identify components within your environment, since this does not produce repeatable processes, which is what cloud is all about.

This first project will use the project we created for you when you signed up for a Genesis Public Cloud account.

If you have questions about networking terms and concepts, please review the Networking in OpenStack section.

If you have never used OpenStack before, we encourage you to read The OpenStack CLI section.

We are assuming you have knowledge about SSH and have an SSH client available to you.

First Project Steps

We will take you through each step of creating a test server along with its respective network and storage components, which you can replicate with your own scripts.

Login to the jump host with the “centos” user and you will see the bash scripts in the home directory, along with your openrc files for your Domain Admin and Project Admin accounts.

Creating a network

On your jump host, we have included a script that creates a test network, subnet, router, and security groups to ease this process. You can copy this script and adjust it as you like:


A network is a layer 2 segment that a port can be binded to. Create your first network by running this command:

openstack network create --mtu 1500 "TestNetwork"

Creating a subnet

A subnet is a layer 3 concept that is used by OpenStack to configure the infrastructure with DHCP servers and initialize its IPAM (IP Address Management) system with the information in the subnet:

openstack subnet create \
  --network "TestNetwork" \
  --subnet-range \
  --gateway \
  --dns-nameserver \
  --dns-nameserver \
  --dns-nameserver \
  --allocation-pool start=,end= \

Creating a router

A router will allow traffic to be routed from your machine to other subnets, but more importantly, to the Internet.

The following command will create a router:

openstack router create "TestRouter"

Adding an external gateway to the router configures an uplink. To configure the uplink, we add a system network called ext-net, an Internet-connect bridge at Genesis:

openstack router set --external-gateway ext-net "TestRouter"

With an external gateway configured, the router will act as an SNAT device, allowing VMs to access the Internet by performing Source Network Address Translation (SNAT), similar to your home router, hiding machines behind a public IP address that was assigned to the router.

Later in this section, we will create a floating IP, which will create the necessary 1:1 NAT rule for inbound traffic for the VM we will create.

Creating a security group

By default, ports do not allow traffic to pass (only a default deny rule exists). Allow rules are added through the use of a security group that consists of security group rules.

The concept of a security group provides for a policy that can be adjusted across a large number of machines with a single change to the policy, avoiding making changes to individual VMs.

The following command creates a security group:

openstack security group create AllowSSHInbound

And the following adds a rule to this security group:

openstack security group rule create \
  --remote-ip \
  --dst-port 22 \
  --ingress \
  --protocol tcp \

This rule allows traffic from any IP ( inbound (ingress) to the destination tcp port 22, which is port for SSH traffic.

Note that this is just a policy, so it does not affect the infrastructure until the security group is assigned to a port or ports.

Additional security groups you may want to use that allow ICMP and RDP traffic inbound, depending on whether you want to install a Linux or Windows server:

openstack security group create AllowICMPInbound
openstack security group rule create \
  --remote-ip \
  --dst-port 3389 \
  --ingress \
  --protocol tcp \

openstack security group create AllowRDPInbound
openstack security group rule create \
  --remote-ip \
  --dst-port 3389 \
  --ingress \
  --protocol tcp \

Choosing an instance flavor

OpenStack, like most public clouds, have definitions for the properties of a virtual machine, including the number of CPUs and the quantity of memory as well as other ancillary properties that operators of the platform may add to direct requests to specific compute resources within the cloud.

OpenStack calls these flavors, which can be viewed using the following command:

openstack flavor list

We have included a script on your jump host that provides a sorted list of flavors:


There are many flavor types to choose from, which can be seen on the Genesis Public Cloud Pricing page.

For your first project, we will use the following flavor the server deployment:


which includes 1 CPU, 4 GiB of RAM, and has 80Mbps of network throughput.

Flavor names consist of 4 parts:

<type><processor revision><options>.<size>

Type can be:

t = tiny
c = compute optimized
m = general purpose
r = memory optimized
e = extreme sizing

Revision consists of the following:

5 = Intel Xeon Skylake
6 = Intel Xeon Coffee Lake
5a = AMD EPYC Zen 1
6a = AMD EPYC Zen 2

Options consists of the following:

s = shared cores
d = SSD boot disk included

Size consists of the following:


Sizing is typically consistent with a size multiplier, where 4xlarge is twice the size of an 2xlarge flavor.

Choosing an image

Genesis Public Cloud includes operating system images that are typically built by the manufacturers of those operating systems (called “cloud images”). Images include Cloud-Init, which is software that provisions an operating system along with network settings, boot partition expansion, and SSH key injection.

The command to view all of the images available is:

openstack image list

We have included a script in your jump host that provides a sorted list of images:


For deploying a Linux machine, we will use the following image:


For deploying a Windows machine, we will use the following image:


Note that we have two images for each operating system, one with “_raw” at the end. Use of the _raw image is best used with Ceph-based volume types (see the next section for information about volume types), where Ceph will create an inline snapshot of the image during server deployment, providing for a much faster deployment.

Images without _raw on the end are qcow2 images, which are compressed. These are best used for non-Ceph volume types, where the image must be copied in its entirety to the target storage. By using a qcow2 image, the copy process is much faster.

Storing a key pair

In order to inject an SSH public key into an image during the boot process, OpenStack must have a copy of the public key. OpenStack includes its own secure secrets vault, which is where it stores sensitive information such as keys and certificates.

During the creation of your jump host, we created a public/private key pair for the “centos” user. The following command will store the public key portion for use with the SSH key injection into the operating system image during deployment. This will provide for passwordless authentication for Linux machines:

openstack keypair create --public-key .ssh/ userkey

For Windows machines, this key is used to encrypt the random Administrator password that is set during deployment of the image. The private key (in .ssh/id_rsa) is required to decrypt this password. This prevents anyone from having access to the Administrator password except the user who has the private key. This also allows for automation of the login process to be secure, allowing only scripts and/or software that has access to the private key to gain access to the machine. We will review this process below in the Accessing your Windows machine section.

Choosing a volume type

OpenStack abstracts storage by providing a consistent front-end for multiple storage back-ends. The Genesis Public Cloud platform includes two storage systems that have different performance characteristics, Ceph and a high-performance NVMe SSD system.

Storage in OpenStack is provisioned in the form of a volume, which is a block device. Volumes are provisioned separate from compute resources.

When preparing a virtual machine, a volume with a bootable operating system must be attached. OpenStack can copy an image onto a volume during the creation of the volume.

We will create a 50GiB volume using the gp1 volume type and copy the operating system image onto the volume.

If you would like to create a CentOS server, this will create the volume, writing the CentOS image:

openstack volume create \
  --size 50 \
  --type gp1 \
  --image centos-7-x86_64-GenericCloud-1905_raw \
  --bootable \

Or if you would like to create a Windows server, this will create the volume, writing the Windows Server image:

openstack volume create \
  --size 50 \
  --type gp1 \
  --image Win2019_20190613_raw \
  --bootable \

Creating a virtual machine

We are finally at the stage where we can create the server, now that we have created a network, stored our public key, created our security groups, chosen a flavor, and created a volume:

openstack server create \
  --flavor t5s.2xlarge \
  --volume TestVolume001 \
  --network TestNetwork001 \
  --security-group AllowICMPInbound \
  --key-name userkey \

Note that multiple security group statements can be used in the server create command.

Specifying the network connects the port of the server to the network called TestNetwork001 that we created above, which currently has a subnet binded. The subnet has DHCP servers on this network, so this server will receive an IP address from these DHCP servers. Cloud-Init configures the network interface in the operating system to use DHCP, so the server will be assigned a private IP from the respective subnet.

Note that OpenStack provisions the DHCP servers to be statically binded to a chosen IP address (from its IPAM) as well as statically binded to the MAC address of the port associated with the VM. In addition, layer 2 and layer 3 filters exist in the port security settings for the VM’s port, and the MAC address associated with the port is created by, and uniquely assigned, by OpenStack. This prevents MAC address conflicts, filtering of any spoofed traffic, and guarantees that the DHCP servers can only assign an IP (and other DHCP options) to the port assigned to the VM.

Adding a security group

Security groups can be added after a server has been provisioned using the following command.

If you are deploying a Linux server, add a rule to allow SSH:

openstack server add security group AllowSSHInbound TestServer001

If you are deploying a Windows server, add a rule to allow RDP:

openstack server add security group AllowRDPInbound TestServer001

Adding a floating IP

We are almost finished! Now we need a 1:1 NAT rule to allow access to the server using a public IP. We do this using a floating IP. Like other objects in OpenStack, such as volumes, security groups, etc., objects can be created separate from compute objects, including floating IPs.

A floating IP is a reservation of a public IP. Floating IPs can be attached to or detached from the ports of servers or load balancers. Once detached, they can be attached to different server (and thus can “float” between servers).

To create a floating IP, we use the following command, which requests an IP on the ext-net, which is the system network where Genesis’ Internet connectivity is provided:

server_public_ip"=$(openstack floating ip create ext-net \
              --tag "TestServer001" -f value -c "Floating IP Address")

Note that we also tag this floating IP with a name so we can reference it by the server’s name for easy deletion, if needed. Also note that we can request the output format to be “value” while specifying which columns we want returned. Multiple “-c” parameters can be specified. In our example, we choose to only return the IP address and store the IP value in a bash variable called “server_public_ip”” for use later.

Now that the floating IP has been created, we can add the floating IP to the server, which chooses the port on the server to assign the IP:

openstack server add floating ip TestServer001 $server_public_ip"

By adding the floating IP to the server, this tells OpenStack to create a 1:1 NAT rule between the public IP and the private IP of the server.

Accessing your Linux machine

If you chose a Linux image for the volume attached to the server, you will use your SSH client to connect to the Linux server.

Since we have injected the public key created on your jump host, you can use your private key for passwordless authentication to the Linux server. From your jump host, you can use the following command to connect to the new Linux server:

ssh -i .ssh/id_rsa centos@$server_public_ip"

Accessing your Windows machine

If you chose a Windows image for the volume attached to the server, you will use RDP to connect to the Windows server.

We have provided a script that will decrypt the Windows Administrator password, which can be run using:

./ TestServer001

To retrieve the public IP address, you can use the command that was previously specified:

server_public_ip"=$(openstack floating ip create ext-net \
              --tag "TestServer001" -f value -c "Floating IP Address")

echo $server_public_ip