OpenStack Providery
https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs
# Configure the OpenStack Provider provider "openstack" { user_name = "admin" tenant_name = "admin" password = "pwd" auth_url = "http://myauthurl:5000/v2.0" region = "RegionOne" } # cloud.yaml provider "openstack" { cloud = "dev-foo" }
resource "openstack_networking_router_v2" "router_1" { name = "foo-router" external_network_id = "88934cac-8d55-40d5-8ff9-bde65011741d" } resource "openstack_networking_router_interface_v2" "terraform" { router_id = openstack_networking_router_v2.router_1.id subnet_id = openstack_networking_subnet_v2.subnet_1.id }
resource "openstack_compute_instance_v2" "basic" { name = "basic" image_id = "ad091b52-742f-469e-8f3c-fd81cadf0743" flavor_id = "3" key_pair = "my_key_pair_name" security_groups = ["default"] metadata = { this = "that" } network { name = "my_network" } }
Image
data "openstack_images_image_v2" "image_ubuntu_2204" { name = "Ubuntu 22.04" most_recent = true }
Floating IP
# network
https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/networking_floatingip_v2
# compute
https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/compute_floatingip_v2
resource "openstack_networking_floatingip_v2" "fip_1" { pool = "public" } resource "openstack_compute_floatingip_associate_v2" "fip_1" { floating_ip = openstack_networking_floatingip_v2.fip_1.address instance_id = openstack_compute_instance_v2.bastion.id }
openstack-check.tf
# Init provider terraform { required_providers { openstack = { source = "terraform-provider-openstack/openstack" } } } # Define variables (can be overwritten in terraform.tfvars) variable "test_cloud" { type = string default = "test-cloud" } variable "az" { type = set(string) default = ["az1", "az2", "az3"] } variable "test_keypair" { type = string default = "test-keypair" } variable "test_keypair_public_key" { type = string default = "~/openstack-checks-conf/id_rsa.pub" } variable "test_secgroup" { type = string default = "test-secgroup" } variable "test_network" { type = string default = "test-network" } variable "test_subnet" { type = string default = "test-subnet" } variable "test_subnet_cidr" { type = string default = "10.0.10.0/24" } variable "test_router" { type = string default = "test-router" } variable "rule_cidr_list" { default = [ "10.0.10.0/24" ] } variable "lb_floating_ip" { type = string default = "" } # Init OpenStack provider "openstack" { cloud = var.test_cloud } # Get OpenStack data resource "openstack_compute_keypair_v2" "keypair_1" { name = var.test_keypair public_key = file("${var.test_keypair_public_key}") } resource "openstack_networking_secgroup_v2" "secgroup_1" { name = var.test_secgroup description = var.test_secgroup } resource "openstack_networking_secgroup_rule_v2" "secgroup_rule_icmp" { direction = "ingress" ethertype = "IPv4" protocol = "icmp" security_group_id = openstack_networking_secgroup_v2.secgroup_1.id } resource "openstack_networking_secgroup_rule_v2" "secgroup_rule_tcp_22" { for_each = toset(var.rule_cidr_list) direction = "ingress" ethertype = "IPv4" protocol = "tcp" port_range_min = 22 port_range_max = 22 remote_ip_prefix = each.value security_group_id = openstack_networking_secgroup_v2.secgroup_1.id } resource "openstack_networking_secgroup_rule_v2" "secgroup_rule_tcp_80" { for_each = toset(var.rule_cidr_list) direction = "ingress" ethertype = "IPv4" protocol = "tcp" port_range_min = 80 port_range_max = 80 remote_ip_prefix = each.value security_group_id = openstack_networking_secgroup_v2.secgroup_1.id } resource "openstack_networking_network_v2" "network_1" { name = var.test_network } resource "openstack_networking_subnet_v2" "subnet_1" { network_id = openstack_networking_network_v2.network_1.id name = var.test_subnet cidr = var.test_subnet_cidr } resource "openstack_networking_router_v2" "router_1" { name = var.test_router external_network_id = data.openstack_networking_network_v2.public_network.id } resource "openstack_networking_router_interface_v2" "router_interface_1" { router_id = openstack_networking_router_v2.router_1.id subnet_id = openstack_networking_subnet_v2.subnet_1.id }
openstack-check-instance.tf
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 EOF } # Create instances in each AZ resource "openstack_compute_instance_v2" "instance" { for_each = var.az name = "test-u2204-${each.key}" image_name = "Ubuntu 22.04" flavor_name = "m1.micro" key_pair = openstack_compute_keypair_v2.keypair_1.name security_groups = [openstack_networking_secgroup_v2.secgroup_1.id] availability_zone = "ch-zh1-${each.key}" user_data = data.template_file.user_data.rendered force_delete = true network { uuid = openstack_networking_network_v2.network_1.id } depends_on = [openstack_networking_subnet_v2.subnet_1] } # Create instance with additional volume and floating IP in each AZ resource "openstack_compute_instance_v2" "instance_from_volume" { for_each = var.az name = "test-u2404-vol-${each.key}" flavor_name = "m1.micro" key_pair = openstack_compute_keypair_v2.keypair_1.name security_groups = [openstack_networking_secgroup_v2.secgroup_1.id] availability_zone = "ch-zh1-${each.key}" user_data = data.template_file.user_data.rendered force_delete = true block_device { uuid = openstack_blockstorage_volume_v3.volume_boot[each.key].id source_type = "volume" boot_index = 0 destination_type = "volume" delete_on_termination = false } network { uuid = openstack_networking_network_v2.network_1.id } depends_on = [openstack_networking_subnet_v2.subnet_1, openstack_blockstorage_volume_v3.volume_boot] } resource "openstack_compute_volume_attach_v2" "volume_attach" { for_each = var.az instance_id = openstack_compute_instance_v2.instance_from_volume[each.key].id volume_id = openstack_blockstorage_volume_v3.volume[each.key].id } data "openstack_networking_network_v2" "public_network" { name = "public" } resource "openstack_networking_floatingip_v2" "floatingip" { pool = data.openstack_networking_network_v2.public_network.name } data "openstack_networking_port_v2" "port1" { device_id = openstack_compute_instance_v2.instance_from_volume[tolist(var.az)[0]].id network_id = openstack_compute_instance_v2.instance_from_volume[tolist(var.az)[0]].network.0.uuid } resource "openstack_networking_floatingip_associate_v2" "instance_fip_association" { floating_ip = openstack_networking_floatingip_v2.floatingip.address port_id = data.openstack_networking_port_v2.port1.id }
openstack-check-volume.tf
# Create boot volume resource "openstack_blockstorage_volume_v3" "volume_boot" { for_each = var.az name = "test-vol1-boot-${each.key}" size = 10 availability_zone = "ch-zh1-${each.key}" image_id = openstack_images_image_v2.image_ubuntu_2404_minimal.id } # Create additional volume resource "openstack_blockstorage_volume_v3" "volume" { for_each = var.az name = "test-vol1-${each.key}" size = 10 availability_zone = "ch-zh1-${each.key}" }
openstack-loadbalancer.tf
# Certificate resource "openstack_keymanager_secret_v1" "server_cert1" { name = "cert1" 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 = "cert2" 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" 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 } # Add monitor for pool resource "openstack_lb_monitor_v2" "monitor_1" { pool_id = openstack_lb_pool_v2.lb_pool_http.id type = "HTTP" delay = 5 timeout = 10 max_retries = 5 } # 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 }
Cloud-init
https://learn.hashicorp.com/tutorials/terraform/cloud-init