Openstack: Some first steps (Tofu revisited)
I wrote an article regarding some initial configuration of Openstack. The very few steps required:

I strongly recommend reading that article in order to understand. I would also recommend reading the article I wrote about installing Openstack locally using Terraform/OpenTofu.

I am going to explain now how can I configure the newly installed Openstack using OpenTofu (Terraform).
As I usually type tofu and terraform, I've created my alias for terraform. Yes, I know, it is clearer if I get used to type tofu, but I got tired of repeating the same command once and again. So, the alias:
alias terraform=tofuSo, what steps will I follow?
- Review the network configuration after my Openstack installation - There are some limitations in a default configuration of Linux, so I created a couple of scripts to make the Openstack networking properly run.
- I'll add a couple images to Glance, so I can create later new Virtual Servers.
- I'll add a few "Flavors", so I can tell my future Virtual Servers how much RAM, vCPUs and disk they can use.
- I'll create a couple of Networks, for sure my future Virtual machines will love to be accessed and used. They will be happy to connect to internet and watch interesting youtube videos.
- I'll create a new user. Yes, it is interesting doing things as an admin user, but I'd better create a new non admin user. Simply for security reasons.
- Finally, as non admin user, I'll show how to create a new Virtual Machines.
Openstack Provider for Terraform/OpenTofu
To configure the driver we need to define the following:
# Define required providers
terraform {
required_version = ">= 0.14.0"
required_providers {
openstack = {
source = "terraform-provider-openstack/openstack"
version = "~> 1.53.0"
}
}
}and run;
terraform initThe configuration part goes like this:
# Configure the OpenStack Provider
# Not needed if the environment variables are defined before running
# "tofu apply|destroy|state xx"
provider "openstack" {
user_name = "admin"
tenant_name = "admin"
password = "xxxx"
auth_url = "http://os-admin.openstack.mine:5000/v3"
region = "corporario"
}However, in Openstack, one standard way to configure this is using environment variables - If we use those environment variables, we can skip that configuration for the Openstack provider.
export OS_USERNAME="admin"
export OS_PROJECT_NAME="admin"
export OS_AUTH_URL=http://os-admin.openstack.mine:5000
export OS_REGION_NAME="corporario"
export OS_PROJECT_DOMAIN_ID="default"
export OS_INTERFACE=public
export OS_IDENTITY_API_VERSION=3
# As I deployed Openstack using kolla-ansible, I can get the admin password
# from the "password.yml" file.
export OS_PASSWORD=$(awk '$1 ~ /keystone_admin_password/ {print $2}' /etc/kolla/passwords.yml)Así que sólo tengo que ejecutarlo con source:
source ~/keystone-rc-admin.shAdd Images to glance
Manual Image downloads
Terraform is not designed for running local commands. We'll later need download a couple images (something like blueprint templates to create new virtual servers) and upload them to Openstack. Some of these images are compressed and we need to uncompress them before uploading them to openstack.
So, Lets download and uncompress those images - I'll do it in my /var/lib/libvirt/base-image-pool/ directory.
cd /var/lib/libvirt/base-image-pool/
# Download cirros
wget https://download.cirros-cloud.net/0.6.3/cirros-0.6.3-x86_64-disk.img
# Download Ubuntu-noble (24.04)
wget https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
# Download fedora coreos
wget https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/43.20260217.3.1/x86_64/fedora-coreos-43.20260217.3.1-qemu.x86_64.qcow2.xz
# I need to descompress before uploading to Openstack.
unxz fedora-coreos-43.20260217.3.1-qemu.x86_64.qcow2.xzUpload Image to Glance
In order to upload a new image to glance, I can add the following hclcode:
# basic example - Not used later.
resource "openstack_images_image_v2" "cirros" {
name = "cirros"
image_source_url = "https://download.cirros-cloud.net/0.6.3/cirros-0.6.3-x86_64-disk.img"
container_format = "bare"
disk_format = "qcow2"
visibility = "public"
properties = {
key = "value"
}
}... Three times. Or I could define a new variable with type map and iterate over the elements:
variable "images" {
description = "List of images to upload with some of their properties"
type = map(object({
filename = string
}))
default = {
cirros = {
filename = "/var/lib/libvirt/base-image-pool/cirros-0.6.3-x86_64-disk.img"
}
ubuntu-2404 = {
filename = "/var/lib/libvirt/base-image-pool/noble-server-cloudimg-amd64.img"
}
fedoracore-43 = {
filename = "//var/lib/libvirt/base-image-pool/fedora-coreos-43.20260217.3.1-qemu.x86_64.qcow2"
}
}
}
resource "openstack_images_image_v2" "images" {
for_each = var.images
name = each.key
local_file_path = each.value.filename
container_format = "bare"
disk_format = "qcow2"
visibility = "public"
properties = {
key = "value"
}
}After running terraform apply, we'll have the images there:
