This repository is intended for learning OpenStack and deploying a full OpenStack lab environment.
The lab is deployed on Libvirt/KVM, meaning all OpenStack instances run under nested virtualization.
Status
- Tested on Ubuntu only
- Intended for lab, learning, and experimentation purposes
Learning materials are primarily sourced from the official OpenStack documentation: https://docs.openstack.org/install-guide/openstack-services.html
-
Host OS: Ubuntu
-
Hypervisor: Libvirt + KVM
-
VM provisioning: Vagrant
-
Configuration management: Ansible
-
Storage backend: Ceph
-
Observability: OpenSearch, Prometheus, Grafana stack
-
Optional workloads:
- CI/CD Lab (GitLab, Jenkins, Runner, Prometheus)
- Kubernetes Lab (kubeadm-based)
Ensure the following tools are installed on your host OS:
-
QEMU + Libvirt https://documentation.ubuntu.com/server/how-to/virtualisation/libvirt/
-
Build tools
gcc,make, orbuild-essential(Ubuntu) -
Vagrant Libvirt provider https://vagrant-libvirt.github.io/vagrant-libvirt/installation.html
-
Ansible https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html
-
Custom Ansible collection https://github.com/merizrizal/ansible-collections-for-utilities
-
Load environment variables:
source envrc -
Navigate to the Vagrant directory:
cd vagrant -
Build the base Ubuntu image:
make -C base_image/ rebuild-base-image-ubuntu
This creates a reusable Vagrant box for:
- Controller node
- Compute nodes
- Storage node
- Ceph node
-
Create the provider network:
make -C controller/ start-provider-network
-
Start the OpenStack VMs:
make -C controller/ start-vm
This provisions:
- 1 Controller node
- 2 Compute nodes
- 1 Storage node
- 1 Ceph node
All Ceph provisioning is done using Ansible.
-
Load environment variables and navigate to Ansible:
source envrc cd ansible
-
Run the playbooks in sequence:
-
Pre-requisites:
ansible-playbook -i deploy_ceph/inventories/local/local.yml \ deploy_ceph/playbook_pre_setup.yml
-
Deploy Ceph ADM:
ansible-playbook -i deploy_ceph/inventories/local/local.yml \ deploy_ceph/playbook_setup_adm.yml
-
Install Ceph common packages:
ansible-playbook -i deploy_ceph/inventories/local/local.yml \ deploy_ceph/playbook_setup_common.yml
-
Apply OSDs:
ansible-playbook -i deploy_ceph/inventories/local/local.yml \ deploy_ceph/playbook_apply_osd.yml
-
Integrate Ceph with OpenStack (Cinder & Nova):
ansible-playbook -i deploy_ceph/inventories/local/local.yml \ deploy_ceph/playbook_openstack_init.yml
-
Alternatively, deploy everything at once:
ansible-playbook -i deploy_ceph/inventories/local/local.yml \
deploy_ceph/playbook_deploy.yml-
Load environment variables and navigate to Ansible:
source envrc cd ansible
-
Run the playbooks in sequence:
-
Pre-requisites:
ansible-playbook -i deploy_openstack/inventories/local/local.yml \ deploy_openstack/playbook_pre_setup.yml
-
Controller node:
ansible-playbook -i deploy_openstack/inventories/local/local.yml \ deploy_openstack/playbook_setup_controller.yml
-
Compute nodes:
ansible-playbook -i deploy_openstack/inventories/local/local.yml \ deploy_openstack/playbook_setup_compute.yml
-
Storage node:
ansible-playbook -i deploy_openstack/inventories/local/local.yml \ deploy_openstack/playbook_setup_storage.yml
-
ansible-playbook -i deploy_openstack/inventories/local/local.yml \
deploy_openstack/playbook_deploy.ymlAt this point, your OpenStack Lab should be operational.
-
Load environment variables and navigate to Ansible:
source envrc cd ansible
-
Deploy OpenSearch components individually:
-
OpenSearch:
ansible-playbook -i deploy_opensearch/inventories/local/local.yml \ deploy_opensearch/playbook_setup_opensearch.yml
-
OpenSearch Dashboards:
ansible-playbook -i deploy_opensearch/inventories/local/local.yml \ deploy_opensearch/playbook_setup_opensearch_dashboard.yml
-
Logstash and Filebeat:
ansible-playbook -i deploy_opensearch/inventories/local/local.yml \ deploy_opensearch/playbook_setup_filebeat.yml
-
-
Deploy Prometheus and Grafana components individually:
-
Prometheus and Grafana:
ansible-playbook -i deploy_prometheus/inventories/local/local.yml \ deploy_prometheus/playbook_setup_prometheus.yml
-
Prometheus node exporter:
ansible-playbook -i deploy_prometheus/inventories/local/local.yml \ deploy_prometheus/playbook_setup_node_exporter.yml
-
ansible-playbook -i deploy_opensearch/inventories/local/local.yml \
deploy_opensearch/playbook_deploy.yml
ansible-playbook -i deploy_prometheus/inventories/local/local.yml \
deploy_prometheus/playbook_deploy.ymlThis step initializes basic OpenStack resources.
-
Prepare a VM image in qcow2 format.
-
Export the image path:
export IMAGE_PATH=/path/to/image.qcow2 -
Copy the image to the Controller VM:
make -C vagrant/controller copy-image-to-vm
-
Bootstrap OpenStack:
source envrc cd ansible ansible-playbook -i bootstrap_openstack/inventories/local/local.yml \ bootstrap_openstack/playbook_bootstrap.yml
This configures:
- Flavors
- Glance images
- Provider / self-service networks
- Security groups
If OpenStack instances cannot access the internet and you are using:
- Custom bridge:
br-provider0 - Subnet:
192.168.123.0/24
Ensure NAT is configured on the bare-metal host:
sudo iptables -t nat -A POSTROUTING \
-s 192.168.123.0/24 \
-o <host-external-interface> \
-j MASQUERADETo auto-detect the external interface:
$(ip route get 1.1.1.1 | awk '{print $5}')This deploys GitLab, Jenkins, Runner, and Prometheus on OpenStack.
-
Load environment variables:
source envrc -
Generate OpenStack client config:
generate_os_client_config local cicd_lab -
Bootstrap CI/CD VMs:
cd ansible ansible-playbook -i bootstrap_openstack/inventories/local/local.yml \ bootstrap_openstack/playbook_init_cicd_server.yml -
Assign floating IPs via Horizon:
- URL: OpenStack Dashboard
- User:
admin - Password:
vagrant
-
Export cloud config:
export OS_CLIENT_CONFIG_FILE=$ROOT_DIR/generated/local_clouds.yml
-
Provision services:
-
Pre-setup:
ansible-playbook -i cicd_in_openstack/inventories/local/openstack.yml \ cicd_in_openstack/playbook_pre_setup.yml
-
GitLab:
ansible-playbook -i cicd_in_openstack/inventories/local/openstack.yml \ cicd_in_openstack/playbook_setup_gitlab.yml
-
Jenkins:
ansible-playbook -i cicd_in_openstack/inventories/local/openstack.yml \ cicd_in_openstack/playbook_setup_jenkins.yml
-
Runner:
ansible-playbook -i cicd_in_openstack/inventories/local/openstack.yml \ cicd_in_openstack/playbook_setup_runner.yml
-
Prometheus:
ansible-playbook -i cicd_in_openstack/inventories/local/openstack.yml \ cicd_in_openstack/playbook_setup_ci_monitor.yml
-
Node Exporter:
ansible-playbook -i cicd_in_openstack/inventories/local/openstack.yml \ cicd_in_openstack/playbook_setup_node_exporter.yml
-
This provisions a kubeadm-based Kubernetes cluster on OpenStack.
-
Load environment variables:
source envrc -
Generate OpenStack client config:
generate_os_client_config local kubernetes_lab -
Bootstrap Kubernetes VMs:
cd ansible ansible-playbook -i bootstrap_openstack/inventories/local/local.yml \ bootstrap_openstack/playbook_init_kubernetes.yml -
Assign floating IPs via Horizon.
- URL: OpenStack Dashboard
- User:
admin - Password:
vagrant
-
Export cloud config:
export OS_CLIENT_CONFIG_FILE=$ROOT_DIR/generated/local_clouds.yml
-
Provision Kubernetes:
-
Pre-setup:
ansible-playbook -i kubernetes_in_openstack/inventories/local/openstack.yml \ kubernetes_in_openstack/playbook_pre_setup.yml
-
Install Kubernetes:
ansible-playbook -i kubernetes_in_openstack/inventories/local/openstack.yml \ kubernetes_in_openstack/playbook_setup_kubernetes.yml
-
Configure nodes:
ansible-playbook -i kubernetes_in_openstack/inventories/local/openstack.yml \ kubernetes_in_openstack/playbook_setup_nodes.yml
-
For collaboration, questions, or discussions:
Email: meriz.rizal@gmail.com