Example #3: Parameterized Templates

While the templates we have used so far are nice for getting the same VM build every time, they aren't terribly reusable outside of a very narrow scope. They also aren't very useful for more complex landscapes of servers.

To allow for better reusability and flexibility, HOT templates can have parameters, which allow us to create customizable templates that allow for better reuse.

There is also the option of creating string resources which can be used to specify autogenerated values, as well as the infrastructure components that we have seen in previous examples. We'll use both in the template below.

The template below is essentially the same one we used in the previous lesson, but this time we're parameterizing it so that it's name doesn't collide with previously provisioned machines.

Parameters

In this example we're going to add THREE new parameters to the template:

  1. An SSH key name, so that we can change the default SSH key that is installed on the new instance. This allows us to redeploy the VM for use by different users.
  2. An Image identifier. This allows us to redeploy the same template with different base images.
  3. A private network identifier. This gives us the option of targeting different private networks for deployment. This will allow you to redeploy this same template in your own environments, just changing this UUID to match your OpenStack's configuration.
heat_template_version: 2014-10-16
description: Template to show off parameters

parameters:
    key_name:
        type: string
        label: Key Name
        description: SSH key to be used for all instances
        default: derek_ssh
    image_id:
        type: string
        label: Image ID
        description: Image to be used (RHEL/Centos 7 compat) for base OS
        default: minimal_salt_centos_7.2
    private_net_id:
        type: string
        description: ID of private network into which servers get deployed
        default: private

Resources (strings)

Using the same YAML that you use to provision infrastructure, OpenStack Heat has a variety of methods of generating useful strings, which you can use for a variety of purposes. In this case, a nonce is of the type OS::Heat::RandomString, which allows us to repeatedly deploy the same HEAT template into the same Tenant/Project without having a naming collision. This is very useful when you are deploying a variety of VMs and want to keep them organized together by name too.

The documentation for configuring these random/custom strings can be viewed at the Template Guide .

resources:
    name_nonce:
        type: OS::Heat::RandomString
        properties:
            length: 16
            sequence: lowercase

All Together

heat_template_version: 2014-10-16
description: Template to show off parameters

parameters:
    key_name:
        type: string
        label: Key Name
        description: SSH key to be used for all instances
        default: derek_ssh
    image_id:
        type: string
        label: Image ID
        description: Image to be used (RHEL/Centos 7 compat) for base OS
        default: minimal_salt_centos_7.2
    private_net_id:
        type: string
        description: ID of private network into which servers get deployed
        default: private


resources:

    # Wouldn't it be nice if the name of the VM was randomized? Then we could
    # use this stack more than once in the same project/tenant, without a
    # naming collision!
    name_nonce:
        type: OS::Heat::RandomString
        properties:
            length: 16
            sequence: lowercase

    new_instance:
        type: OS::Nova::Server
        properties:
            key_name: { get_param: key_name }
            image: { get_param: image_id }
            flavor: m1.small
            name:
                # We'll explain how this works in the next section!
                str_replace:
                    template: random-vm-$NONCE
                    params:
                        $NONCE: { get_resource: name_nonce }
            networks:
              - network: { get_param: private_net_id }