Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 2 Next »

Installing Terraform

On a Ubuntu machine run the following command

# 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

  1. Create a directory and cd  to the directory
  2. Create a file named providers.tf with the following content. This will enable the OpenStack provider

    # Define required providers
    terraform {
    required_version = ">= 0.14.0"
      required_providers {
        openstack = {
          source  = "terraform-provider-openstack/openstack"
          version = "~> 1.35.0"
        }
      }
    }
    
    provider "openstack" {}
  3. Declare the cloud information. It is recommended that you refer to Using OpenStack Command-line Interface. You can also declare it in the providers.tf  However, you will have to declare your login details in plain text which is not secure.
  4. Run terraform init

    $ 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.

Applying config via terraform

To create a configuration you need the deploy.tf for your configuration and variable.tf  for the variables in the provider folder 

I have create an example that will create a set of instances with a volume attached to it.

deploy.tf
# 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
# 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" {
    description = "The image ID to be used."
    default  = "622cb70d-c88c-4dc4-99e6-df8b8f9965d7"
}

variable "flavor_id" {
    description = "The flavor id to be used."
    default  = "026ace2c-5247-4bdc-8929-81d129cc69bf"
}

# 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 keypair public key."
    default = 1
}

variable "volume_name" {
    description = "name of volume"
    default = "tutorial_volume"
}

variable "volume_size" {
    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. 

After you have edited the files, you can run

terraform plan to preview the changes

e.g.

$ terraform plan -var "instance_num=2"

# Terraform will compare the configuration witht the desired state and produce a action plan

terrafor apply to apply the changes

e.g.

$ 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"
}

Reference

You should refer to Docs overview | terraform-provider-openstack/openstack | Terraform Registry for details on how to use the providers

Here are some of the more commonly used providers

ProviderFunction
openstack_compute_instance_v2Create instance
openstack_networking_secgroup_v2Create security group
openstack_networking_secgroup_rule_v2Create security group rule
openstack_networking_network_v2Create network
openstack_networking_floatingip_v2Get a floating IP from allocated pool
openstack_compute_floatingip_associate_v2Associate floating IP to instances
openstack_containerinfra_clustertemplate_v1Create magnum cluster template
openstack_containerinfra_cluster_v1Create magnum cluster
openstack_blockstorage_volume_v2Create a new volume
openstack_compute_volume_attach_v2Attach volume to instances
openstack_lb_loadbalancer_v2Create Load balancer
openstack_lb_listener_v2Create Load balancer listener
openstack_lb_pool_v2Set method for load balance charge between instance (e.g. round robin)
openstack_lb_member_v2Add instance to load balancer
openstack_lb_monitor_v2Create health monitor for load balancer
  • No labels