Vai al contenuto

Openstack With Terraform

Pubblicato:

Technologies

Openstack

Openstack is an open source cloud computing platform. It is composed of several services that can be used in conjunction to create a cloud environment, similar to the ones provided by AWS, GCP and Azure.

Terraform

Terraform is an infrastructure as code (IaC) tool. It allows to define the infrastructure of a project in a declarative way, and then apply the changes to the actual environment.
It will take care of creating, updating and deleting the resources to make sure the actual environment matches the desired one defined in the configuration files.

Setup

Openstack setup

In this snippet we assume that the Openstack environment is already up and running, and the user has access to it.
The Terraform plugin needs the correct credentials to connect to authenticate.
This can be achieved by creating the Application Credentials in the Openstack dashboard.
To store the credentials locally so they are easy to access, they can be saved in a configuration file ~/.config/openstack/clouds.yaml. It should look something like this:

# ~/.config/openstack/clouds.yaml
clouds:
  application_credentials:
    auth:
      auth_url: <auth_url>
      username: <username>
      project_id: <project_id>
      project_name: <project_name>
      user_domain_name: <user_domain_name>
    region_name: <region_name>
    interface: "public"
    identity_api_version: 3

To access it any time you want to use the Openstack cli, you can add the following flag:

openstack --os-cloud application_credentials <command>

Terraform setup

Terraform can be installed on any operating system, and it is available as a binary or as a package for some of the most common ones.
To work it in conjunction with Openstack, the Openstack provider will be used.

The first step to do so is to create a terraform file ending in .tf that will contain the provider’s configuration.

# main.tf

# Use the Openstack provider
terraform {
required_version = ">= 0.14.0"
  required_providers {
    openstack = {
      source  = "terraform-provider-openstack/openstack"
      version = "~> 1.48.0"
    }
  }
}

# Configure the OpenStack Provider
provider "openstack" {
  cloud = "garr_cli"
}

Calling terraform init will download the provider and initialize the working directory.

Resources

End result

Loading diagram...

Network

To create a network, the openstack_networking_network_v2 resource can be used.

# main.tf

resource "openstack_networking_network_v2" "network" {
  name           = "network"
  admin_state_up = "true"
}

Private networking

# main.tf
# Create a private network
resource "openstack_networking_network_v2" "tf-network" {
  name = "tf-network"
  admin_state_up = true # Needed for the network to be active
}

# Create a subnet
resource "openstack_networking_subnet_v2" "tf-subnet-1" {
  name       = "tf-subnet-1"
  network_id = openstack_networking_network_v2.tf-network.id
  cidr       = "192.168.1.0/24" # The subnet range
  ip_version = 4                # IPv4
}

Remote networking

# main.tf
# Get a floating IP from the public network.
# It should already exist in the Openstack environment
resource "openstack_networking_floatingip_v2" "tf-public-ip" {
  pool = <public network>
  description = "Public IP for web-server"
}

# Create a routing path from the public network
resource "openstack_networking_router_v2" "tf-router" {
  name = "tf-router"
  external_network_id = <public network id>
}

# Make the router interface access the private subnet
resource "openstack_networking_router_interface_v2" "tf-router-interface" {
  router_id = openstack_networking_router_v2.tf-router.id
  subnet_id = openstack_networking_subnet_v2.tf-subnet-1.id
}

Compute instance

# main.tf
# Key pair used to access the instance via SSH
resource "openstack_compute_keypair_v2" "tf-keypair" {
  name = "tf-keypair"
}

# Create a security group to associate to the instance
# This will allow SSH and HTTP(s) access
resource "openstack_compute_secgroup_v2" "sg-web-access" {
  name        = "sg-web-access"
  description = "Security group for instances that need to be accessed from the web"

  rule {
    from_port   = 22
    to_port     = 22
    ip_protocol = "tcp"
    cidr        = "0.0.0.0/0"
  }

  rule {
    from_port   = 80
    to_port     = 80
    ip_protocol = "tcp"
    cidr        = "0.0.0.0/0"
  }

  rule {
    from_port   = 443
    to_port     = 443
    ip_protocol = "tcp"
    cidr        = "0.0.0.0/0"
  }
}

# Compute instance
resource "openstack_compute_instance_v2" "web-server" {
  name            = "web-server"
  image_id        = <image id>
  flavor_name     = <flavour name>
  key_pair        = openstack_compute_keypair_v2.tf-keypair.name
  security_groups = ["sg-web-access"]

  network {
    name = "tf-network"
  }
}

Output

# main.tf
# Output the private key of the key pair
output "key_pair" {
  value = openstack_compute_keypair_v2.tf-keypair.private_key
}

# Output the public IP of the instance
output "server_public_ip" {
 value = openstack_networking_floatingip_v2.tf-public-ip.address
}

Use Terraform

Apply changes

To apply the changes, use the terraform apply command. If the resources are not present, Terraform will create them.
Terraform will ask for confirmation before applying the changes, and will show a summary of the changes that will be applied.

terraform apply

Destroy resources

To destroy the resources, use the terraform destroy command. All the resources created with the configuration will be destroyed.

terraform destroy