How To Create Private Networks in OpenStack using Terraform

OpenStack private networks enable instances to be reached safely without being exposed to the public internet. Private networks are vital for internal services, database layers, or application layers.

In this post, we’re going to automate private networks and subnets creation using a Terraform module stored in a github repository.

Prerequisites

  • Terraform installed
  • OpenStack credentials and network access
  • OpenStack provider properly configured

Step 1: Install Terraform

If you don’t have terraform installed, run one of the following commands that match your working environment:

# Ubuntu/Debian
wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform

# CentOS/RHEL
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
sudo yum -y install terraform

# Fedora
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager addrepo --from-repofile=https://rpm.releases.hashicorp.com/fedora/hashicorp.repo
sudo dnf -y install terraform

# Amazon Linux
sudo yum install -y yum-utils shadow-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo
sudo yum -y install terraform

# macOS Homebrew
brew tap hashicorp/tap
brew install hashicorp/tap/terraform

Step 2: Configure Terraform Provider

To authenticate Terraform with OpenStack, define the provider as follows in your main.tf file:

# Define required providers
terraform {
  required_version = ">= 0.14.0"
  required_providers {
    openstack = {
      source = "terraform-provider-openstack/openstack"
      version = "~> 2.1.0"
    }
  }
}

# Configure the OpenStack Provider
provider "openstack" {
  user_name   = "admin"
  tenant_name = "admin"
  password    = "pwd"
  auth_url    = "http://myauthurl:5000/v3"
  region      = "RegionOne"
}

For a local statefile, you can configure it as follows:

terraform {
  backend "local" {
    path = "${path.module}/terraform.tfstate"
  }
}

Step 3: The Network Module Overview

The netowork module uses resources such as the openstack_networking_network_v2 to create private networks and subnets. This module creates a private network, a private subnet, a router, and attaches the subnet to the private network.

It utilizes four main configuration files to achieve this:

  • data.tf: Defines data sources
  • main.tf: Contains resource definitions
  • outputs.tf: Declares input variables
  • variables.tf: Defines module outputs

The files are configured as follows:

data.tf

This file defines data sources to retrieve existing OpenStack resources, such as the external network:

# Data source to get the external network ID
data "openstack_networking_network_v2" "external_network" {
  name = var.external_network_name
}
main.tf

This file contains the primary resource definitions for creating the network and subnet:

# Create a private network
resource "openstack_networking_network_v2" "private_network" {
  name           = var.network_name
  admin_state_up = true
}

# Create a private subnet
resource "openstack_networking_subnet_v2" "private_subnet" {
  name            = var.subnet_name
  network_id      = openstack_networking_network_v2.private_network.id
  cidr            = var.subnet_cidr
  ip_version      = 4
  dns_nameservers = var.dns_nameservers
}

# Create a router
resource "openstack_networking_router_v2" "router" {
  name                = "${var.network_name}-router"
  admin_state_up      = true
  external_network_id = data.openstack_networking_network_v2.external_network.id
}

# Attach the private subnet to the router
resource "openstack_networking_router_interface_v2" "router_interface" {
  router_id = openstack_networking_router_v2.router.id
  subnet_id = openstack_networking_subnet_v2.private_subnet.id
}
variables.tf

This file declares the input variables required by the module:

variable "network_name" {
  description = "The name of the private network"
  type        = string
}

variable "subnet_name" {
  description = "The name of the private subnet"
  type        = string
}

variable "subnet_cidr" {
  description = "The CIDR block of the private subnet"
  type        = string
}

variable "external_network_name" {
  description = "The name of the external network"
  type        = string
}

variable "region" {
  description = "The region in which to create the network resources"
  type        = string
  default     = "RegionOne"
}

variable "dns_nameservers" {
  description = "List of DNS nameservers for the subnet"
  type        = list(string)
  default     = ["8.8.8.8", "8.8.4.4"]
}
outputs.tf

This file defines the outputs of the module, which can be used by other modules or resources:

variable "network_name" {
  description = "The name of the private network"
  type        = string
}

variable "subnet_name" {
  description = "The name of the private subnet"
  type        = string
}

variable "subnet_cidr" {
  description = "The CIDR block of the private subnet"
  type        = string
}

variable "external_network_name" {
  description = "The name of the external network"
  type        = string
}

variable "region" {
  description = "The region in which to create the network resources"
  type        = string
  default     = "RegionOne"
}

variable "dns_nameservers" {
  description = "List of DNS nameservers for the subnet"
  type        = list(string)
  default     = ["8.8.8.8", "8.8.4.4"]
}

Step 4: Using the Module

Configure your main.tf file as follows:

module "network" {
  source = "git::https://github.com/cloudspinx/terraform-openstack.git//modules/network?ref=main"

  network_name          = privatenet
  subnet_name           = privatenet_subnet
  subnet_cidr           = 172.34.50.0/24
  external_network_name = public
  region                = RegionOne
  dns_nameservers       = ["8.8.8.8", "8.8.4.4"]
}

Run the following terraform commands to deploy the resources:

terraform init
terraform apply

The private network and subnet should be created on your OpenStack cloud.

Optional: Run the module locally

If you want to customize the module to match your needs, it’s best to clone the repo and run the module locally on your working environment:

git clone https://github.com/cloudspinx/terraform-openstack.git

Create a main.tf file in the root folder for module usage configs.

terraform-openstack/
├── main.tf               # Provider and module usage configs                   
├── modules               # Modules, including kepair
│   ├── network/          # The module you're using
│   │   ├── data.tf
│   │   ├── main.tf       # Define resouces
│   │   ├── variables.tf  # Define any variables
│   │   ├── outputs.tf    # Optional outputs 
│   └── other_modules/

Be sure to reference the module path in your source. See below:

module "network" {
  source = "./modules/network"

  network_name          = privatenet
  subnet_name           = privatenet_subnet
  subnet_cidr           = 172.34.50.0/24
  external_network_name = public
  region                = RegionOne
  dns_nameservers       = ["8.8.8.8", "8.8.4.4"]
}

Run the following commands in your OpenStack environment to verify the resource creation:

openstack network list
openstack subnet list

Join our Linux and open source community. Subscribe to our newsletter for tips, tricks, and collaboration opportunities!

Recent Post

Unlock the Right Solutions with Confidence

At CloudSpinx, we don’t just offer services - we deliver clarity, direction, and results. Whether you're navigating cloud adoption, scaling infrastructure, or solving DevOps challenges, our seasoned experts help you make smart, strategic decisions with total confidence. Let us turn complexity into opportunity and bring your vision to life.

Leave a Comment

Your email address will not be published. Required fields are marked *

Related Post

OpenStack Security Groups provide an extremely powerful and very effective way of controlling and managing both the incoming and outgoing […]

The flavors in OpenStack specify the compute, memory, and storage resources available to virtual machines (instances). The configurations that specify […]

Node.js is an open-source platform built on Chrome’s JavaScript runtime environment to help developers build fast and scalable network applications. […]

Let's Connect

Unleash the full potential of your business with CloudSpinx. Our expert solutions specialists are standing by to answer your questions and tailor a plan that perfectly aligns with your unique needs.
You will get a response from our solutions specialist within 12 hours
We understand emergencies can be stressful. For immediate assistance, chat with us now

Contact CloudSpinx today!

Download CloudSpinx Profile

Discover the full spectrum of our expertise and services by downloading our detailed Company Profile. Simply enter your first name, last name, and email address.