Public clouds like AWS, GCP, and Azure get most of the attention these days, but there's another player that deserves some love: the private cloud. If you've ever wondered why so many companies still rely on private infrastructure, it usually comes down to two things: regulatory requirements or cost control. Cloud bills can spiral out of control faster than you'd think.
Private clouds come in two flavors. Internal private clouds live in your own data centers, while hosted private clouds are managed by third-party providers. OpenStack is one of the frameworks that makes managing these environments possible, and it's what we're diving into today.
OpenStack is an open source framework for managing both public and private cloud infrastructure. When you provision resources in any cloud environment, you're essentially hitting an API that talks to data center management software, which then carves out virtual resources from physical hardware pools.
The interesting thing about working with OpenStack is that it strips away all the automation you take for granted in major public clouds. You get a much clearer view of what's actually happening under the hood to make a data center work. It's eye-opening, even if it can be frustrating at first.
👉 Explore reliable private cloud hosting solutions with dedicated resources
Before jumping into commands, let's talk about how OpenStack organizes things.
Everything lives inside projects (which used to be called tenants in older versions). Your OpenStack admin creates these projects and assigns resource quotas - things like VCPUs, RAM, number of VM instances, and storage. Hit your quota limit and OpenStack won't let you create more resources. Simple as that.
Inside a project, you'll work with several key resources:
Flavors define your VM hardware specs - pre-configured combinations of RAM and VCPUs. Your admin typically sets these up for you.
Images are your base VM configurations. Think Ubuntu, CentOS, Windows 10, or whatever OS you need. These can be bare-bones installations or come with pre-installed software. Images can be public (everyone can use them), community, shared, or private to your project.
Instances are the actual VMs you spin up using those images.
Key pairs handle public key authentication so you can SSH into your machines.
Security groups contain firewall rules that control traffic to and from your VMs. Each security group rule defines specific access patterns.
Let's get your local machine ready to talk to OpenStack.
You'll need Python 3.8 or higher installed. I recommend setting up a virtual environment to keep things clean:
pip3 install virtualenv
virtualenv venv
source venv/bin/activate
python -m pip install --upgrade pip
Now install the OpenStack CLI:
pip install python-openstackclient
Check that it worked:
openstack --version
OpenStack has an older authentication method using openrc.sh files, but there's a cleaner approach: the OpenStack SDK with clouds.yaml configuration.
First, install the SDK:
pip install openstacksdk
Create your configuration directory and file:
mkdir -p ~/.config/openstack
touch ~/.config/openstack/clouds.yaml
Your clouds.yaml file lets you define multiple cloud configurations in one place. Each "cloud" is just a named set of connection details for a specific project. You could have one for development, one for production, whatever you need.
The beauty of this approach is switching between projects. You can either set an environment variable:
export OS_CLOUD=os_tenant1
openstack user show
Or pass it directly in each command:
openstack --os-cloud=os_tenant1 user show
Pick whichever feels more natural for your workflow.
Now for the fun part - actually building something.
You'll need a security group to control access to your VMs. There's always a default one in your project, but creating your own gives you more control:
export OS_CLOUD="os_tenant1"
openstack security group create "foo"
openstack security group rule create --ethertype "IPv4" --ingress --dst-port "22" --protocol "TCP" --remote-ip "" "foo"
The security group rule here allows SSH access from specific IP addresses. You can set ingress or egress rules, specify TCP, UDP, or ICMP protocols, define port ranges, and use CIDR notation for IP blocks.
Before creating a VM, check what flavors and images are available:
openstack flavor list
openstack image list
The flavor list shows you machine specs - how much RAM and how many VCPUs you'll get. The image list shows available operating systems and pre-configured software stacks.
👉 Get started with powerful dedicated servers for your infrastructure needs
Create your VM instance:
openstack server create --image --flavor --security-group
Grab your VM's IP address and SSH in:
VM_IP=$(openstack server show foo1 -f json | jq '.addresses.[0]' | tr -d '"')
ssh @$VM_IP
If you don't have jq installed for JSON parsing, install it with brew install jq on Mac.
Here are some commands you'll use regularly:
List all servers: openstack server list
Delete a server: openstack server delete <server_name>
View security groups: openstack security group list
Find an image ID: openstack image list -f json | jq '.[] | select(.Name|test("^<image_name>")) | .ID' | tr -d '"'
OpenStack gives you direct control over cloud infrastructure in a way that public clouds abstract away. The initial setup takes some work, but once you're past that, you have a powerful framework for managing virtual resources.
You now know how to install the OpenStack CLI and SDK, configure authentication with clouds.yaml, create security groups and firewall rules, provision VM instances, and access your machines via SSH.
The learning curve can feel steep, especially when OpenStack documentation sends you on scavenger hunts. But stick with it. Understanding how these pieces fit together makes you better at working with any cloud infrastructure, public or private.