Mirantis OpenStack Express — Intro to Heat Orchestration

This is the thirteenth in a series of short tutorials showing how to perform common cloud operations tasks in Mirantis OpenStack Express — Mirantis’ “Private Cloud as a Service”

In our last video, we showed you a little bit about how the Swift Object Store works and tweaked a parameter to fully-enable Public objects in Mirantis OpenStack Express. Now we’ll look a little deeper at Swift from a RESTful perspective.


Basic Ops Tutorials

Mirantis OpenStack Express — Mirantis’ “Private Cloud as a Service” — is the fastest way to get your hands on a fully-functional, optimally-configured, private OpenStack cloud, running on hosted bare metal and able to scale on demand. This series of short tutorials shows how to perform common cloud operations tasks in MOX, and offers links to documentation and learning resources. Though aimed at Mirantis OpenStack Express, many of the techniques discussed here will also work on a private OpenStack cloud deployed using Mirantis OpenStack.



In our last tutorial, we looked at using OpenStack’s REST API to authenticate with Keystone, and access objects in private containers via the Swift object store API. This time, we’ll start delving into Heat — OpenStack’s orchestration engine.

Heat is a tool for orchestrating clouds that automatically configures and deploys resources in stacks. Such deployments can be simple — like deploying WordPress on Ubuntu with an SQL back-end. And they can be quite awesome, like launching a group of servers that autoscale: starting and stopping based on realtime CPU loading information from Ceilometer.

Heat’s stacks are defined with templates, which are non-procedural documents describing tasks in terms of resources, parameters, inputs, constraints and dependencies. When Heat was originally introduced, it worked with AWS CloudFormation templates, which are in JSON format — fairly hard for humans to read and maintain directly because of all the nested brackets.

Now, Heat executes HOT (Heat Orchestration Template) templates, written in YAML: a terse notation that loosely follows Python/Ruby-type structural conventions (colons, returns, indentation) so it’s easy to write, parse, grep, generate with tools, and maintain with source-code management systems. HOT templates can also execute shell scripts, Chef recipes and Puppet automation, so there’s almost no limit to what you can do with it.

Heat can be accessed via the CLI, and using RESTful queries. It can also be accessed easily via Horizon, which can be quite powerful, since Horizon knows how to interpret and present HOT templates as easy-to-use web UI, complete with multiple-choice popdowns and input-checking to help you populate them error-free.

Heat can also perform orchestration tasks under the control of Murano. Its architecture permits extension via so-called ‘providers’ (basically drivers) to adapt to different OpenStack cloud architectures, offering the potential for write-once/run-anywhere functionality.

Step by Step

To see Heat in action, let’s start by launching a stack that does something simple. (You can find stacks and snippets like this throughout the OpenStack Heat documentation and across the web. One blog at Technology Chronicle, discussing how to associate a floating IP with a port, gets a shout-out below.) You can find the Heat interface in Horizon under Orchestration in the left-hand menu.

Click Launch Stack, and you’ll see a dialog that lets you pull in a template by URL, upload it from a file, or simply cut and paste it into an editable dialog. That’s lots of flexibility for working with various kinds of source-code control systems for versioning and maintaining template and template-snippet libraries. We’ll just pick Direct Input, and I’ll cut and paste my template into the box. We’ll look at the template itself in a moment — but first, we’ll look at what it does from the perspective of a user.

The Heat interface in Horizon gives administrators lots of ways to input template code from URLs, files, or cut-and-paste sources — making it easy to run stacks from source-code control.

Hit Next. The template is read in, validated, and executed. In response, Horizon throws up a dialog that asks for input parameters: it looks a little like the dialog used to launch a VM. You can supply a name for a new instance, hook it up with an SSH keypair, pick a flavor from a popdown list, and supply the name of a boot image. Then, you’re asked to specify resource IDs identifying the internal network and subnet you want to put the VM on, and the external network you want to connect the instance to, using a floating IP. Except for the instance name, defaults are supplied for all these values.

Executing Heat templates in Horizon can be powerful. The Horizon integration with Heat APIs turns template input requisites into web UI, complete with popdown menus to constrain choices, and pre-seeded default values for error-free input.

Click Launch, and after a few seconds, there’s our new instance, with its internal and floating IPs, its SSH keypair and other details.

Our simple HOT template has built us a server, attached it to networks, given it a floating IP address and an SSH keypair for access.

Going back to the Orchestration tab, we can click on the name of our stack to show a tabbed display of its inputs and outputs; a manipulable graphic display of its nodes with popup information; a list of its resources; and a list of the events involved in its creation. Very useful to have all this info in one place.

Click the name of an active stack to review details, topology, and find resource IDs — all the info needed to administer the stack, all in one place.
The topo view shows our server with a single port bound to internal and (by means of a floating IP address) external networks.

Now let’s quickly take a look at the HOT template file used to create this stack. It opens with a header that identifies the template version: this date means the template may contain Icehouse-era Heat features.

heat_template_version: 2013-05-23

description: >
  HOT template - deploys server with user-provided name, image, key, flavor
  Attaches to private network, and obtains floating IP on public network	

Following the header is a list of the template’s input and output parameters, with optional default values and constraints placed on the inputs. The flavor value, for example, is constrained to a list of permitted flavors — the Horizon interface with Heat will see this constraint table and present it as a pop-down menu.

    type: string
    description: Name of your new server
    type: string
    description: Keypair name
    default: dkp
    type: string
    description: Image name
    default: TestVM
    type: string
    description: Flavor
    default: m1.small
      - allowed_values: [m1.tiny,m1.small,m1.medium,m1.large,m1.xlarge]
    type: string
    description: ID of the external network
    default: 73e8560d-51bb-4e38-ae47-4252263fb10a
    type: string
    description: ID of the internal network
    default: 704c8034-5bcf-4151-bf69-b5d9791b6eb4
    type: string
    description: ID of private sub network into which servers get deployed
    default: a9d6fd47-6c3c-46e5-a44a-ede76877934b

Next is a more-complex section of the template describing cloud resources: the server itself, its network port, floating IP address, security group, and so on. Each resource descriptor references a type and provides values for required properties. In this template, values for properties are supplied as literals, obtained directly from the user (using the get_param: directive) or derived indirectly by referencing another resource descriptor (using the get_resource: directive). Heat offers several other ways to pull data into templates, as well: including reading from files, concatenating and manipulating strings.

    type: OS::Nova::Server
      name: { get_param: server_name }
      image: { get_param: image }
      flavor: { get_param: flavor }
      key_name: { get_param: key_name }
        - port: { get_resource: server_port }

    type: OS::Neutron::Port
      network_id: { get_param: private_net_id }
        - subnet_id: { get_param: private_subnet_id }
      security_groups: [{ get_resource: server_security_group }]

    type: OS::Neutron::FloatingIP
      floating_network_id: { get_param: public_net_id }
      port_id: { get_resource: server_port }

    type: OS::Neutron::SecurityGroup
      description: Add security group rules for server
      name: security-group
        - remote_ip_prefix:
          protocol: tcp
          port_range_min: 22
          port_range_max: 22
        - remote_ip_prefix:
          protocol: icmp

The final section of the template describes the outputs we want to include in the persistent stack overview.

    description: IP address of server on private network
    value: { get_attr: [ server, first_address ] }
    description: Floating IP address of server on public network
    value: { get_attr: [ server_floating_ip, floating_ip_address ] }

Next time, we’ll look in more detail at this Heat template, and extend it with additional Heat features. In the meantime, if you start playing with Heat, heed this advice: use a YAML language setting in your editor to manipulate HOT templates, set the editor to supplant tabs with spaces, and just for the heck of it, make whitespace characters visible. The current generation of OpenStack Heat validation is extremely picky, and it’s easy to scratch your head for long minutes over a validation that’s failing because a tab crept invisibly into the middle.



Check out Express for yourself at https://express.mirantis.com.

Subscribe to Our Newsletter

Latest Tweets

Suggested Content

What's New in Kubernetes 1.10