Terraform
Terraform is one of the most famous IaaC (Infrastructure as a code) tools that is widely used to provision resources on top of well known cloud providers.
The idea of this example is to create the following:
- A router connected to the public gateway
- A network to have the VMs in
- A subnet in the created network
- A keypair to allow SSH
- 2 VMs (frontend and backend)
- 2 floating IPs
- Multiple security groups
Steps:
Installation: Follow this Guide to install Terraform on the target OS
Create a directory to contain the terraform (.tf) files
mkdir bluvalt-terraformCreate a terraform file for configs
touch configs.tfAdd the following snippet to
configs.tf:terraform { required_providers { openstack = { source = "terraform-provider-openstack/openstack" version = "~> 1.48.0" } } } provider "openstack" { user_name = "<Your Username>" tenant_name = "<Your Tenant Name>" password = "<Your Password>" auth_url = "https://api-<Cloud Domain>-vdc.bluvalt.com/identity/v3" user_domain_name = "<Cloud Domain>" project_domain_name = "<Cloud Domain>" }To access STC Jeddah Cloud JED1, replacewithjed1To access STC Riyadh2 Cloud RUH2, replacewithruh2`Create a terraform file for resources
touch resources.tfAdd the following snippet to
resources.tf:data "openstack_images_image_v2" "ubuntu" { name = "Ubuntu-18.04-LTS" most_recent = true } data "openstack_networking_network_v2" "public" { name = "Public_Network" } resource "openstack_compute_keypair_v2" "terraform-keypair" { name = "terraform-keypair" } data "openstack_compute_flavor_v2" "r1-generic-8" { name = "R1-Generic-8" } resource "openstack_networking_network_v2" "terraform-network" { name = "terraform-network" admin_state_up = "true" } resource "openstack_networking_subnet_v2" "subnet-1" { network_id = "${openstack_networking_network_v2.terraform-network.id}" cidr = "10.1.0.0/16" ip_version = 4 } resource "openstack_networking_router_v2" "terraform-router" { name = "terraform-router" external_network_id = "${data.openstack_networking_network_v2.public.id}" } resource "openstack_networking_router_interface_v2" "router-subnet-interface" { router_id = "${openstack_networking_router_v2.terraform-router.id}" subnet_id = "${openstack_networking_subnet_v2.subnet-1.id}" } resource "openstack_compute_floatingip_v2" "backend" { pool = "Public_Network" } resource "openstack_compute_floatingip_v2" "frontend" { pool = "Public_Network" } resource "openstack_networking_secgroup_v2" "allow-http-https" { name = "allow-http-https" description = "HTTP HTTPS security group" } resource "openstack_networking_secgroup_rule_v2" "allow-http" { direction = "ingress" ethertype = "IPv4" protocol = "tcp" port_range_min = 80 port_range_max = 80 remote_ip_prefix = "0.0.0.0/0" security_group_id = "${openstack_networking_secgroup_v2.allow-http-https.id}" } resource "openstack_networking_secgroup_rule_v2" "allow-https" { direction = "ingress" ethertype = "IPv4" protocol = "tcp" port_range_min = 443 port_range_max = 443 remote_ip_prefix = "0.0.0.0/0" security_group_id = "${openstack_networking_secgroup_v2.allow-http-https.id}" } resource "openstack_networking_secgroup_v2" "allow-ssh" { name = "allow-ssh" description = "SSH security group" } resource "openstack_networking_secgroup_rule_v2" "allow-ssh" { direction = "ingress" ethertype = "IPv4" protocol = "tcp" port_range_min = 22 port_range_max = 22 remote_ip_prefix = "0.0.0.0/0" security_group_id = "${openstack_networking_secgroup_v2.allow-ssh.id}" } resource "openstack_compute_instance_v2" "backend" { name = "backend" flavor_id = "${data.openstack_compute_flavor_v2.r1-generic-8.id}" key_pair = "terraform-keypair" security_groups = ["allow-ssh", "allow-http-https"] block_device { uuid = "${data.openstack_images_image_v2.ubuntu.id}" source_type = "image" destination_type = "volume" boot_index = 0 volume_size = 20 delete_on_termination = true } network { name = "${openstack_networking_network_v2.terraform-network.name}" } } resource "openstack_compute_floatingip_associate_v2" "backend" { floating_ip = "${openstack_compute_floatingip_v2.backend.address}" instance_id = "${openstack_compute_instance_v2.backend.id}" fixed_ip = "${openstack_compute_instance_v2.backend.network.0.fixed_ip_v4}" } resource "openstack_compute_instance_v2" "frontend" { name = "frontend" flavor_id = "${data.openstack_compute_flavor_v2.r1-generic-8.id}" key_pair = "terraform-keypair" security_groups = ["allow-ssh", "allow-http-https"] block_device { uuid = "${data.openstack_images_image_v2.ubuntu.id}" source_type = "image" destination_type = "volume" boot_index = 0 volume_size = 20 delete_on_termination = true } network { name = "${openstack_networking_network_v2.terraform-network.name}" } } resource "openstack_compute_floatingip_associate_v2" "frontend" { floating_ip = "${openstack_compute_floatingip_v2.frontend.address}" instance_id = "${openstack_compute_instance_v2.frontend.id}" fixed_ip = "${openstack_compute_instance_v2.frontend.network.0.fixed_ip_v4}" }`
Run
terraform initto prepare for provisioning.Run
terraform planto see the execution plan and what resources are going to be created.Run
terraform applyto start the provisioning and you will prompt for confirmation.
For more details about other resources in terraform, please refer to this Document