Feb 13, 2020
5 Min read

A Real World HOT File

Heat is a template based resource orchestration service for OpenStack. It can be used to deploy cloud applications of any complexity.

In a previous post we introduced the basic usage of Heat, with a simplified HOT file. Today, we will build on that foundation by creating and deploying a more advanced Heat stack.

This is a real world Heat template, which creates a single VM. Let’s go through its each section to see what is happenning.

Since we are familiar with heat_template_version, description, and parameters sections we will go straight to the resources section, which creates the virtual resources.

flavor

#flavor
app_server_flavor:
type: OS::Nova::Flavor
properties:
    name: "app_server"
    vcpus: 2
    ram: 4096
    disk: 100
    extra_specs: { "hw:cpu_policy" : "dedicated", "hw:mem_page_size": "1048576" }
 

Nova flavor defines how much vCPUs, memory (MB), and disk (GB) is allocated to the VM.

extra_specs is used to define a list of key-value pairs, which can control some features in VM and scheduling behaviors in OpenStack. hw:cpu_policy, and hw:mem_page_size are two of the most common parameters related to CPU pinning and huge page allocation in VMs.

security groups

Security groups act as a basic firewall in controlling access to a VM. Each virtual port should be associated with at least one security group, or OpenStack will apply the default security group in that particular project. Unless you have changed this default security group, all incoming traffic will be denied, and only outgoing traffic will be allowed.

  #security groups
  oam_security_group:
    type: OS::Neutron::SecurityGroup
    properties:
      name: "app_server_oam"
      rules:
        - remote_ip_prefix: "0.0.0.0/0"
          protocol: "tcp"
          port_range_min: 22
          port_range_max: 22
        - remote_ip_prefix: "0.0.0.0/0"
          protocol: "tcp"
          direction: "egress"
          port_range_min: 22
          port_range_max: 22
  service_security_group:
    type: OS::Neutron::SecurityGroup
    properties:
      name: "app_server_service"
      rules:
        - remote_ip_prefix: "0.0.0.0/0"
          protocol: "tcp"
          port_range_min: 1
          port_range_max: 65534
        - remote_ip_prefix: "0.0.0.0/0"
          protocol: "tcp"
          direction: "egress"
          port_range_min: 1
          port_range_max: 65534
        - remote_ip_prefix: "0.0.0.0/0"
          protocol: "icmp"
        - remote_ip_prefix: "0.0.0.0/0"
          protocol: "icmp"
          direction: "egress"

This template is creating two security groups; oam_security_group, and service_security_group. Each security group contains a list of security rules, which defines the IP, port details that are allowed to and from the VM.

A security rule rule applies to a single direction, so separate rules must be created for incoming and outgoing traffic. Security rules with direction set to egress applies to traffic going out from the VM, while ingress rules applies to traffic coming in to the VM.

As you may observe, oam_security_group is allowing only TCP port 22 (ssh), and app_server_service is allowing all TCP and ICMP traffic in both directions.

The protocols and ports not specified by security rules will be denied, so both security groups will not allow UDP in either direction..

ports

app_server has two virtual ports. The get_resource parameter in Heat is used to refer to a virtual resource created in the same HOT file. Both ports use this to specify the securiy groups that we described above.

  #ports
  oam_port:
    type: OS::Neutron::Port
    properties:
      name: "app_server_oam"
      network: { get_param: oam_net } 
      fixed_ips:
        - ip_address: "10.10.10.5"
      security_groups:
        - { get_resource: oam_security_group}
  service_port:
    type: OS::Neutron::Port
    properties:
      name: "app_server_service"
      network: { get_param: service_net } 
      fixed_ips:
        - ip_address: "10.10.20.5"
      security_groups:
        - { get_resource: service_security_group}

virtual machine

  #virtual machine       
  app_server:
    type: OS::Nova::Server
    properties:
      config_drive: "true"
      name: { get_param: app_server_name }
      flavor: { get_resource: app_server_flavor }
      image: { get_param: app_server_image_name }
      availability_zone: "zone-a"
      networks:
      - port: { get_resource: oam_port }
      - port: { get_resource: service_port }
      user_data_format: RAW
      user_data: |
        #cloud-config
        password: app_server_password
        chpasswd: { expire: False }
        ssh_pwauth: True

Our HOT package creates only one VM. We are using the get_resource to refer to the flavor and virtual ports. The get_param is used to refer to values defined in parameters section.

Most of the cloud images provided by major linux distributioins such as Centos and Ubuntu, do not allow password based authentication by default. We are using user_data to set the password of the default user, and enable password authentication for SSH. Alternatively we can use key based authentication by creaitng a key pair.

We can deploy the Heat stack using the methods described in previous post.

Although we can use OpenStack CLI to create security groups and flavor, we have decided to create them via the HOT file itself. An advantage of this approach is that when the Heat stack is deleted, all the associated resources will also be deleted, so less manual cleansing is required.

The complete HOT file can be found here. In future posts we will expore more about Heat.