Terraform: Create LoadBalancer in OpenStack

provider "openstack" {
  cloud = "lab-admin"
  use_octavia = true
}
 
# data "template_file" "user_data" {
#   template = file("user-data.txt")
# }
 
data "template_file" "user_data" {
  template = <<EOF
#cloud-config
package_update: true
packages:
 - nginx
runcmd:
 - hostname -f | sudo tee /var/www/html/index.nginx-debian.html
 - id > /tmp/debug
EOF
}
 
variable "http_instance_names" {
  type = set(string)
  default = ["www1", "www2"]
}
 
resource "openstack_compute_instance_v2" "http" {
  for_each    = var.http_instance_names
  name        = each.key
 #name = "www${count.index + 1}"
 #count = 2
 image_name = "Ubuntu 20.04 minimal"
 flavor_name = "m1.small"
 key_pair = "lab-key"
 security_groups = ["default"]
 user_data = data.template_file.user_data.rendered
 
 network {
   name = "demo-net"
 }
}
 
data "openstack_networking_network_v2" "network_1" {
  name = "demo-net"
}
 
data "openstack_networking_subnet_v2" "subnet_1" {
  name = "demo-subnet"
  network_id = data.openstack_networking_network_v2.network_1.id
}
 
# Create loadbalancer
resource "openstack_lb_loadbalancer_v2" "http" {
  name          = "demo-lb1"
  vip_subnet_id = data.openstack_networking_subnet_v2.subnet_1.id
}
 
# Create listener
resource "openstack_lb_listener_v2" "http" {
  name            = "demo-lb1-http-listener"
  protocol        = "TCP"
  protocol_port   = 80
  loadbalancer_id = openstack_lb_loadbalancer_v2.http.id
  #depends_on      = [openstack_lb_loadbalancer_v2.http]
 
  insert_headers = {
    X-Forwarded-For = "true"
    X-Forwarded-Proto = "true"
  }
}
 
# Create pool
resource "openstack_lb_pool_v2" "http" {
  name        = "demo-lb1-http-pool1"
  protocol    = "TCP"
  lb_method   = "ROUND_ROBIN"
  listener_id = openstack_lb_listener_v2.http.id
  #depends_on  = [openstack_lb_listener_v2.http]
}
 
# Add member to pool
resource "openstack_lb_member_v2" "http1" {
  for_each      = var.http_instance_names
  address       = openstack_compute_instance_v2.http[each.key].access_ip_v4
  protocol_port = 80
  pool_id       = openstack_lb_pool_v2.http.id
  subnet_id     = data.openstack_networking_subnet_v2.subnet_1.id
  #depends_on    = [openstack_lb_pool_v2.http]
}
 
# Get floating IP
resource "openstack_networking_floatingip_v2" "floatingip_1" {
  pool = "public"
}
 
# Associate floating IP to LoadBalancer
resource "openstack_networking_floatingip_associate_v2" "floatip_1" {
  floating_ip = openstack_networking_floatingip_v2.floatingip_1.address
  port_id = openstack_lb_loadbalancer_v2.http.vip_port_id
}
 
output "LoadBalancer_IP" {
  value = "http://${openstack_networking_floatingip_v2.floatingip_1.address}"
}

TERMINATED_HTTPS loadbalancer

resource "openstack_keymanager_secret_v1" "server_cert1" {
  name                      = "cert11"
  algorithm                 = "aes"
  bit_length                = 256
  mode                      = "cbc"
  payload                   = filebase64("cert1.p12")
  secret_type               = "opaque"
  payload_content_type      = "application/octet-stream"
  payload_content_encoding  = "base64"
}
 
resource "openstack_keymanager_secret_v1" "server_cert2" {
  name                      = "cert12"
  algorithm                 = "aes"
  bit_length                = 256
  mode                      = "cbc"
  payload                   = filebase64("cert2.p12")
  secret_type               = "opaque"
  payload_content_type      = "application/octet-stream"
  payload_content_encoding  = "base64"
}
 
# Create loadbalancer
resource "openstack_lb_loadbalancer_v2" "lb1" {
  name          = "test-lb1"
  vip_subnet_id = openstack_networking_subnet_v2.subnet_1.id
}
 
# Create HTTP listener
resource "openstack_lb_listener_v2" "lb_listener_http" {
  name            = "test-lb1-http-listener"
  protocol        = "HTTP"
  protocol_port   = 80
  loadbalancer_id = openstack_lb_loadbalancer_v2.lb1.id
  default_pool_id = openstack_lb_pool_v2.lb_pool_http.id
}
 
# Create HTTPS listener
resource "openstack_lb_listener_v2" "lb_listener_https" {
  name                        = "test-lb1-https-listener"
  protocol                    = "TERMINATED_HTTPS"
  protocol_port               = 443
  loadbalancer_id             = "${openstack_lb_loadbalancer_v2.lb1.id}"
  default_pool_id             = openstack_lb_pool_v2.lb_pool_http.id
  default_tls_container_ref   = "${openstack_keymanager_secret_v1.server_cert1.secret_ref}"
  sni_container_refs          = [ "${openstack_keymanager_secret_v1.server_cert1.secret_ref}", "${openstack_keymanager_secret_v1.server_cert2.secret_ref}" ]
}
 
# Create pool
resource "openstack_lb_pool_v2" "lb_pool_http" {
  name              = "test-lb1-http-pool1"
  protocol          = "HTTP"
  lb_method         = "ROUND_ROBIN"
  #listener_id      = openstack_lb_listener_v2.lb_listener_http.id
  loadbalancer_id   = "${openstack_lb_loadbalancer_v2.lb1.id}"
}
 
# Add member to pool
resource "openstack_lb_member_v2" "lb_member" {
  for_each      = var.az
  address       = openstack_compute_instance_v2.instance[each.key].access_ip_v4
  protocol_port = 80
  pool_id       = openstack_lb_pool_v2.lb_pool_http.id
  subnet_id     = openstack_networking_subnet_v2.subnet_1.id
}
 
# Get floating IP
resource "openstack_networking_floatingip_v2" "floatingip_1" {
  pool = "public"
}
 
# Associate floating IP to LoadBalancer
resource "openstack_networking_floatingip_associate_v2" "floatip_1" {
  floating_ip = try(length(var.lb_floating_ip), 0) > 0 ? var.lb_floating_ip : openstack_networking_floatingip_v2.floatingip_1.address
  port_id     = openstack_lb_loadbalancer_v2.lb1.vip_port_id
}

Links
https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/lb_loadbalancer_v2
https://cloudinit.readthedocs.io/en/latest/topics/examples.html
https://github.com/diodonfrost/terraform-openstack-examples/blob/master/04-instance-with-loadbalancer/070-loadbalancer.tf
https://github.com/syseleven/terraform-examples/blob/master/lbaas/main.tf
https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/lb_listener_v2
https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/networking_floatingip_associate_v2
# HTTPS
https://registry.terraform.io/providers/ftarasenko/openstack/latest/docs/resources/keymanager_container_v1
https://github.com/thobiast/terraform-openstack-loadbalancer/blob/master/main.tf
https://www.ps.kz/faq/cloud/vpc/terraform-loadbalancer-terminated-https