Installing Terraform
On a Ubuntu machine run the following command
Code Block | ||
---|---|---|
| ||
# register key curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add - # add repo sudo apt-add-repository "deb [arch=$(dpkg --print-architecture)] https://apt.releases.hashicorp.com $(lsb_release -cs) main" # install with apt sudo apt install terraform |
...
Setting up provider
Create a directory with any name and
cd
to the directoryCreate a file named
providers.tf
with the following content. This will enable the OpenStack providerproviders.tf
Code Block language hcl # Define required providers terraform { required_version = ">= 0.14.0" required_providers { openstack = { source = "terraform-provider-openstack/openstack" version = "~> 1.35.0" } } } provider "openstack" {}
Declare the cloud information. It is recommended that you refer to Using the OpenStack Command -line Line Interface . You can also declare it in the
providers.tf
However however, you will have to declare your login details in plain text which is not secure.Run
terraform init
Code Block language bash $ terraform init Initializing the backend... Initializing provider plugins... - Reusing previous version of terraform-provider-openstack/openstack from the dependency lock file - Using previously-installed terraform-provider-openstack/openstack v1.35.0 Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work. If you ever set or change modules or backend configuration for Terraform, rerun this command to reinitialize your working directory. If you forget, other commands will detect it and remind you to do so if necessary.
...
I have create an example that will create a set of instances with a volume attached to it.
deploy.tf
Code Block | ||
---|---|---|
| ||
# create a security group named secgroup_1 resource "openstack_networking_secgroup_v2" "secgroup_1" { # you can access the variables using var.<variable-name> name = var.http_sec_group description = "My neutron security group" } # create a security group rules resource "openstack_networking_secgroup_rule_v2" "secgroup_rule_1" { direction = "ingress" ethertype = "IPv4" protocol = "tcp" port_range_min = 80 port_range_max = 80 remote_ip_prefix = "0.0.0.0/0" # you can access the output attribute of other resources using ${<provider>.<name>.<attribute>} security_group_id = "${openstack_networking_secgroup_v2.secgroup_1.id}" } #creating instances resource "openstack_compute_instance_v2" "Instance" { # the count will create a number of duplicates equal to the number count = var.instance_num name = format("%s-%02d", var.instance_name, count.index+1) image_id = var.image_id flavor_id = var.flavor_id key_pair = var.key_pair_name security_groups = var.security_groups network { name = var.network_name } } resource "openstack_blockstorage_volume_v2" "Volume" { count = var.instance_num name = format("%s-%02d", var.volume_name, count.index+1) size = var.volume_size } resource "openstack_compute_volume_attach_v2" "attachments" { count = var.instance_num # if there are multiples of same resources the detail are stored in an array instance_id = "${openstack_compute_instance_v2.Instance[count.index].id}" volume_id = "${openstack_blockstorage_volume_v2.Volume[count.index].id}" } # this will create a output which you can use output "instance_ips" { value = { for instance in openstack_compute_instance_v2.Instance: instance.name => instance.access_ip_v4 } } |
variables.tf
Code Block | ||
---|---|---|
| ||
# create a SSH key-pair using other method first since terraform is not secure variable "key_pair_name" { description = "key pair name" default = "tutorial" } variable "http_sec_group" { description = "custom security group name" default = "HTTP-ingress" } variable "network_name" { description = "The network to be used." default = "Internal" } variable "instance_name" { description = "The Instance Name to be used." default = "tutorial-machine" } variable "image_id" { #find#find with: openstack image list description = "The image ID to be used." default = "622cb70d-c88c-4dc4-99e6-df8b8f9965d7" } variable "flavor_id" { #find with: openstack flavor list description = "The flavor id to be used." default = "026ace2c-5247-4bdc-8929-81d129cc69bf" } # You have to put http sec group here as well variable "security_groups" { description = "List of security group" type = list default = ["default", "HTTP-ingress"] } variable "instance_num" { description = "The number keypairof instances publicto keycreate." default = 1 } variable "volume_name" { description = "name of volume" default = "tutorial_volume" } variable "volume_size" { #volume size in gigabytes description = "size of volume" default = 3 } |
To change the variable you can either change the default in variable.tf
or by passing the -var "<variable-name>=<value>"
flag during terraform plan
or terraform apply
.
On thing to note is that you should create ssh keys via the web interface or OpenStack clients and reference it in terraform since terraform will store configuration in plain text which will expose your ssh key.
To save the plan to a file you can use the -out=<path>
flag. This will make sure when you apply the plan, terraform uses the correct plan
After you have edited the files, you can run
terraform plan
to preview the changes
e.g.
Code Block | ||
---|---|---|
| ||
$ terraform plan -var "instance_num=2" -out plan # Terraform will compare the configuration witht the desired state and produce a action plan |
terrafor apply plan
to apply the changes
e.g.
Code Block | ||
---|---|---|
| ||
$ terraform apply -var "instance_num=2" ################################################## Same as above Skipped ################################################### Apply complete! Resources: 8 added, 0 changed, 0 destroyed. Outputs: instance_ips = { "tutorial-machine-01" = "172.16.100.135" "tutorial-machine-02" = "172.16.101.124" } |
...
Here are some of the common providers
Provider | Function |
---|---|
openstack_compute_instance_v2 | Create instance |
openstack_networking_secgroup_v2 | Create security group |
openstack_networking_secgroup_rule_v2 | Create security group rule |
openstack_networking_network_v2 | Create network |
openstack_networking_floatingip_v2 | Get a floating IP from allocated pool |
openstack_compute_floatingip_associate_v2 | Associate floating IP to instances |
openstack_containerinfra_clustertemplate_v1 | Create magnum cluster template |
openstack_containerinfra_cluster_v1 | Create magnum cluster |
openstack_blockstorage_volume_v2 | Create a new volume |
openstack_compute_volume_attach_v2 | Attach volume to instances |
openstack_lb_loadbalancer_v2 | Create Load balancer |
openstack_lb_listener_v2 | Create Load balancer listener |
openstack_lb_pool_v2 | Set method for load balance charge between instance (e.g. round robin) |
openstack_lb_member_v2 | Add instance to load balancer |
openstack_lb_monitor_v2 | Create health monitor for load balancer |