Once you have your OpenStack playground up and running it is time to actually use it. What we want to do today is to create our first compute instance. Before we can do that, we again need a bit of preparation. If you know AWS EC2, or other public cloud services when it comes to compute, you probably know the concept of “flavors”, or “instance types”, or “shapes”, or whatever the wording. No matter how it is called, this is all about defining base metrics for an instance to be launched, such as the number of CPUs/Cores or the amount of memory to assign to them.
With OpenStack this is not much different. Looking at the “flavors” we currently have available we’ll notice that there is nothing defined yet. You can either look at that from the command line:
[root@controller ~]$ . admin-openrc
[root@controller ~]$ openstack flavor list
[root@controller ~]$
… or from the Horizon dashboard:

From now on, we’ll used the command line but you’ll see some screenshots of the dashboard when it makes sense. If you prefer using the dashboard, go ahead and manage it from there.
We currently have one image available to deploy instances from, and this is the CirrOS image we’ve uploaded when we created the playground (see the link on top of this post if you didn’t follow that). This image is really small, so we can create a really small “flavor” for this:
[root@controller ~]$ openstack flavor create --id 0 --vcpus 1 --ram 64 --disk 1 m1.nano
+----------------------------+---------+
| Field | Value |
+----------------------------+---------+
| OS-FLV-DISABLED:disabled | False |
| OS-FLV-EXT-DATA:ephemeral | 0 |
| description | None |
| disk | 1 |
| id | 0 |
| name | m1.nano |
| os-flavor-access:is_public | True |
| properties | |
| ram | 64 |
| rxtx_factor | 1.0 |
| swap | 0 |
| vcpus | 1 |
+----------------------------+---------+
[root@controller ~]$ openstack flavor list
+----+---------+-----+------+-----------+-------+-----------+
| ID | Name | RAM | Disk | Ephemeral | VCPUs | Is Public |
+----+---------+-----+------+-----------+-------+-----------+
| 0 | m1.nano | 64 | 1 | 0 | 1 | True |
+----+---------+-----+------+-----------+-------+-----------+
When it comes to connecting to the VM we’ll deploy in a couple of minutes later on, you should have a SSH keypair (again, very much the same as you know it from public cloud compute services). To create that with OpenStack, create a standard SSH key, and then upload it into OpenStack:
[root@controller ~]$ ssh-keygen -q -N ""
Enter file in which to save the key (/root/.ssh/id_rsa):
[root@controller ~]$ ls -a .ssh/
. .. id_rsa id_rsa.pub
[root@controller ~]$ openstack keypair create --public-key ~/.ssh/id_rsa.pub demokey
+-------------+-------------------------------------------------+
| Field | Value |
+-------------+-------------------------------------------------+
| created_at | None |
| fingerprint | f9:ef:2f:7d:c3:6c:99:17:0e:63:3b:f8:b0:75:aa:85 |
| id | demokey |
| is_deleted | None |
| name | demokey |
| type | ssh |
| user_id | 3d6998879b6c4fdd91ba4b6ec00b7157 |
+-------------+-------------------------------------------------+
[root@controller ~]$ openstack keypair list
+---------+-------------------------------------------------+------+
| Name | Fingerprint | Type |
+---------+-------------------------------------------------+------+
| demokey | f9:ef:2f:7d:c3:6c:99:17:0e:63:3b:f8:b0:75:aa:85 | ssh |
+---------+-------------------------------------------------+------+
The next bit we need to get right for being able to access the instance are security groups. You can think of them like firewalls allowing or denying access for specific ports and protocols. Current we have one security group available, the default one:
[root@controller ~]$ openstack security group list
+--------------------------------------+---------+------------------------+----------------------------------+------+
| ID | Name | Description | Project | Tags |
+--------------------------------------+---------+------------------------+----------------------------------+------+
| 52a3b8d0-9490-4f85-8692-e7875f744bc9 | default | Default security group | 920bf34a6c88454f90d405124ca1076d | [] |
+--------------------------------------+---------+------------------------+----------------------------------+------+
This group does not have any rules defined to allow access over ssh:
[root@controller ~]$ openstack security group rule list default
+--------------------------------------+-------------+-----------+-----------+------------+-----------+--------------------------------------+----------------------+
| ID | IP Protocol | Ethertype | IP Range | Port Range | Direction | Remote Security Group | Remote Address Group |
+--------------------------------------+-------------+-----------+-----------+------------+-----------+--------------------------------------+----------------------+
| 09b76b42-1cb6-437b-b7dc-f6b947d5cf88 | None | IPv6 | ::/0 | | ingress | 52a3b8d0-9490-4f85-8692-e7875f744bc9 | None |
| 461734e3-113d-4b87-a266-c448eb407f18 | None | IPv4 | 0.0.0.0/0 | | egress | None | None |
| cf174f68-9e67-4299-8f0a-af9f4c250005 | None | IPv4 | 0.0.0.0/0 | | ingress | 52a3b8d0-9490-4f85-8692-e7875f744bc9 | None |
| e23e72d7-a432-4330-9a0b-ee74c9d61661 | None | IPv6 | ::/0 | | egress | None | None |
+--------------------------------------+-------------+-----------+-----------+------------+-----------+--------------------------------------+----------------------+
To allow this, we need to add the rules:
[root@controller ~]$ openstack security group rule create --proto tcp --dst-port 22 default
+-------------------------+--------------------------------------+
| Field | Value |
+-------------------------+--------------------------------------+
| belongs_to_default_sg | True |
| created_at | 2025-01-27T08:51:06Z |
| description | |
| direction | ingress |
| ether_type | IPv4 |
| id | a3bc97d7-8ba1-4f8a-a87f-28e14c2b6883 |
| name | None |
| normalized_cidr | 0.0.0.0/0 |
| port_range_max | 22 |
| port_range_min | 22 |
| project_id | 920bf34a6c88454f90d405124ca1076d |
| protocol | tcp |
| remote_address_group_id | None |
| remote_group_id | None |
| remote_ip_prefix | 0.0.0.0/0 |
| revision_number | 0 |
| security_group_id | 52a3b8d0-9490-4f85-8692-e7875f744bc9 |
| tags | [] |
| updated_at | 2025-01-27T08:51:06Z |
+-------------------------+--------------------------------------+
[root@controller ~]$ openstack security group rule list default
+--------------------------------------+-------------+-----------+-----------+------------+-----------+--------------------------------------+----------------------+
| ID | IP Protocol | Ethertype | IP Range | Port Range | Direction | Remote Security Group | Remote Address Group |
+--------------------------------------+-------------+-----------+-----------+------------+-----------+--------------------------------------+----------------------+
| 09b76b42-1cb6-437b-b7dc-f6b947d5cf88 | None | IPv6 | ::/0 | | ingress | 52a3b8d0-9490-4f85-8692-e7875f744bc9 | None |
| 461734e3-113d-4b87-a266-c448eb407f18 | None | IPv4 | 0.0.0.0/0 | | egress | None | None |
| a3bc97d7-8ba1-4f8a-a87f-28e14c2b6883 | tcp | IPv4 | 0.0.0.0/0 | 22:22 | ingress | None | None |
| cf174f68-9e67-4299-8f0a-af9f4c250005 | None | IPv4 | 0.0.0.0/0 | | ingress | 52a3b8d0-9490-4f85-8692-e7875f744bc9 | None |
| e23e72d7-a432-4330-9a0b-ee74c9d61661 | None | IPv6 | ::/0 | | egress | None | None |
+--------------------------------------+-------------+-----------+-----------+------------+-----------+--------------------------------------+----------------------+
If you want a ping to success as well, add it:
[root@controller ~]$ openstack security group rule create --proto icmp default
+-------------------------+--------------------------------------+
| Field | Value |
+-------------------------+--------------------------------------+
| belongs_to_default_sg | True |
| created_at | 2025-01-27T08:52:56Z |
| description | |
| direction | ingress |
| ether_type | IPv4 |
| id | 246aab68-9a8c-47f4-9554-0ea9c88ef18d |
| name | None |
| normalized_cidr | 0.0.0.0/0 |
| port_range_max | None |
| port_range_min | None |
| project_id | 920bf34a6c88454f90d405124ca1076d |
| protocol | icmp |
| remote_address_group_id | None |
| remote_group_id | None |
| remote_ip_prefix | 0.0.0.0/0 |
| revision_number | 0 |
| security_group_id | 52a3b8d0-9490-4f85-8692-e7875f744bc9 |
| tags | [] |
| updated_at | 2025-01-27T08:52:56Z |
+-------------------------+--------------------------------------+
[root@controller ~]$ openstack security group rule list default | egrep "tcp|icmp"
| 246aab68-9a8c-47f4-9554-0ea9c88ef18d | icmp | IPv4 | 0.0.0.0/0 | | ingress | None | None |
| a3bc97d7-8ba1-4f8a-a87f-28e14c2b6883 | tcp | IPv4 | 0.0.0.0/0 | 22:22 | ingress | None | None |
Now we’re ready to deploy our first instance. As we have configured a provider network, this is the network we need to use:
[root@controller ~]$ openstack network list
+--------------------------------------+----------+--------------------------------------+
| ID | Name | Subnets |
+--------------------------------------+----------+--------------------------------------+
| aa8bd4f9-4d89-4c7f-803c-c56aaf8f8f57 | provider | 77ba8f00-edeb-4555-8c2a-be48b24f0320 |
+--------------------------------------+----------+--------------------------------------+
To deploy the instance provide the flavor, the image ID, the network ID, the ssh key, the security group, and a name to the instance:
[root@controller ~]$ . admin-openrc
[root@controller ~]$ openstack server create --flavor m1.nano --image cirros --nic net-id=f0183177-cef2-4e56-8c61-15ae96636ba1 --security-group default --key-name demokey --wait "demo-instance"
+-------------------------------------+---------------------------------------------------------------------------------------------+
| Field | Value |
+-------------------------------------+---------------------------------------------------------------------------------------------+
| OS-DCF:diskConfig | MANUAL |
| OS-EXT-AZ:availability_zone | nova |
| OS-EXT-SRV-ATTR:host | compute.it.dbi-services.com |
| OS-EXT-SRV-ATTR:hostname | demo-instance |
| OS-EXT-SRV-ATTR:hypervisor_hostname | compute.it.dbi-services.com |
| OS-EXT-SRV-ATTR:instance_name | instance-0000000c |
| OS-EXT-SRV-ATTR:kernel_id | None |
| OS-EXT-SRV-ATTR:launch_index | None |
| OS-EXT-SRV-ATTR:ramdisk_id | None |
| OS-EXT-SRV-ATTR:reservation_id | r-3lautvxl |
| OS-EXT-SRV-ATTR:root_device_name | /dev/vda |
| OS-EXT-SRV-ATTR:user_data | None |
| OS-EXT-STS:power_state | Running |
| OS-EXT-STS:task_state | None |
| OS-EXT-STS:vm_state | active |
| OS-SRV-USG:launched_at | 2025-02-03T07:53:27.000000 |
| OS-SRV-USG:terminated_at | None |
| accessIPv4 | None |
| accessIPv6 | None |
| addresses | provider=172.22.19.8 |
| adminPass | 9ZYMUC9HULnv |
| config_drive | None |
| created | 2025-02-03T06:52:55Z |
| description | None |
| flavor | description=, disk='1', ephemeral='0', , id='m1.nano', is_disabled=, is_public='True', |
| | location=, name='m1.nano', original_name='m1.nano', ram='64', rxtx_factor=, swap='0', |
| | vcpus='1' |
| hostId | 9edd54905ea9dce4189babcb1424ea5cc082dea3f6d876bfd5749446 |
| host_status | UP |
| id | 19ed87ea-b380-4381-9b58-03c8f48cad92 |
| image | cirros (654f6256-3b26-4579-99bc-8a2f55690b81) |
| key_name | demokey |
| locked | None |
| locked_reason | None |
| name | demo-instance |
| pinned_availability_zone | None |
| progress | None |
| project_id | da47f1e805ef4f5c95ede8daab5f5f4f |
| properties | None |
| security_groups | name='default' |
| server_groups | None |
| status | ACTIVE |
| tags | |
| trusted_image_certificates | None |
| updated | 2025-02-03T06:53:29Z |
| user_id | 92181c8807d541368fdc3ffaee1f0168 |
| volumes_attached | |
+-------------------------------------+---------------------------------------------------------------------------------------------+
[root@controller ~]$ openstack server list
+--------------------------------------+---------------+--------+----------------------+--------+---------+
| ID | Name | Status | Networks | Image | Flavor |
+--------------------------------------+---------------+--------+----------------------+--------+---------+
| 19ed87ea-b380-4381-9b58-03c8f48cad92 | demo-instance | ACTIVE | provider=172.22.19.8 | cirros | m1.nano |
+--------------------------------------+---------------+--------+----------------------+--------+---------+
This triggered the instance creation and you can watch the event with:
[root@controller ~]$ openstack server event list demo-instance
+------------------------------------------+--------------------------------------+--------+----------------------------+
| Request ID | Server ID | Action | Start Time |
+------------------------------------------+--------------------------------------+--------+----------------------------+
| req-69a0028a-f2ef-4c9d-9213-e137c5b09470 | c5e4728d-819e-4c10-b893-7337fd91d606 | create | 2025-01-27T09:57:36.648465 |
+------------------------------------------+--------------------------------------+--------+----------------------------+
[root@controller ~]$ openstack server event show demo-instance req-69a0028a-f2ef-4c9d-9213-e137c5b09470
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Field | Value |
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| action | create |
| events | details=, event='compute__do_build_and_run_instance', finish_time='2025-01-27T09:57:49.761092', host='compute.it.dbi-services.com', |
| | host_id='59222072a40332e03d274c533afc51348f1c4cf81b55bf9e618d7ece', result='Success', start_time='2025-01-27T09:57:40.211637', traceback= |
| id | req-69a0028a-f2ef-4c9d-9213-e137c5b09470 |
| message | None |
| project_id | 920bf34a6c88454f90d405124ca1076d |
| request_id | req-69a0028a-f2ef-4c9d-9213-e137c5b09470 |
| start_time | 2025-01-27T09:57:36.648465 |
| user_id | 3d6998879b6c4fdd91ba4b6ec00b7157 |
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
Looking at the log in the dashboard, all looks fine:

Ready to connect and check connectivity to the internet:
[root@controller ~]$ ssh [email protected]
[email protected]'s password:
$ nslookup www.dbi-services.com
Server: 8.8.4.4
Address 1: 8.8.4.4 dns.google
Name: www.dbi-services.com
Address 1: 2a06:98c1:3120::7
Address 2: 188.114.96.7
Address 3: 188.114.97.7
All fine, so we’re good to use the instance for whatever purpose. If you need access to the console, this can easily be done over the dashboard:

That’s it for the introduction posts to OpenStack. From here on, you should be ready to move on, either by adding additional components such as block or object storage, or harden the environment (for now all is based on http and no traffic is encrypted).