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.