Best Practices for OpenStack Heat Templates

Approximately remain in this minutes read.

Best Practices for OpenStack Heat Templates

Best Practices for OpenStack Heat Templates
Written by

OpenStack-Heat-Deplying-Multiple-InstancesProvisioning a single instance is a great first step to getting your workloads into the cloud, but you will soon realize that managing your workloads is a lot more than the deployment of a single instance. In this case using templates with OpenStack Heat becomes not only useful, but also a necessity.

In this article we will go through a number of best practices for using Heat, assuring that your templates will be reusable throughout your deployments. These recommendations enhance your capabilities to deploy across multiple OpenStack providers without having to make major changes in your code.

See this infographic for a look at OpenStack deployment tools.

HOT Syntax

Openstack Heat templates are written in YAML – and there are a number of integral functionalities you can and should make use of while writing your templates.

Description

The description is an optional field in your template, but it is advised to provide a proper description to describe what your template is actually going to do. Remember that just because you know what happens in the template does not mean that a few months from now – when someone else has to modify it – will they be able to ‘get into your head’ and understand what you wanted to accomplish.

A nice tip you should be aware of is that YAML also supports multi-line text. See the example below:

description: >
 This is a very long description of your template
 that needs to span over more that one line.

Parameterization

Parameters are used for specifying values when the template is instantiated.

Each parameter has a number of attributes associated with it, the full list is below:

 <param name>:
   type: <string | number | json | comma_delimited_list | boolean>
   label: <human-readable name of the parameter>
   description: <description of the parameter>
   default: <default value for parameter>
   hidden: <true | false>
   constraints:
     <parameter constraints>
   immutable: <true | false>

The <param name>: and type: are mandatory; all others are optional.

The following are recommended as best practices.

Learn how to determine OpenStack hardware requirements.

Description

Use a description in each of your parameters, explain what the parameter is for – why and how it is used.

“imagename”:
   type: string
   description: Name of image used in instance creation

Defaults

It is highly recommended to provide a default value for your parameters. These defaults can always be overridden if needed – but it will ensure that the template will be deployed with a standard default – that has been tested and verified.

 “clear_config”:
   type: string
   default: “false”
   description: >
      Parameter that will pass a value to the stack to clear the database on instantiation

Constraints

There are certain cases where you will want to ensure that only specific values are passed to the stack, to ensure that the provisioning works correctly – for example, passwords. To ensure that a compliant password is used in your stack, you can limit the value of a certain parameter. If the parameter does not match your requirements – the stack will not launch.

 password:
   type: string
   description: The password to be used to configure the application
   constraints:
       – allowed_pattern: “^[a-zA-Z]\w{3,14}$”
       description: >
          The password’s first character must be a letter, it must contain at least 4
          characters and no more than 15 characters and no characters other than letters,
          numbers and the underscore may be used.

Learn more about the benefits of open source clouds, here.

Re-use of Elements

Let us take an example in which you are going to provision a stack with 10 instances. Each of these ten instances are almost the same, with the exception of a few minor differences. They share the same:

  • Network
  • Image name
  • Flavor
  • Etc.

It becomes quite tedious repeating all of the same information in your Heat template over 10 times. Instead, you can call an additional Heat template that is already configured with all the options you need. By creating another template and pointing your main template to the list of resources, you can make your templates much more manageable.

Here is a diagram demonstrating how this works:

Diagram-Yaml

 

 

 

 

 

 

 

In your resource.yaml you will have your default template with all your options configured (the syntax below is just a short example of what you can achieve).

 resource:
   type: OS::Nova::Server
   properties:
     name:
       str_replace:
         template: $nameprefix-$instance_name
         params:
           $nameprefix : { get_param: nameprefix }
           $instance_name: { get_param: instance_name }
     flavor: {get_param: flavor}
     image: {get_param: image}
     key_name: {get_param: key_name}
     availability_zone: { get_param: availability_zone }
     networks:
       – port: { get_resource: server_port }

This is the standard HOT syntax.

For your template you would use the following:

 instance1:
   type: resource.yaml
   properties:
     nameprefix: { get_param: “OS::stack_name” }
     instance_name: instance1hornetq
     key_name:  { get_param: “keypairid” }
     flavor: { get_param: “flavorname” }
     image: { get_param: “imagename”}
     private_network_id: { get_param: “networkid”}
     availability_zone: { get_param: “azname” }
     ….

As you can see here – the resource type of the instance is no longer
type: OS::Nova::Server
but rather type: resource.yaml – which allows you to make use of the nested feature within Heat that allows you to call one template resource from within another template.

Environment files

Ask any operator what is the worst thing you can ever do with your code, and they will probably tell you that it is hard coding a variable into your code. This action will render it useless when you want to reuse that same snippet again. That is why it is important to expose as much as possible within your OpenStack Heat templates as variables.

But then of course you will need to provide a sane set of defaults – but more importantly,  the option to change these defaults as needed.

That is where an environment file comes into play. Heat allows you provide an environment file to your stack for just this purpose. This is accomplished by adding a flag to your heat stack-create command:

heat stack-create <stack_name> -f template.yaml -e env.yaml

In this environment file you would put the correct values for your deployment – and this would make it completely portable to the next (and every) environment you deploy into.

Here is an example of an environment file:

parameters:
 subnetid: my_subnet_id
 networkid: my_network_id
 keypairid: my_keypair
 imagename: my_image
 flavorname: m1.small
 azname: nova

All you would need to do to deploy the same template in another location would be to change the appropriate values in your environment file to match the new values. You can deploy in a completely different provider, without having to make any changes inside your deployment code.

Summary

Using Heat should become an integral part of your cloud provisioning strategy. Above, we have gone through a number of best practices and recommended ways to help you write better and more robust OpenStack Heat templates that can be used not only by you, but also by others as well. Following these recommendations will also allow you make your infrastructure portable and expand your capabilities to deploy across multiple OpenStack providers without having to make major changes in your code.

These recommendations will expand your capabilities to deploy across multiple OpenStack providers without having to make major changes in your code.

OpenSource for your private cloud

 


September 13, 2016

Simple Share Buttons
Simple Share Buttons