Architecting Private Cloud Infrastructure with the Terraform OpenStack Provider

Infrastructure as Code (IaC) has revolutionized the way technical teams deploy and manage resources, moving away from manual dashboard clicks toward version-controlled, declarative configurations. Terraform, an open-source IaC tool, serves as a blueprint for infrastructure, enabling the automated provisioning of networks, servers, and cloud platforms. When applied to OpenStack—which powers a vast number of global private clouds and select public offerings—Terraform provides a standardized workflow identical to that used by cloud teams managing AWS or GCP, but applied specifically to a private cloud environment.

The Terraform OpenStack provider acts as the essential translation layer, converting HashiCorp Configuration Language (HCL) defined in .tf files into the specific API calls required by the OpenStack orchestration platform. Whether the target environment is a DevStack instance for development, a small-scale private cloud, or a massive multi-tenant production environment, the provider remains compatible as long as the deployment exposes the standard OpenStack APIs.

Understanding the OpenStack Provider Ecosystem

In the Terraform ecosystem, providers are categorized by who maintains them, which dictates their support lifecycle and governance. The OpenStack provider is classified as a Community provider, meaning it is maintained by open-source community members rather than directly by HashiCorp or a specific corporate partner.

The following table delineates the different types of providers available within the Terraform framework:

Provider Type Maintenance Entity Description
Official HashiCorp Maintained directly by the creators of Terraform.
Partner Technology Partners Maintained by companies that partner officially with HashiCorp.
Community Open Source Community Maintained by independent developers and the community.

For users who wish to contribute to the provider or build it from source, the project is hosted on GitHub. Development requires Go version 1.24 or higher. The build process is streamlined via a Makefile:

```bash

Clone the repository

git clone [email protected]:terraform-provider-openstack/terraform-provider-openstack.git

Enter the provider directory

cd terraform-provider-openstack

Build the provider binary

make build
```

The project utilizes GitHub Actions for continuous integration, automatically building and publishing assets for release when a tag matching the v* pattern (e.g., v0.1.0) is pushed. Releases are initially created as drafts and become available via the Terraform Registry once published.

Installation and Environment Setup

Before configuring the provider, Terraform must be installed on the management host (jump host). While Terraform is available as a binary for most operating systems, it can be installed via package managers on Linux distributions. For those using CentOS, the installation involves adding the HashiCorp repository before installing the binary.

```bash

Add the HashiCorp repository

sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo

Install Terraform

sudo dnf install terraform -y

Verify installation

terraform --version
```

Authentication and Credential Acquisition

Successful orchestration requires valid authentication to the OpenStack Keystone identity service. The provider supports multiple authentication methods, including usernames and passwords, application credentials, or tokens.

The most efficient method for acquiring these credentials is through the Horizon dashboard. By navigating to Project > API Access and selecting "Download OpenStack RC File," users can obtain a shell script containing all necessary authentication details.

Required Authentication Parameters

To establish a connection, the following parameters are typically required:

  • auth_url: The endpoint for the Keystone identity service.
  • region: The specific OpenStack region being targeted.
  • tenant_name: The project or tenant name.
  • user_name: The identity of the user.
  • password: The secret key for the user.
  • userdomainname: Required for Keystone v3 (often "Default").
  • projectdomainname: Required for Keystone v3 (often "Default").

For users who prefer using the OpenStack CLI alongside Terraform, the openstack --os-cloud application_credentials <command> flag can be used to maintain persistent access.

Provider Declaration and Configuration

The first step in any Terraform project is the creation of a .tf file (commonly main.tf or versions.tf) to declare the required provider and versioning.

Versions Declaration

Specifying the Terraform version and the provider version ensures environment stability and prevents breaking changes during terraform init.

```hcl

versions.tf - Declare the OpenStack provider

terraform {
requiredversion = ">= 1.0"
required
providers {
openstack = {
source = "terraform-provider-openstack/openstack"
version = "~> 3.4"
}
}
}
```

Note: Depending on the specific project requirements, some environments may use older version constraints such as required_version = ">= 0.14.0" with provider versions like ~> 1.48.0 or 1.49.0.

Configuration Methods

There are two primary ways to configure the OpenStack provider: Direct Configuration and Cloud Configuration.

Direct Configuration

Direct configuration explicitly defines credentials within the HCL. While this is straightforward, it is recommended to use variables for sensitive data like passwords.

```hcl

provider.tf - Configure with explicit credentials

provider "openstack" {
authurl = "https://keystone.example.com:5000/v3"
region = "RegionOne"
tenant
name = "my-project"
username = var.osusername
password = var.ospassword
user
domainname = "Default"
project
domain_name = "Default"
}

variable "os_username" {
type = string
}

variable "os_password" {
type = string
}
```

Cloud Configuration

Alternatively, Terraform can leverage an existing OpenStack cloud configuration file (typically clouds.yaml), allowing for a cleaner provider block.

```hcl

main.tf

terraform {
requiredversion = ">= 0.14.0"
required
providers {
openstack = {
source = "terraform-provider-openstack/openstack"
version = "~> 1.48.0"
}
}
}

Configure using a predefined cloud profile

provider "openstack" {
cloud = "garr_cli"
}
```

Once the provider is declared and configured, running terraform init downloads the necessary provider binary and initializes the working directory for deployment.

Resource Provisioning: Admin vs. Tenant Perspectives

A critical distinction in OpenStack management is the difference between the Admin perspective and the Tenant perspective. Effective cloud governance requires splitting these concerns into separate Terraform configurations or directories.

Admin-Level Provisioning

Admin-level configurations focus on the foundational elements of the cloud. This includes the creation of external networks, routers, global images, flavor definitions, user accounts, tenant profiles, and quota allocations.

For example, when managing admin resources, it is common to create a dedicated directory (e.g., AdminTF) and use an admin-privileged account.

```hcl

AdminTF/main.tf

provider "openstack" {
username = "OSUSERNAME"
tenantname = "admin"
password = "OS
PASSWORD"
authurl = "OSAUTHURL"
region = "OS
REGION"
}

Define a small flavor

resource "openstackcomputeflavorv2" "small-flavor" {
name = "small"
ram = "4096"
vcpus = "1"
disk = "0"
flavor
id = "1"
is_public = "true"
}

Define a medium flavor

resource "openstackcomputeflavor_v2" "medium-flavor" {
name = "medium"
ram = "8192"
vcpus = "2"
disk = "0"
}
```

Tenant-Level Provisioning

Tenant-level orchestration involves deploying actual workloads. This includes creating private networks, subnets, and the compute instances that will run applications.

Network Infrastructure

The openstack_networking_network_v2 resource is used to define the virtual network, while openstack_networking_subnet_v2 defines the IP address range within that network.

```hcl

Create a private network

resource "openstacknetworkingnetworkv2" "tf-network" {
name = "tf-network"
admin
state_up = true
}

Create a subnet attached to the network

resource "openstacknetworkingsubnetv2" "tf-subnet-1" {
name = "tf-subnet-1"
network
id = openstacknetworkingnetwork_v2.tf-network.id
cidr = "192.168.1.0/24"
}
```

Comparative Analysis of Deployment Workflows

The following table compares the manual approach to OpenStack management versus the Terraform-driven approach.

Feature Manual (Horizon/CLI) Terraform (IaC)
Configuration Imperative/Manual Declarative/Coded
Reproducibility Low (prone to human error) High (identical environments)
Version Control None Git-integrated (GitOps)
Speed of Deployment Slow (sequential steps) Fast (parallel resource creation)
Auditability Logs (hard to parse) Commit history (exact changes)
Scalability Limited by operator speed Highly scalable via modules

Technical Deep Dive: Resource Lifecycle

When a user executes Terraform commands against an OpenStack cluster, the provider follows a specific lifecycle to ensure the desired state matches the actual state of the cloud.

  1. Initialization: terraform init downloads the terraform-provider-openstack binary based on the source and version specified in the terraform block.
  2. Planning: terraform plan queries the OpenStack APIs to compare the existing infrastructure with the .tf files. It determines which resources need to be created, modified, or destroyed.
  3. Application: terraform apply sends the API requests to Keystone (for auth), Neutron (for networking), Nova (for compute), and Cinder/Swift (for storage).
  4. State Management: Terraform maintains a state file that tracks the mapping between the HCL resource names and the OpenStack UUIDs.

Conclusion

The Terraform OpenStack provider transforms private cloud management from a series of manual, error-prone tasks into a streamlined, professional DevOps pipeline. By leveraging the provider, organizations can treat their private cloud as a programmable entity, enabling the same agility and scalability found in public cloud environments.

The strategic separation of Admin and Tenant configurations allows for a robust governance model where cloud architects can define the "guardrails" (flavors, quotas, and external networks) while developers can independently provision their own environments (private networks and compute instances) within those boundaries. Whether building from the official registry or compiling the community provider from source using Go, the integration of Terraform and OpenStack ensures that infrastructure is documented, versioned, and repeatable. As private clouds grow in complexity, the transition to a declarative model via Terraform is no longer optional but a requirement for operational stability and scalability.

Sources

  1. https://opensource.com/article/23/1/terraform-manage-openstack-cluster
  2. https://oneuptime.com/blog/post/2026-02-23-how-to-configure-openstack-provider-in-terraform/view
  3. https://tendto.github.io/en/posts/openstack-with-terraform/
  4. https://github.com/terraform-provider-openstack/terraform-provider-openstack

Related Posts