How To Create Security Groups in OpenStack using Terraform

OpenStack Security Groups provide an extremely powerful and very effective way of controlling and managing both the incoming and outgoing network traffic that is aimed at multiple instances within your cloud infrastructure environment. They work in much the same way as virtual firewalls, forming a barrier that will protect your resources, and are absolutely vital to the security and integrity of your whole cloud infrastructure system.

In this guide, we will be using a Terraform module to carefully define and then instantiate a security group with certain custom rules to suit a specific set of needs.

Prerequisites

Before proceeding, ensure you have:

  • Terraform installed.
  • OpenStack credentials and network access.
  • OpenStack provider already configured in your project.

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 Module Overview

This module uses the openstack_networking_secgroup_v2 resource type to create a security group and the openstack_networking_secgroup_rule_v2 resource type to create security group rules. The module utilizes three config files to function properly:

  • main.tf
  • variables.tf
  • outputs.tf

Let’s break them down.

main.tf

This file creates the security group and the associated rules:

resource "openstack_networking_secgroup_v2" "secgroup" {
  name = var.security_group_name
}

resource "openstack_networking_secgroup_rule_v2" "secgroup_rules" {
  count              = length(var.rules)
  direction          = var.rules[count.index].direction
  ethertype          = var.rules[count.index].ethertype
  protocol           = var.rules[count.index].protocol
  remote_ip_prefix   = var.rules[count.index].remote_ip_prefix
  security_group_id  = openstack_networking_secgroup_v2.secgroup.id
}
variables.tf

This defines the modules’ input variables:

variable "security_group_name" {
  description = "The name of the security group"
  type        = string
}

variable "rules" {
  description = "List of security group rules"
  type = list(object({
    direction        = string
    ethertype        = string
    protocol         = string
    remote_ip_prefix = string
  }))
}
outputs.tf

Defines the modules outputs:

output "security_group_id" {
  value = openstack_networking_secgroup_v2.secgroup.id
}

Step 4: Using the security_group Module

To use the module, add the following configs to your main.tf file:

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

  security_group_name = "test_sg"
  rules = [
    {
      direction = "ingress"
      ethertype = "IPv4"
      protocol  = "icmp"
      remote_ip_prefix = "0.0.0.0/0"
    },
    {
      direction = "ingress"
      ethertype = "IPv4"
      protocol  = "tcp"
      remote_ip_prefix = "0.0.0.0/0"
    },
    {
      direction = "egress"
      ethertype = "IPv4"
      protocol  = "tcp"
      remote_ip_prefix = "0.0.0.0/0"
    }
  ]
}
Apply the configuration

Initialize terraform and apply the condifguration:

terraform init
terraform apply

Terraform will show the plan and prompt you for approval. Once approved, your resources will be provisioned on your OpenStack cloud.

Verify that the Security Group:

openstack security group list
openstack security group rule list <security-group-id>

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
│   ├── security_group/   # The module you're using
│   │   ├── main.tf       # Define resources
│   │   ├── variables.tf  # Define any variables
│   │   ├── outputs.tf    # Optional outputs 
│   └── other_modules/

Be sure to reference the module path in your source insteag of the github url. See below:

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

  security_group_name = "test_sg"
  rules = [
    {
      direction = "ingress"
      ethertype = "IPv4"
      protocol  = "icmp"
      remote_ip_prefix = "0.0.0.0/0"
    },
    {
      direction = "ingress"
      ethertype = "IPv4"
      protocol  = "tcp"
      remote_ip_prefix = "0.0.0.0/0"
    },
    {
      direction = "egress"
      ethertype = "IPv4"
      protocol  = "tcp"
      remote_ip_prefix = "0.0.0.0/0"
    }
  ]
}

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

Floating IPs within OpenStack are important to ensure that there is proper external connectivity for virtual machine instances that are […]

OpenStack private networks enable instances to be reached safely without being exposed to the public internet. Private networks are vital […]

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

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.