Chapter 6. Composable Services

In Red Hat OpenStack Platform, you can define custom roles and compose service combinations on roles. For more information, see Composable Services and Custom Roles in the Advanced Overcloud Customization guide. As part of the integration, you can define your own custom services and include them on chosen roles. This section explores the composable service architecture and provides an example of how to integrate a custom service into the composable service architecture.

6.1. Examining Composable Service Architecture

The core Heat template collection contains two sets of composable service templates:

  • deployment contains the templates for key OpenStack Platform services.
  • puppet/services contains legacy templates for configuring composable services. In some cases, the composable services use templates from this directory for compatibility. In most cases, the composable services use the templates in the deployment directory.

Each template contains a description that identifies its purpose. For example, the deployment/time/ntp-baremetal-puppet.yaml service template contains the following description:

description: >
  NTP service deployment using puppet, this YAML file
  creates the interface between the HOT template
  and the puppet manifest that actually installs
  and configure NTP.

These service templates are registered as resources specific to a Red Hat OpenStack Platform deployment. This means you can call each resource using a unique Heat resource namespace defined in the overcloud-resource-registry-puppet.j2.yaml file. All services use the OS::TripleO::Services namespace for their resource type.

Some resources use the base composable service templates directly. For example:

resource_registry:
  ...
  OS::TripleO::Services::Ntp: deployment/time/ntp-baremetal-puppet.yaml
  ...

However, core services require containers and use the containerized service templates. For example, the keystone containerized service uses the following resource:

resource_registry:
  ...
  OS::TripleO::Services::Keystone: deployment/keystone/keystone-container-puppet.yaml
  ...

These containerized templates usually reference other templates to include dependencies. For example, the deployment/keystone/keystone-container-puppet.yaml template stores the output of the base template in the ContainersCommon resource:

resources:
  ContainersCommon:
    type: ../containers-common.yaml

The containerized template can then incorporate functions and data from the containers-common.yaml template.

The overcloud.j2.yaml Heat template includes a section of Jinja2-based code to define a service list for each custom role in the roles_data.yaml file:

{{role.name}}Services:
  description: A list of service resources (configured in the Heat
               resource_registry) which represent nested stacks
               for each service that should get installed on the {{role.name}} role.
  type: comma_delimited_list
  default: {{role.ServicesDefault|default([])}}

For the default roles, this creates the following service list parameters: ControllerServices, ComputeServices, BlockStorageServices, ObjectStorageServices, and CephStorageServices.

You define the default services for each custom role in the roles_data.yaml file. For example, the default Controller role contains the following content:

- name: Controller
  CountDefault: 1
  ServicesDefault:
    - OS::TripleO::Services::CACerts
    - OS::TripleO::Services::CephMon
    - OS::TripleO::Services::CephExternal
    - OS::TripleO::Services::CephRgw
    - OS::TripleO::Services::CinderApi
    - OS::TripleO::Services::CinderBackup
    - OS::TripleO::Services::CinderScheduler
    - OS::TripleO::Services::CinderVolume
    - OS::TripleO::Services::Core
    - OS::TripleO::Services::Kernel
    - OS::TripleO::Services::Keystone
    - OS::TripleO::Services::GlanceApi
    - OS::TripleO::Services::GlanceRegistry
...

These services are then defined as the default list for the ControllerServices parameter.

Note

You can also use an environment file to override the default list for the service parameters. For example, you can define ControllerServices as a parameter_default in an environment file to override the services list from the roles_data.yaml file.

6.2. Creating a User-Defined Composable Service

This example examines how to create a user-defined composable service and focuses on implementing a message of the day (motd) service. This example assumes the overcloud image contains a custom motd Puppet module loaded either through a configuration hook or through modifying the overcloud images as per Chapter 3, Overcloud Images.

When creating your own service, there are specific items to define in the service’s Heat template:

parameters

The following are compulsory parameters that you must include in your service template:

  • ServiceNetMap - A map of services to networks. Use an empty hash ({}) as the default value as this parameter is overriden with values from the parent Heat template.
  • DefaultPasswords - A list of default passwords. Use an empty hash ({}) as the default value as this parameter is overriden with values from the parent Heat template.
  • EndpointMap - A list of OpenStack service endpoints to protocols. Use an empty hash ({}) as the default value as this parameter is overriden with values from the parent Heat template.

Define any additional parameters that your service requires.

outputs
The following output parameters define the service configuration on the host. See Appendix A, Composable service parameters for information on all composable service parameters.

The following is an example Heat template (service.yaml) for the motd service:

heat_template_version: 2016-04-08

description: >
  Message of the day service configured with Puppet

parameters:
  ServiceNetMap:
    default: {}
    type: json
  DefaultPasswords:
    default: {}
    type: json
  EndpointMap:
    default: {}
    type: json
  MotdMessage: 1
    default: |
      Welcome to my Red Hat OpenStack Platform environment!

    type: string
    description: The message to include in the motd

outputs:
  role_data:
    description: Motd role using composable services.
    value:
      service_name: motd
      config_settings: 2
        motd::content: {get_param: MotdMessage}
      step_config: | 3
        if hiera('step') >= 2 {
          include ::motd
        }
1
The template includes a MotdMessage parameter used to define the message of the day. The parameter includes a default message but you can override it using the same parameter in a custom environment file, which is demonstrated later.
2
The outputs section defines some service hieradata in config_settings. The motd::content hieradata stores the content from the MotdMessage parameter. The motd Puppet class eventually reads this hieradata and passes the user-defined message to the /etc/motd file.
3
The outputs section includes a Puppet manifest snippet in step_config. The snippet checks if the configuration has reached step 2 and, if so, runs the motd Puppet class.

6.3. Including a User-Defined Composable Service

The aim for this example is to configure the custom motd service only on our overcloud’s Controller nodes. This requires a custom environment file and custom roles data file included with our deployment.

First, add the new service to an environment file (env-motd.yaml) as a registered Heat resource within the OS::TripleO::Services namespace. For this example, the resource name for our motd service is OS::TripleO::Services::Motd:

resource_registry:
  OS::TripleO::Services::Motd: /home/stack/templates/motd.yaml

parameter_defaults:
  MotdMessage: |
    You have successfully accessed my Red Hat OpenStack Platform environment!

Note that our custom environment file also includes a new message that overrides the default for MotdMessage.

The deployment will now include the motd service. However, each role that requires this new service must have an updated ServicesDefault listing in a custom roles_data.yaml file. In this example, we aim to only configure the service on Controller nodes.

Create a copy of the default roles_data.yaml file:

$ cp /usr/share/openstack-tripleo-heat-templates/roles_data.yaml ~/custom_roles_data.yaml

Edit this file, scroll to the Controller role, and include the service in the ServicesDefault listing:

- name: Controller
  CountDefault: 1
  ServicesDefault:
    - OS::TripleO::Services::CACerts
    - OS::TripleO::Services::CephMon
    - OS::TripleO::Services::CephExternal
...
    - OS::TripleO::Services::FluentdClient
    - OS::TripleO::Services::VipHosts
    - OS::TripleO::Services::Motd           # Add the service to the end

When creating an overcloud, include the resulting environment file and the custom_roles_data.yaml file with your other environment files and deployment options:

$ openstack overcloud deploy --templates -e /home/stack/templates/env-motd.yaml -r ~/custom_roles_data.yaml [OTHER OPTIONS]

This includes our custom motd service in our deployment and configures the service on Controller nodes only.