Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: Added load balancing application in terraform #150

Merged
merged 9 commits into from
Jun 25, 2024
26 changes: 26 additions & 0 deletions terraform_provisioning/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,31 @@
* This folder contains terraform scripts to manage openstack configurations
* These require a `clouds.yaml` in `~/.config/openstack/` to provide authentication

## Running the scripts
* The scripts require the terraform package to be installed
* To install terraform on ubuntu or any ubuntu derivative with snap installed:
```bash
snap install terraform --classic
```
* If you are confused please find further info [here](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli)
* To actually run the script, start by entering the directory of the script you want to run, e.g.:
```bash
cd load_balancing_application
```
* Then generate a plan, this will also tell you what actions terraform will perform:
* Note this will generate a plan file in the current directory
```bash
terraform plan -out plan --var-file=vars.tfvars
```
* After that, to actually "apply" the changes planned in the plan:
```bash
terraform apply plan
```
* To revert the changes, e.g. to change the number of instances, use:
```bash
terraform destroy --var-file=vars.tfvars
```

## private_network
* This terraform script creates a private network with a subnet domain of `10.0.0.x`
* It also adds a router to connect the private network to the external network
Expand All @@ -20,3 +45,4 @@
* A flavour name for the bastion and web vm's also
* A key pair to place on the bastion vm in order for you to access it
* The number of instances of the web vm to be created in order for effective load balancing
* Note you must use the ssh jumphost to access an application vm
130 changes: 130 additions & 0 deletions terraform_provisioning/load_balancing_application/deploy.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Define required providers
terraform {
required_version = ">= 0.14.0"
required_providers {
openstack = {
source = "terraform-provider-openstack/openstack"
version = "~> 1.53.0"
}
}
}

# States we will be using openstack
provider "openstack" {
cloud = "openstack"
}

# Creates a private network
resource "openstack_networking_network_v2" "private_network" {
name = "${var.deployment_name}-private_network"
admin_state_up = "true"
}

# Creates a subnet within our private network
resource "openstack_networking_subnet_v2" "subnet" {
name = "${var.deployment_name}-subnet"
network_id = openstack_networking_network_v2.private_network.id
cidr = "192.168.1.0/24"
ip_version = 4
}

# Creates a router within our network
resource "openstack_networking_router_v2" "router" {
name = "${var.deployment_name}-router"
external_network_id = var.external_network_id
}

# Connects the router to our subnet
resource "openstack_networking_router_interface_v2" "router_interface" {
router_id = openstack_networking_router_v2.router.id
subnet_id = openstack_networking_subnet_v2.subnet.id
}

# Create a load balancer and places it in the subnet we made earlier
resource "openstack_lb_loadbalancer_v2" "loadbalancer" {
name = "${var.deployment_name}-loadbalancer"
vip_subnet_id = openstack_networking_subnet_v2.subnet.id
vip_address = var.floating_ip
}

# Creating the bastion vm to access the other vm's
resource "openstack_compute_instance_v2" "bastion" {
name = "${var.deployment_name}-bastion"
image_name = var.image_name
flavor_name = var.flavor_name
key_pair = var.key_pair

network {
uuid = openstack_networking_network_v2.private_network.id
}
}

# Create a ssh listener for the bastion vm
resource "openstack_lb_listener_v2" "ssh_listener" {
name = "${var.deployment_name}-bastion-ssh"
protocol = "TCP"
protocol_port = 22
loadbalancer_id = openstack_lb_loadbalancer_v2.loadbalancer.id
timeout_client_data = 600000
timeout_member_connect = 600000
timeout_member_data = 600000
}

# Create an ssh listener for the web servers
resource "openstack_lb_listener_v2" "web_server_listener" {
name = "${var.deployment_name}-web_servers"
protocol = "TCP"
protocol_port = 80
loadbalancer_id = openstack_lb_loadbalancer_v2.loadbalancer.id
}

# Creating the ssh pool
resource "openstack_lb_pool_v2" "ssh_pool" {
name = "${var.deployment_name}-ssh-pool"
protocol = "TCP"
lb_method = "SOURCE_IP"
listener_id = openstack_lb_listener_v2.ssh_listener.id
}

# Creating a web_servers pool
resource "openstack_lb_pool_v2" "web_servers_pool" {
name = "${var.deployment_name}-web_servers_pool"
protocol = "TCP"
lb_method = "SOURCE_IP"
listener_id = openstack_lb_listener_v2.web_server_listener.id
}

# Adds the bastion to the ssh pool with the ssh listener
resource "openstack_lb_member_v2" "ssh_member" {
pool_id = openstack_lb_pool_v2.ssh_pool.id
address = openstack_compute_instance_v2.bastion.access_ip_v4
protocol_port = 22
depends_on = [ openstack_compute_instance_v2.bastion ]
}

# Creating the web_server member
resource "openstack_lb_member_v2" "web_server_member" {
pool_id = openstack_lb_pool_v2.web_servers_pool.id
count = length(openstack_compute_instance_v2.vm)
address = openstack_compute_instance_v2.vm[count.index].access_ip_v4
protocol_port = 80
}

# Create multiple vm's for web serving
resource "openstack_compute_instance_v2" "vm" {
name = format("${var.deployment_name}-vm-%d", count.index)
count = var.instances
image_name = var.image_name
flavor_name = var.flavor_name
key_pair = var.key_pair

network {
uuid = openstack_networking_network_v2.private_network.id
}

# Due to weird issue faced with terraform creating vm's before subnets are made
depends_on = [
openstack_networking_subnet_v2.subnet,
openstack_lb_loadbalancer_v2.loadbalancer
]
}
37 changes: 37 additions & 0 deletions terraform_provisioning/load_balancing_application/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
variable "deployment_name" {
description = "The name of the deployment (prepended to resources)"
type = string
}

variable "external_network_id" {
description = "The id of the external network to connect the router to"
type = string
}

variable "floating_ip" {
description = "The floating ip to attach to the load balancer to access the grafanas"
type = string
}

variable "image_name" {
description = "The name of the image you want to use for the instances"
type = string
default = "ubuntu-focal-20.04-nogui"
}

variable "flavor_name" {
description = "The name of the flavour that will be used by the instances"
type = string
default = "l3.nano"
max-amb marked this conversation as resolved.
Show resolved Hide resolved
}

variable "key_pair" {
description = "The key pair to put on the bastion and web-serving vm's"
type = string
}

variable "instances" {
description = "The number of web instances wanted"
type = number
default = 1
}
7 changes: 7 additions & 0 deletions terraform_provisioning/load_balancing_application/vars.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
deployment_name = ""
external_network_id = ""
max-amb marked this conversation as resolved.
Show resolved Hide resolved
floating_ip = ""
image_name = ""
flavor_name = ""
max-amb marked this conversation as resolved.
Show resolved Hide resolved
key_pair = ""
instances =
Loading