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.
Tutorials:
- Adding New Custom Boot Images
- Launching a VM from a Boot Image
- Creating a Block Storage Volume
- Attaching and Using Volumes
- Creating new VM Flavors
- Setting Up a project
- Murano in a Minute
- Mirantis OpenStack Express VPN-as-a-Service
- Running OpenStack from the Command Line
- Automating VM Launch and Apache Installation
- Intro to Object Store
- REST Access to Object Store
- Intro to Heat Orchestration
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.
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.
Click Launch, and after a few seconds, there’s our new instance, with its internal and floating IPs, its SSH keypair and other details.
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.
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.
parameters:
server_name:
type: string
description: Name of your new server
key_name:
type: string
description: Keypair name
default: dkp
image:
type: string
description: Image name
default: TestVM
flavor:
type: string
description: Flavor
default: m1.small
constraints:
- allowed_values: [m1.tiny,m1.small,m1.medium,m1.large,m1.xlarge]
public_net_id:
type: string
description: ID of the external network
default: 73e8560d-51bb-4e38-ae47-4252263fb10a
private_net_id:
type: string
description: ID of the internal network
default: 704c8034-5bcf-4151-bf69-b5d9791b6eb4
private_subnet_id:
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.
resources:
server:
type: OS::Nova::Server
properties:
name: { get_param: server_name }
image: { get_param: image }
flavor: { get_param: flavor }
key_name: { get_param: key_name }
networks:
- port: { get_resource: server_port }
server_port:
type: OS::Neutron::Port
properties:
network_id: { get_param: private_net_id }
fixed_ips:
- subnet_id: { get_param: private_subnet_id }
security_groups: [{ get_resource: server_security_group }]
server_floating_ip:
type: OS::Neutron::FloatingIP
properties:
floating_network_id: { get_param: public_net_id }
port_id: { get_resource: server_port }
server_security_group:
type: OS::Neutron::SecurityGroup
properties:
description: Add security group rules for server
name: security-group
rules:
- remote_ip_prefix: 0.0.0.0/0
protocol: tcp
port_range_min: 22
port_range_max: 22
- remote_ip_prefix: 0.0.0.0/0
protocol: icmp
The final section of the template describes the outputs we want to include in the persistent stack overview.
outputs:
server_private_ip:
description: IP address of server on private network
value: { get_attr: [ server, first_address ] }
server_public_ip:
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.
Resources:
- Mirantis OpenStack Express 2.0 Documentation
- Mirantis OpenStack Express Operations Guide
- OpenStack Command-Line Reference
- OpenStack Heat REST API Documentation
- OpenStack Heat HOT Specification
- OpenStack Heat HOT Guide
- Technology Chronicle - Blog on Attaching Floating IP to Instance with Heat
Check out Express for yourself at https://express.mirantis.com.