Terraform is a tool from HashiCorp that can be used to deploy and manage cloud infrastructure easily by defining configuration files. It is similar to OpenStack Heat. However, unlike Heat which is specific to OpenStack, terraform is provider agnostic and can work with multiple cloud platforms such as OpenStack, AWS and VMware. This blog will give an overview of how to use Terraform with OpenStack.
Infrastructure as a Service (IaaS) is the most basic cloud model, giving you the ability to create your own infrastructure resources such as networks, firewalls, load balancers, different kind of storage and of course servers.
In the world of ever-changing requirements and workloads, the pressure and constant demand for deployment of applications and infrastructure is relentless. The days when IT admins would install servers manually are slowly but surely fading away. However, as in any situation that removes manual processes, something else must take its place, and in this circumstance, it is Infrastructure as code.
OpenStack adopted some of the tools used in AWS for their own Orchestration engine Heat and some of them are even still supported today in the current Liberty version. And, although most of the functionality has moved over to Heat native resources, the tools are still beneficial for everyday use.
As the use of cloud technologies and infrastructure grew, the need for solutions that are not solely dependent on a single vendor became a necessity. Cloud environments fail, and with all your eggs in a single basket, IT becomes vulnerable. IT admins started to look for a way to deploy their workloads across clouds and different providers to minimize exposure to risk. The missing piece in this scenario, was a single tool that would allow the end user (be it an IT admin or a developer creating an application) to manage multiple environments with a standard set of tools
Terraform:
Terraform is self-sufficient and executable, which makes it extremely simple to install, and it works on almost any platform.As of today, terraform works with different providers, enabling you to control different types of resources and infrastructures.
Terraform and OpenStack:
Terraform has several modules that will allow you manage your OpenStack infrastructure. It does support some (but not all) of the components of OpenStack, namely:
variable “openstack_user_name” {
description = “The username for the Tenant.”
default = “myuser”
}
variable “openstack_tenant_name” {
description = “The name of the Tenant.”
default = “my_tenant”
}
variable “openstack_password” {
description = “The password for the Tenant.”
default = “my_password”
}
variable “openstack_auth_url” {
description = “The endpoint url to connect to OpenStack.”
default = “http://<HOSTNAME>:5000/v2.0”
}
variable “openstack_keypair” {
description = “The keypair to be used.”
default = “my_keypair”
}
variable “tenant_network” {
description = “The network to be used.”
default = “my_network”
}
Here we have a file that will store all the information you need to interact with your OpenStack infrastructure.
provider “openstack” {
user_name = “${var.openstack_user_name}”
tenant_name = “${var.openstack_tenant_name}”
password = “${var.openstack_password}”
auth_url = “${var.openstack_auth_url}”
}
Next, we have the provider definitions, the values will be populated from our variable definitions above.
variable “count” {
default = 2
}
resource “openstack_compute_instance_v2” “web” {
count = “${var.count}”
name = “${format(“web-%02d”, count.index+1)}”
image_name = “CentOS6”
availability_zone = “AZ1”
flavor_id = “2”
key_pair = “${openstack_keypair}”
security_groups = [“default”]
network {
name = “${tenant_network}”
}
user_data = “${file(“bootstrapweb.sh”)}”
}
Here we have defined a how many instances are to be deployed and given each of them a name accordingly. We have also defined that the instance should run a number of commands that are defined in the bootstrapweb.sh file below.
#!/bin/bash
yum install -y httpd
chkconfig –level 345 httpd on
cat <<EOF > /var/www/html/index.html
<html>
<body>
<p>hostname is: $(hostname)</p>
</body>
</html>
EOF
chown -R apache:apache /var/www/html
service httpd start
To test the configuration – we run the following command:
terraform plan
This will go through the configuration that you have provided and do a dry run – and will print out what the outcome of your provisioned state will be. An example of such outcome is below:
+ openstack_compute_instance_v2.web.1
access_ip_v4: “” => “<computed>”
access_ip_v6: “” => “<computed>”
availability_zone: “” => “AZ1”
flavor_id: “” => “2”
flavor_name: “” => “<computed>”
image_id: “” => “<computed>”
image_name: “” => “CentOS-DevOPS-v2.4”
key_pair: “” => “my_keypair”
name: “” => “web-02”
network.#: “” => “1”
network.0.fixed_ip_v4: “” => “<computed>”
network.0.fixed_ip_v6: “” => “<computed>”
network.0.mac: “” => “<computed>”
network.0.name: “” => “my_network”
network.0.port: “” => “<computed>”
network.0.uuid: “” => “<computed>”
security_groups.#: “” => “1”
security_groups.3814588639: “” => “default”
user_data: “” => “67b4a89214eb5ecc368e8dbec1bd4bba566cc78d”
volume.#: “” => “<computed>”
Plan: 2 to add, 0 to change, 0 to destroy.
Here, we see what resources will be created, where <computed> appears – the resources will be created upon instantiation. The last line details that two resources will be created. Since this is first time that they are going to be created, nothing will be changed, or destroyed.
After deployment you can see that there are two instances, each with Apache running and their default page populated.
$ curl http://192.168.100.56
<html>
<body>
<p>hostname is: web-01</p>
</body>
</html>
$ curl http://192.168.100.57
<html>
<body>
<p>hostname is: web-02</p>
</body>
</html>
Ofcourse cleaning up afterwards is just running another command:
terraform destroy
Do you really want to destroy?
Terraform will delete all your managed infrastructure.
There is no undo. Only ‘yes’ will be accepted to confirm.
Enter a value: yes
openstack_compute_instance_v2.web.0: Refreshing state… (ID: 783cbddf-7cbd-4b56-808d-01a6b05d8f03)
openstack_compute_instance_v2.web.1: Refreshing state… (ID: 0b90d987-f339-47c9-9d83-a78ffb7234ca)
openstack_compute_instance_v2.web.0: Destroying…
openstack_compute_instance_v2.web.1: Destroying…
openstack_compute_instance_v2.web.1: Destruction complete
openstack_compute_instance_v2.web.0: Destruction complete
Apply complete! Resources: 0 added, 0 changed, 2 destroyed.
There’s more to Terraform than what we have covered here, but this should at least get you started. Terraform allows representing infrastructure as code and eases the process of infrastructure automation. It works across multiple cloud platforms by providing higher abstraction to managing infrastructure. This is achieved by wrapping the APIs into Terraform providers and provisioners.
While Terraform supports OpenStack, only a limited set of resources are supported out-of the box. These are sufficient to perform usual tasks such as spinning up a VM and attaching it to a network and storage. For advanced tasks, custom handlers will need to be created to support other OpenStack resources.