Avi Heat Resources

This article cites benefits of using OpenStack Heat to describe an application via a template. Examples using Avi Heat resources are included.

Introduction to OpenStack Heat

“The mission of the OpenStack Orchestration program is to create a human- and machine-accessible service for managing the entire lifecycle of infrastructure and applications within OpenStack clouds.” (Source: https://wiki.openstack.org/wiki/Heat)

All OpenStack services such as Nova, Neutron, and Glance are API-driven. Though using APIs is the most basic way to obtain a service, APIs work on the granularity of individual objects. And, as any real usage of an OpenStack public cloud involves creating several objects on different services, using APIs directly for orchestration is a tedious process. For example, to create a typical three-tier application, one has to upload their application images to Glance, create storage volumes in Cinder, create different virtual networks for each tier using Neutron APIs, create appropriate security groups using Nova or Neutron APIs, and create virtual machines using Nova APIs. In addition, we may need to make another Neutron API call to create a floating IP for the application.

Creation is tedious also because some of those API calls depend on the resources created by other API calls. For example, Glance image upload has to succeed before VMs can be created. And you need the UUID of the Glance image for the VM creation. Or you need the IP address of the front-end server VM to create the floating IP association.

Updates are even worse, because you need to know the exact sequence of all objects to update. Suppose you want to use a different volume for one of your VMs. Then you need to remove the previous VM and create a new VM with that new volume. And you may need to update the floating IP if that VM is the front-end server.

Deletion requires several API calls which need to be done in the reverse order of creation to ensure no dependencies are violated.

Dealing with all objects as a single entity makes the orchestration much simpler, enabling creation or deletion of an entire application “stack” with one command.

To that end, Heat service allows users to describe their application as a Heat template with

  • Support for create, update and delete actions
  • Ability to operate on a whole-stack level, rather than in individual-element fashion
  • Easy deletion of all elements in the stack because Heat describes and tracks all created objects
  • Easy update and state-tracking for all elements in the stack

Note: In the case of scripts, one needs to remove all resources and recreate them.

Downsides

You can’t use Heat resources to manage pre-existing objects. Only those resources created via a stack can be managed by the heat-engine.

Stacks are stateful, and therefore always track the current state. And any changes to the stack spec can be automatically applied by the heat-engine since it can determine the appropriate steps needed to go from a previous state to the next state.

In contrast, with stateless orchestration systems such as Ansible, you need to remove an object explicitly (e.g., setting “state=absent” in your yaml spec file). Then you have to remove the object/resource from your spec file so that further runs don’t try to delete it again or to save the clutter.

Example

Below we create a network, subnet, router, create web server, and associate a floating IP address.


heat_template_version: 2015-04-30

description: Web service with its own virtual network template

parameters:
  external_net:
    type: string
    label: External Net
    description: UUID of the external network for Internet access

resources:
  my_net:
        type: OS::Neutron::Net
        properties:
          name: my-net

  my_subnet:
        type: OS::Neutron::Subnet
        properties:
          network_id: { get_resource: my_net }
          cidr: 10.10.2.0/24
          gateway_ip: 10.10.2.1

  my_router:
        type: OS::Neutron::Router
        properties:
          external_gateway_info:
                network: { get_param: public_net }

  my_router_interface:
        type: OS::Neutron::RouterInterface
        properties:
          router_id: { get_resource: my_router }
          subnet_id: { get_resource: my_subnet }

  my_instance:
    type: OS::Nova::Server
    properties:
      image: web-server
      flavor: m1.medium

  floating_ip:
    type: OS::Neutron::FloatingIP
    properties:
      floating_network: { get_param: public_net }

  association:
    type: OS::Neutron::FloatingIPAssociation
    properties:
      floatingip_id: { get_resource: floating_ip }
      port_id: {get_attr: [my_instance, addresses, {get_param: net}, 0, port]}

Avi Heat Resource Types

All resource types are exposed via Heat. Therefore, templates can instantiate and manage the life cycle of Avi resources directly via their Heat stacks. One can check the resource types by invoking heat resource-type-list and grepping for Avi::LBaaS::. All available options for a resource type can be obtained by heat resource-type-show <RESOURCE_NAME>

Create two webservers, create a pool, add load balancer in front

Add a health monitor to detect when a back-end member is down

Servers in a pool are of separate resource type.

Obtaining Avi UUIDs by Using Names

For properties that need UUIDs, you can specify a name but prefixed with string get_avi_uuid_by_name:. Internally, heat-engine would perform an API call to resolve the provided name into the Avi UUID.


heat_template_version: 2015-04-30

description: >
Example template to add a member to an existing pool on Avi. Existing pool is specified using name instead of UUID.

# Make sure that testpool already exists on Avi
resources:
  member:
    type: Avi::LBaaS::Pool::Server
    properties:
      pool_uuid:  get_avi_uuid_by_name:testpool
      ip:
        addr: 10.10.10.50
        type: V4
      port: 8080

Sometimes you may want to provide the name for a UUID property via an input parameter to your template rather than hard-coding it as in the example above. You can achieve that as in the following example:


heat_template_version: 2015-04-30
description: >
  Example template that takes pool_name as an input
  parameter

# Make sure that pool_name provided already exists on Avi.
parameters:
   pool_name:
    type: string
    label: Pool Name

resources:
  member:
    type: Avi::LBaaS::Pool::Server
    properties:
      pool_uuid:
        str_replace:
          template: get_avi_uuid_by_name:pname
          params:
            pname: { get_param: pool_name }
      ip:
        addr: 10.10.10.50
        type: V4
      port: 8080

Avi Resource Types vs. OpenStack LBaaS Resource Types

OpenStack Heat ships with LBaaS v1 (to be deprecated soon) and LBaaS v2 resource types. One can use Avi resource types in templates to leverage the extensive features available in Avi Vantage, especially for the features that are not available via LBaaS. Installation The Avi Heat repository is Open Source and is available online on GitHub at https://github.com/avinetworks/avi-heat. Please follow the installation instructions from the README on the main page.