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-terraform
Create a terraform file for configs
touch configs.tf
Add 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, replace
with
jed1To access STC Riyadh2 Cloud RUH2, replace
with
ruh2`Create a terraform file for resources
touch resources.tf
Add 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 init
to prepare for provisioning.Run
terraform plan
to see the execution plan and what resources are going to be created.Run
terraform apply
to start the provisioning and you will prompt for confirmation.
For more details about other resources in terraform, please refer to this Document