Intro to Heat Templates

Hi Folks,

It’s been a long time right? I mean ~really~ long time since I’ve posted anything. I apologize. It’s been a crazy summer. And Fall. You don’t want the details – trust me, it has very little to do with KVM or storage. I think I’m back to being able to devote some time to helping you kind and patient people out with technology again, so hopefully you haven’t completely abandoned me. 🙂

Today, I’d like to introduce the concept of Heat templates. Essentially, where we left off before was that we’ve got OpenStack up and running, we’ve got some cloud images built, but we’re really not automating anything. This is where Heat comes in..

If you’ve been paying attention, OpenStack is NOT a replacement for vSphere or RHEV or Hyper-V. Those are “scale up” technologies.. OpenStack is a “scale out” technology. You run monolithic applications (like a full LAMP stack for example) on traditional virtualization. And when you need MOAR POWR, you add more vCPU and/or more vRAM to the VM. In OpenStack, when you need MOAR POWR, you add more instances and spread the load. This of course means that your applications have to be written in a manner that can take advantage of the architecture, but that’s another article..

The point is that we need to be able to automate that scale out ability because OpenStack was NOT designed to be a “point and click” environment. I mean, Horizon has gotten better over the last few releases, but the real power is in the API’s. It’s meant to be hit via a Cloud Management Platform.

Ok, so lets take a look at a very basic heat template written in “yaml” (as opposed to json)

$ cat SueStack.yaml 
heat_template_version: 2013-05-23

description: Simple template to deploy a single compute instance

resources:
  my_instance:
    type: OS::Nova::Server
    properties:
      name: sue
      image: RHEL 6.5 [x86-64]
      flavor: m1.small
      key_name: jb_key
      networks:
        - network: tenant

Keep in mind that while it’s very simple, the parser is VERY picky and throws errors every which way if you hit a “tab” key instead of hit the space bar 5 times, and such.. Starting with a proper “heat template version” is much like starting with a “#!/bin/sh”, or similar. Also note the resource types. Every project (Neutron, Nova, Keystone, etc) can be hit via Heat templates and therefore automated. They can be short and sweet, or long and complex. But again, this is an intro, so we’ll keep in simple.

Being that this is a very simple heat template, it’s really easy to see that all we’re doing is firing up a single instance named “sue”, using a RHEL 6.5 cloud image, an m1 flavor, selected a security key, and picked a network that it should pull an IP address from.

We can launch this in 3 ways: from the Horizon dashboard, the OpenStack command line, or from an API. Again, because this is an intro, we’ll stick with Horizon. But, really you’ll want to get to the point of depending on the API’s and not the point-and-click. Otherwise, you’re essentially using a semi-truck to get groceries.

Let’s check it out in this video (better viewed in full screen):

Keep in mind that we’re not limited to instances by any stretch.. If it’s a service or resource you have access to, you can add it to the template. This absolutely includes networks and routers. See this next (still basic) YAML file:

$ cat NetStack01.yaml 
heat_template_version: 2013-05-23

description: A simple Heat template 

resources:
    new_net:
      type: OS::Neutron::Net
      properties:
        name: heat_net01
    new_subnet:
      type: OS::Neutron::Subnet
      properties:
        name: heat_sub01
        network_id: { get_resource: new_net }
        cidr: "192.168.2.0/24"
        dns_nameservers: [ "192.168.2.1" ]
        enable_dhcp: true
        gateway_ip: 192.168.2.1
        ip_version: 4
    subnet1_interface:
      type: OS::Neutron::RouterInterface
      properties:
        router_id: { get_resource: router2 }
        subnet_id: { get_resource: new_subnet }
    router2:
      type: OS::Neutron::Router
      properties:
        admin_state_up: true
        external_gateway_info: { network: provider }
        name: heat_router01

Here we’ve created a new network, subnet, and router. Could be useful.. Let’s see it in action:

But what if you don’t want to write a new template every time you want to fire up a new resource, you ask. Good question. The answer is “environment files”. Essentially, you leave placeholders in your template, such as the “get_resource” directives above, and simply call the environmental file at the same time that you call the template itself. The YAML parser will fill the blanks in the template from the values in the environmental file. BOOM!  And as you can probably imagine, the possibilities are endless at this point. You could create entire dev and/or production environments complete with application stacks with the templates and environmental files. But that’s another post.. (Check out “git”.. lots of templates there..)

If you want more in depth, please check out the official Heat Documentation for a full tutorial.

Hope this helps,

Captain KVM

Agree? Disagree? Something to add to the conversation?