OpenStack – Heat Orchestration Template

Heat provides us with a powerful orchestration engine where we can specify infrastructure in a declarative way. A heat orchestration template is easy to get the hang of and in this article we are going to look at an example of how we can deploy infrastructure using it.

When working with heat orchestration templates, we are writing simply writing declarative YAML (YAML Ain’t Markup Language) files where we specify infrastructure that we want Heat to create for us via the OpenStack API.

Prerequisites

In this quick tutorial, the end goal is to deploy a minimal instance (VM) with a floating IP. How to get started with OpenStack is considered out of scope for this article. The article assumes that you already have the following.

  • An OpenStack API account at a provider with the Heat service enabled.
  • Sourced the Openstack API environment variales.
  • OpenStack client installed.

Heat Orchestration Template

An heat orchestration template contains of 4 sections.

  • Version
  • Parameters
  • Resources
  • Output

Version

Heat Orchestration is an evolving project, and new releases are being made from time to time. Therefore, you need to specify which version you are going to use in the template. Check with your cloud provider which versions they support.

Parameters

Parameters are where you can specify input to the template, variables that should be dynamic for re-usability. A good example is an SSH key name and a public network ID. Variables that will be different for different users of the template. It is also popular to have flavors (size of instances in processor cores, ram, and disk size) as a parameter.

Resources

Resources is the section where you specify what types of infrastructure that you want to get, for example, a network, an instance (VM) and a floating IP.

Output

Similar to how a template can have input, it can also have output, for example, IPs.

Template Example

heat_template_version: 2015-04-30
description: |
  A basic example of a template used for HEAT Orchestration in OpenStack.
  The template deploys a single instance (VM) with an external ip.

parameters:
  public_net_id:
    type: string
  key_name:
    type: string
  flavor:
    type: string
    default: 1C-1GB
  image:
    type: string
    default: CentOS 7 1602

resources:
  # The router where network traffic will pass through.
  my_router:
    type: OS::Neutron::Router
    properties:
      name: router
      external_gateway_info:
        network: { get_param: public_net_id }

  # Associates a router with a subnet or a port.
  my_router_interface:
    type: OS::Neutron::RouterInterface
    properties:
      router: { get_resource: my_router }
      subnet: { get_resource: my_subnet }

  # The network that will contain one, or many subnets.
  my_network:
    type: OS::Neutron::Net
    properties:
      name: testnet
  
  # Subnet that the instance will be connected to and receive a ip address from.
  my_subnet:
    type: OS::Neutron::Subnet
    properties:
      cidr: 10.0.2.1/24
      network: { get_resource: my_network }

  # A Port that our instance will attach it's interface on to.
  my_port:
    type: OS::Neutron::Port
    properties:
      network: { get_resource: my_network }

  # A resource where Floating IPs will be taken from.
  floating_ip:
    type: OS::Neutron::FloatingIP
    properties:
      floating_network: { get_param: public_net_id }

  # Creates the association from an Floating IP to the Port
  association:
    type: OS::Neutron::FloatingIPAssociation
    properties:
      floatingip_id: { get_resource: floating_ip }
      port_id: { get_resource: my_port }

  # The Instance (VM)
  my_instance:
    type: OS::Nova::Server
    properties:
      name: test-instance
      key_name: { get_param: key_name }
      flavor: { get_param: flavor }
      image: { get_param: image }
      networks:
        - subnet: { get_resource: my_subnet }
          port: { get_resource: my_port }

outputs:
  instance_ip: 
    description: The IP address of the deployed instance
    value: { get_attr: [ my_instance, first_address ]}
  floating_ip:
    description: The floating IP to the deployed instance
    value: { get_attr: [ floating_ip, floating_ip_address ]}

Parameters

The template above takes four parameters; the first is a key_name which is the name of a KeyPair resource if you haven’t created one yet you can do it with the command below.

openstack keypair create --public-key ~/.ssh/id_rsa.pub my_key_name

The second parameter it takes is a public network. Each user in an OpenStack environment is assigned a unique public network. This is the network which makes it reachable over the web, and it is also what enables you to SSH into it. You can figure out the ID of your public network with the command below (usually it is named ext-net or something similar).

openstack network list

The third parameter is flavor which is the size of the instance that is to be deployed. Unfortunately, flavors have different names in different cloud environment. You can find out available flavors with the command below.

openstack flavor list

The fourth parameter is the OS that is to be deployed on the instance, similar to flavor the names is likely to be different depending on your cloud provider. You can find out available with the command below.

openstack image list

You might have noticed as well that I specified a default value for flavor and instance.

Resources

The template declares a couple of different resources. An instance is specified which is connected to an OS::Neutron::Subnet and an OS::Neutron::Port. Which is why we also specify those resources as well as an OS::Neutron::Net that the subnet resides in. We also specify an OS::Neutron::Router as well as an OS::Neutron::RouterInterface which connects our subnet to the router. And lastly, an OS::Neutron::FloatingIP to provide us with a floating IP so that we can connect to the instance, and an OS::Neutron::FloatingIPAssociation to connect it to our port.

Output

The template when deployed will also output the IP of the instance and the floating IP associated with it.

Usage

The template is easy to deploy with the following command.

openstack stack create -t template.yaml --parameter public_net_id=ext-net --parameter key_name=planevik --parameter flavor=1C-1GB --parameter image="CentOS 7 1602" test

Give it a couple of seconds to deploy and then we can check the output of the template with the command below.

openstack stack output show --all test

Now we should be able to SSH into it using the private key associated with the public key that you created in your KeyPair.

When you are done with the instance, you can bring down it and all the other resources with a simple command.

openstack stack delete test.

Final Words

We have looked a heat orchestration template example deployment and it really is that easy to deploy infrastructure. Because everything is done in YAML everything is declarative and easy to read.

There are really loads of cool stuff that you can do with Heat and I recommend checking out the official OpenStack Documentation for the Template Guide. In future articles we will dive a bit deeper with heat orchestration.

Leave a Reply