A simple tutorial for getting started with Heat, OpenStack’s orchestration service.

image

This article first appeared on Christian’s blog. Christian Berendt
is currently working as a cloud solution architect for B1 Systems. You should follow him on GitHub.

Heat is the orchestration service included in OpenStack. In teamwork with Ceilometer it is possible to build auto scaling environments. A good entry point to learn how to write Heat Orchestration Templates (HOT) is the HOT Guide. A list of all available resource types (only a few of them are used in the following example) is available in the HOT Reference. Tons of example templates are available in the repository openstack/heat-templates. This article is based on the autoscaling.yaml example template.

Presumptions for the following example:

  • an image with the name Cirros 0.3.3 is available (glance image-create --name "Cirros 0.3.3" --disk-format qcow2 --container-format bare --is-public True --copy http://download.cirros-cloud.net/0.3.3/cirros-0.3.3-x86_64-disk.img)
  • a flavor with the name m1.nano is available (nova flavor-create m1.nano 42 64 0 1)
  • a network with the name internal001 is available (neutron net-create internal001; neutron subnet-create --name internal001 internal001 192.168.200.0/24)

First create a template for a stack with a single instance in the file cirros.yaml.

heat_template_version: 2014-10-16  
description: A simple server.  
resources:  
  server:
    type: OS::Nova::Server
    properties:
      block_device_mapping:
        - device_name: vda
          delete_on_termination: true
          volume_id: { get_resource: volume } 
      flavor: m1.nano
      networks:
        - network: internal001

  volume:
    type: OS::Cinder::Volume
    properties:
      image: 'Cirros 0.3.3'
      size: 1

To validate the syntax use heat template-validate --template-file cirros.yaml.

Test if the template is working like expected with heat stack-create -f cirros.yaml cirros. After a few seconds (or minutes, depends on the environment) heat stack-list should show a stack with stack_status = CREATE_COMPLETE. If not have a look in the output of heat event-list cirros to identify the issue.

To delete the stack run heat stack-delete cirros.

Let’s add a script that generates a high load on all cores of the instance. A high CPU load will be the trigger to launch further instances.

Add the properties user_data_format and user_data to the definition of server.

      user_data_format: RAW
      user_data: |
        #!/bin/sh
        while [ 1 ] ; do echo $((13**99)) 1>/dev/null 2>&1; done &

The cirros.yaml file should now have the following content:

heat_template_version: 2014-10-16  
description: A simple server.  
resources:  
  server:
    type: OS::Nova::Server
    properties:
      block_device_mapping:
        - device_name: vda
          delete_on_termination: true
          volume_id: { get_resource: volume }
      flavor: m1.nano
      networks:
        - network: internal001
      user_data_format: RAW
      user_data: |
        #!/bin/sh
        while [ 1 ] ; do echo $((13**99)) 1>/dev/null 2>&1; done

  volume:
    type: OS::Cinder::Volume
    properties:
      image: 'Cirros 0.3.3'
      size: 1

Create the file environment.yaml to define a new resource type OS::Nova::Server::Cirros.

resource_registry:  
    "OS::Nova::Server::Cirros": "cirros.yaml"

Create a OS::Heat::AutoScalingGroup resource in the file simple.yaml. This group defines the resources that should be scaled.

heat_template_version: 2014-10-16  
description: A simple auto scaling group.  
resources:  
  group:
    type: OS::Heat::AutoScalingGroup
    properties:
      cooldown: 60
      desired_capacity: 2
      max_size: 5
      min_size: 1
      resource:
        type: OS::Nova::Server::Cirros

Start the stack with heat stack-create simple -f simple.yaml -e environment.yaml. There should be 2 instances, the value of the desired_capacity parameter, and nothing more should happen.

Delete the stack with heat stack-delete simple and add the following resources to complete the example.

First a OS::Heat::ScalingPolicy resource.

  scaleup_policy:
    type: OS::Heat::ScalingPolicy
    properties:
      adjustment_type: change_in_capacity
      auto_scaling_group_id: { get_resource: group }
      cooldown: 60
      scaling_adjustment: 1

Finally a OS::Ceilometer::Alarm resource. This resource will notify the scaling policy resource. The scaling policy resource will increase the number of the resources defined in the scaling group.

  cpu_alarm_high:
    type: OS::Ceilometer::Alarm
    properties:
      meter_name: cpu_util
      statistic: avg
      period: 60
      evaluation_periods: 1
      threshold: 50
      alarm_actions:
        - {get_attr: [scaleup_policy, alarm_url]}
      comparison_operator: gt

The simple.yaml file should now have the following content:

heat_template_version: 2014-10-16  
description: A simple auto scaling group.  
resources:  
  group:
    type: OS::Heat::AutoScalingGroup
    properties:
      cooldown: 60
      desired_capacity: 2
      max_size: 5
      min_size: 1
      resource:
        type: OS::Nova::Server::Cirros

  scaleup_policy:
    type: OS::Heat::ScalingPolicy
    properties:
      adjustment_type: change_in_capacity
      auto_scaling_group_id: { get_resource: group }
      cooldown: 60
      scaling_adjustment: 1

  cpu_alarm_high:
    type: OS::Ceilometer::Alarm
    properties:
      meter_name: cpu_util
      statistic: avg
      period: 60
      evaluation_periods: 1
      threshold: 50
      alarm_actions:
        - {get_attr: [scaleup_policy, alarm_url]}
      comparison_operator: gt

Start the complete stack with heat stack-create simple -f simple.yaml -e environment.yaml.

At the beginning there are only 2 instances. After some time (more than 10 minutes because of the default interval of Ceilometer) the number of instances increases to a maximum of 5, the value of the max_size parameter.

Photo by rogersmith // CC BY NC ND

Christian Berendt
Latest posts by Christian Berendt (see all)