How to create a set of VMs using OpenStack Heat Orchestration

Heat is an OpenStack component responsible for Orchestration. Its purpose is to deliver automation engine and optimize processes.

Heat receives commands through templates which are text files in yaml format. A template describes the entire infrastructure that you want to deploy. The deployed environment is called a stack and can consist of any combination out of the different resources that are available in OpenStack.

What We Are Going To Cover

  • Typical parts of a Heat template

  • Basic template for using Heat

  • How to get data for Heat Template

  • Using Heat with CLI

  • Using Heat with GUI

  • More advanced template for Heat

Prerequisites

No. 1 Account

You need a Destination Earth hosting account with access to the Horizon interface: https://cloud.central.data.destination-earth.eu.

No. 2 OpenStack CLI client with the appropriate module

If you want to use Heat through CLI commands, you need to have the OpenStack CLI client installed and ready to use. The following article contains more information:

Apart from that, you will need to have the python-heatclient module.

If you used pip to install the OpenStack CLI Client, you can install this module using one of the commands below (depending on the environment you are running):

pip install python-heatclient
pip3 install python-heatclient

If you, however, installed the OpenStack CLI client using apt on Ubuntu 22.04, install the Heat client using the following command:

sudo apt install python3-heatclient

No. 3 SSH key pair

Your OpenStack environment needs to have an SSH key pair to perform the examples found in this article. You can add it by following one of these articles:

Always use the latest value of image id

From time to time, the default images of operating systems in the Destination Earth cloud are upgraded to the new versions. As a consequence, their image id will change. Let’s say that the image id for Ubuntu 22.04 LTS was 233656c2-2625-4b4f-a99f-d0663458e45a at the time of writing of this article. While working through the article, you would normally take the current value of image id, and would use it to replace 233656c2-2625-4b4f-a99f-d0663458e45a throughout the text.

Now, suppose you wanted to automate processes under OpenStack, perhaps using Heat, Terraform, Ansible or any other tool for OpenStack automation; if you use the value of 233656c2-2625-4b4f-a99f-d0663458e45a for image id, it would remain hardcoded and once this value gets changed during the upgrade, the automated process may stop to execute.

Warning

Make sure that your automation code is using the current value of an OS image id, not the hardcoded one.

How to write Heat templates

Here are the basic elements of a Heat template:

heat_template_version

The exact version of heat template. Each of them varies in many ways (including support for various modules, additional parameters, customization etc). See Orchestration -> Template Versions.

resources

Entry to commence providing particular components for deployment.

instance

Name of resource (you can type in anything on your own).

type

Definition of an OpenStack component (a comprehensive list is under Orchestration -> Resource Types)

properties

Required parameters for deploying a component.

Example 1: Launching one virtual machine

Code

Using the following snippet, you can create one virtual machine with Ubuntu 22.04 (flavor eo2a.large) on a default project. Create a text file called template.yaml using your favorite text editor and add the content below to it:

heat_template_version: 2015-04-30

resources:
  instance:
    type: OS::Nova::Server
    properties:
      flavor: eo2a.large
      image: 233656c2-2625-4b4f-a99f-d0663458e45a
      networks:
        - network: <cloud_johnsmith_1>
      key_name: <mykey>
      security_groups:
        - allow_ping_ssh_rdp
        - default

Important

YAML format does not allow using tabs, you must enter spaces instead.

In the code above, replace <cloud_johnsmith_1> with the name of the network found in your project and <mykey> with the name of the SSH key.

How to get data needed for describing a virtual machine in Heat

Templates need data for images, flavor networks, key pairs, security groups and so on. You would normally know all these elements in advance, or you could “look around” at various parts of the Horizon dashboard:

flavor

Compute -> Instances -> Launch Instance -> Flavor

image

Compute -> Instances -> Launch Instance -> Source

networks

Network -> Networks -> cloud network for your domain

key_name

Compute -> Key Pairs

security_groups

Network -> Security Groups

You can work with Heat in two ways:

  • through Command Line Interface (CLI), with python-heatclient installed and

  • using the Horizon dashboard in your browser.

Launching the Stack using Heat

If you launch a Stack using Heat, the infrastructure described in a Stack should be created. You can do that using the Horizon dashboard or the OpenStack CLI client.

Method 1: Using the Horizon dashboard

Log in to the Horizon dashboard, choose Orchestration and then Stacks tab:

../_images/stacks_menu1.png

Navigate to the right part of the screen, click on button click_button_launch_stack and bring Select Template window to the screen.

From the drop-down menu Template Source choose the appropriate source:

  • File allows you to upload a file with the template.

  • Direct Input allows you to enter the template directly into a text field in the Horizon dashboard.

  • URL allows you to use a template available on the Internet - you can specify URL here.

../_images/orch41.png

In this example, choose Direct Input.

Copy the contents of the previously created template.yaml file to the Template Data text field:

../_images/select_template_yaml1.png

Provide a name of your stack and the password for your Destination Earth account:

../_images/launch_stack1.png

Click Launch.

The process of creating a stack should be started:

../_images/create_new_template1.png

Once the Stack has the Status Create Complete, your new virtual machine should be available in the Compute -> Instances section of the Horizon dashboard:

../_images/heat_instance1.png

Method 2: Using the OpenStack CLI client

Make sure that you have the OpenStack CLI client with the Heat client module set up and ready to use (as explained in Prerequisite No. 2).

The command used to deploy the stack can then have the following syntax:

openstack stack create -t <filename> <stackname>

where -t assigns file from your local hard drive with a template for deployment (<filename>) and <stackname> defines name for the stack.

For example, if the name of the file is template.yaml, you are in the folder containing that file and you wish to call your stack heat-test2, this is how the command will look like:

openstack stack create -t template.yaml heat-test2

It should produce output like this:

../_images/heat-test21.png

You can use the openstack stack list command to list your current stacks:

../_images/heat_test_list1.png

Your new stack should also be visible in the Horizon dashboard:

../_images/heat_test2_stacks1.png

To list servers found in your project, execute openstack server list - this command should show your new virtual machine:

../_images/heat-test-server-list1.png

In this example, the optional parameter –fit-width was used so that the output looks better on this screenshot.

The virtual machine should also be visible in the Compute -> Instances section of the Horizon dashboard:

../_images/heat_test2_instances1.png

Example 2: Launching five VMs using an advanced Heat template

In this example, we will create four VMs which only have ephemeral storage and one VM booted from a volume, all using one template file.

Code

Below you can find the code for this example. Make sure to replace all values in <> brackets as explained in the code (after replacing, remove the brackets). For example, if the name of your SSH key is mykey, replace <insert your ssh key name here> in the code below with mykey.

heat_template_version: 2015-04-30

parameters:
   key_name:
       type: string
       label: sshkey
       description: SSH key to be used for all instances
       default: <insert your ssh key name here>
   image_id:
       type: string
       description: Image to be used. Check all available options in Horizon dashboard or, with CLI, use openstack image list command.
       default: 233656c2-2625-4b4f-a99f-d0663458e45a
   private_net_id:
       type: string
       description: ID/Name of private network
       default: <insert your network name here, e.g. cloud_johnsmith_1>

resources:
       Group_of_VMs:
               type: OS::Heat::ResourceGroup
               properties:
                       count: 4
                       resource_def:
                               type: OS::Nova::Server
                               properties:
                                       name: my_vm%index%
                                       flavor: eo2a.large
                                       image: { get_param: image_id }
                                       networks:
                                               - network: { get_param: private_net_id }
                                       key_name: { get_param: key_name }
                                       security_groups:
                                               - allow_ping_ssh_rdp
                                               - default

       VOL_FAQ:
               type: OS::Cinder::Volume
               properties:
                       name: vol
                       size: 20
                       image : { get_param: image_id }


       With_volume:
               type: OS::Nova::Server
               properties:
                       flavor: eo2a.large
                       block_device_mapping: [{"volume_size": 20, "volume_id": { get_resource: VOL_FAQ }, "delete_on_termination": False, "device_name": "/dev/vda" }]
                       networks:
                                - network: { get_param: private_net_id }
                       key_name: { get_param: key_name }
                       security_groups:
                                - allow_ping_ssh_rdp
                                - default
                       image : { get_param: image_id }

outputs:
       SERVER_DETAILS:
               description: Shows details of all virtual servers.
               value: { get_attr: [ Group_of_VMs, show ] }

After appropriate modifications, save the following code as template5.yaml

Explanation of the code

The four virtual machines which only have ephemeral storage are created as a ResourceGroup with counter. In parameter count we state that we want to generate 4 instances at once.

The fifth instance booted from a Cinder volume is created separately. First, we create a volume in the VOL_FAQ section and then we create a VM in the With_volume section.

Parameters

Here you provide default values (key_name, image_id, private_net_id in this case) and later inject them into resource definitions. The syntax is:

{get param: param_name }
ResourceGroup

Component being used for repeating deployment, e.g two identical VM’s.

Count

Defines a variable for iterative operations.

resource_def

Starting statement for defining group resources.

%index%

This is how you add iterative number to the VM name, increasing values starting from 0.

block_device_mapping

Property to define a bootable Cinder volume for instance.

outputs

Additional information concerning deployed elements of the stack. In this case it returns a “show” attribute output. You can examine this kind of information by using openstack stack output list. Available attributes for every component can be found here..

Launching the Stack using Heat

Execute the template with the following command:

openstack stack create -t template5.yaml five

The name of the stack will be five. This is the result in CLI window:

../_images/create_heat_51.png

Once the building of virtual machines is over, the new instances should be available in the Compute -> Instance section of the Horizon dashboard:

../_images/five_created1.png

Four of them have names my_vm0, my_vm1, my_vm1 and my_vm1, as defined in line name: my_vm%index% in the template.

The name of the fifth VM starts with the name of the stack - five - and is proceeded by the name of the section of the template responsible for its creation - With_volume and the final part of the name is generated automatically (in your case it might be different).

What To Do Next

Apart from writing your templates as yaml files manually, you can also use option Orchestration -> Template Generator, which will enable you to enter components in an interactive way:

../_images/template_generator1.png

Further explanation of this option is out of scope of this article.