solace_broker_service - manage a broker service

Manage a self-hosted Broker Service running in Docker.

This role is a wrapper around community.general.docker_compose. It also uses solace_get_available – check if broker semp & spool is available for state=present to ensure the broker service has initialized properly.

Note

The role only supports a single node (not H/A).

When using a remote VM:
  • ensure ansible has access to the public key for the VM

  • ensure the SEMP http/https ports on the VM are open

Prerequisites

Examples

Start Single Broker on Remote Ubuntu-18 VM

Example ansible controller ssh config:

Switch off host key checking:

mkdir -p ~/.ssh
echo "Host *" > ~/.ssh/config
echo " StrictHostKeyChecking no" >> ~/.ssh/config

Example Bootstrap for Ubuntu-18:

#!/usr/bin/env bash

scriptName=$(basename $(test -L "$0" && readlink "$0" || echo "$0"));

############################################################################################################################
# Bootstrap Ubuntu-18 VM with prerequisites to run role solace_broker_service.
# Note:
#   ssh requires public key to be available in ~/.ssh/
#


############################################################################################################################
# Check Environment Variables

  if [ -z "$vmAdminUsr" ]; then echo ">>> XT_ERROR: - $scriptName - missing env var: vmAdminUsr"; exit 1; fi
  if [ -z "$vmPublicIpAddress" ]; then echo ">>> XT_ERROR: - $scriptName - missing env var: vmPublicIpAddress"; exit 1; fi

############################################################################################################################
# Run

echo " >>> Bootstrap vm ..."

ssh "$vmAdminUsr@$vmPublicIpAddress" <<BOOT_EOL
  sudo apt-get update
  sudo apt-get -y upgrade
  echo ">>> docker =================================================="
  sudo apt-get install apt-transport-https ca-certificates curl software-properties-common -y
  curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
  apt-cache policy docker-ce
  sudo apt-get install --upgrade docker-ce -y
  echo ">>> python =================================================="
  sudo apt-get install --upgrade python3
  sudo apt-get install --upgrade python3-pip -y
  sudo -H python3 -m pip install --upgrade pip
  sudo -H python3 -m pip install --upgrade docker
  sudo -H python3 -m pip install --upgrade docker-compose
  echo ">>> upgrading =================================================="
  sudo apt-get update
  sudo apt-get -y upgrade
BOOT_EOL

if [[ $? != 0 ]]; then echo " >>> XT_ERROR: bootstrap vm"; exit 1; fi

echo " >>> Success."


###
# The End.

Example Template Inventory File for Remote VM:

---
all:
  hosts:
    remotehost:
      ansible_host: "public-ip-address"
      ansible_user: "admin-user"
      ansible_become: true
      ansible_python_interpreter: "/usr/bin/python3"
      solace_broker_service:
        semp_host: "fqdns"
        semp_port_plain: 8080
        semp_port_secure: 1943

Example Inventory File for Local Machine (the Ansible controller):

---
all:
 hosts:
   localhost:
     ansible_connection: local

Example Playbook to Create & Delete a Service using the default settings:

-
  name: broker service create and delete
  hosts: all
  tasks:
  - name: standup broker service
    include_role:
      name: solace.pubsub_plus.solace_broker_service
    vars:
      docker_compose_settings:
        project_name: my-docker-project-name
        state: present

  - name: "Output the role results"
    debug:
      msg: "{{ solace_broker_service_result }}"

  - name: "Output the broker service inventory"
    debug:
      msg: "{{ solace_broker_service_result.broker_service.inventory }}"

  - name: "Output the docker_compose settings used"
    debug:
      msg: "{{ solace_broker_service_result.broker_service.docker_compose_settings }}"

  - name: "Output docker logs"
    debug:
      msg: "{{ solace_broker_service_result.broker_service.docker_logs }}"

  - name: delete broker service
    include_role:
      name: solace.pubsub_plus.solace_broker_service
    vars:
      docker_compose_settings:
        project_name: my-docker-project-name
        definition: "{{ solace_broker_service_result.broker_service.docker_compose_settings.definition }}"
        state: absent

Run the Playbook:

This playbook will:
  • download the latest Solace PubSub+ standard edition image from docker hub

  • start the docker container

  • wait until the broker service is up and running, including a test if message spool is availabe

  • uses the default definition values for docker-compose

  • outputs

  • delete the service again

    • using the same project name

    • using the same docker compose definition

ansible-playbook \
              -i {inventory-file} \
              {playbook-file}

Example Playbook with default settings and docker compose file:

-
  name: create broker service
  hosts: all
  tasks:
  - name: set docker compose yaml file
    set_fact:
      broker_docker_compose_file: "{path}/docker_compose_file.yml"

  - name: create broker service with docker compose file
    include_role:
      name: solace.pubsub_plus.solace_broker_service
    vars:
      docker_compose_settings:
        project_name: my-docker-project-name
        state: present
        definition: "{{ lookup('file', broker_docker_compose_file) | from_yaml }}"

Example Playbook with default settings and inline definition for docker compose:

-
  name: create broker service
  hosts: all
  tasks:
  - name: set the docker compose definition
    set_fact:
      _docker_compose_definition:
        version: '3.3'
        services:
          primary:
            container_name: my-container
            image: solace/solace-pubsub-standard:latest
            restart: unless-stopped
            shm_size: 1g
            ulimits:
              core: 2
              nofile:
                soft: 2448
                hard: 38048
            volumes:
              - "/var/local/spool/softAdb:/usr/sw/internalSpool/softAdb:Z"
              - "/var/local/spool:/usr/sw/internalSpool:Z"
              - "/var/local/jail:/usr/sw/jail:Z"
              - "/var/local/diagnostics:/var/lib/solace/diags:Z"
              - "/var/local/adbBackup:/usr/sw/adb:Z"
              - "/var/local/var:/usr/sw/var:Z"
            ports:
              - "8080:8080"
              - '1883:1883'
            environment:
              - username_admin_globalaccesslevel=admin
              - username_admin_password=admin
              - system_scaling_maxconnectioncount=100

  - name: create broker service
    include_role:
      name: solace.pubsub_plus.solace_broker_service
    vars:
      docker_compose_settings:
        project_name: my-docker-project-name
        services:
          - primary
        definition: "{{ _docker_compose_definition }}"
        recreate: always
        restarted: yes
        debug: yes
        state: present

Example docker compose definition for secure SEMP:

-
  name: create broker service
  hosts: all
  tasks:

  # set: _user
  # create: _user
  # set: ssl_cert_file

  - name: "Copy cert to mount path secrets"
    copy:
      src: "{{ ssl_cert_file }}"
      dest: "{{ /var/local/secrets }}"
      owner: "{{ _user }}"

  - set_fact:
      _ssl_cert_filename: "{{ ssl_cert_file | basename }}"

  - name: set the docker compose definition
    set_fact:
      _docker_compose_definition:
        version: '3.3'
        services:
          primary:
            container_name: my-container
            image: solace/solace-pubsub-standard:latest
            restart: unless-stopped
            shm_size: 1g
            user: "{{ _user }}"
            ulimits:
              core: 2
              nofile:
                soft: 2448
                hard: 38048
            volumes:
              - "/var/local/secrets:/run/secrets"
              - "/var/local/spool/softAdb:/usr/sw/internalSpool/softAdb:Z"
              - "/var/local/spool:/usr/sw/internalSpool:Z"
              - "/var/local/jail:/usr/sw/jail:Z"
              - "/var/local/diagnostics:/var/lib/solace/diags:Z"
              - "/var/local/adbBackup:/usr/sw/adb:Z"
              - "/var/local/var:/usr/sw/var:Z"
            ports:
              - "1943:1943"
              - "8080:8080"
              - '1883:1883'
            environment:
              - username_admin_globalaccesslevel=admin
              - username_admin_password=admin
              - system_scaling_maxconnectioncount=100
              - "tls_servercertificate_filepath=/run/secrets/{{ _ssl_cert_filename }}"

  - name: create broker service
    include_role:
      name: solace.pubsub_plus.solace_broker_service
    vars:
      docker_compose_settings:
        project_name: my-docker-project-name
        services:
          - primary
        definition: "{{ _docker_compose_definition }}"
        recreate: always
        restarted: yes
        debug: yes
        state: present

Check the certificate of the broker service:

openssl s_client -showcerts -servername {fqdns} -connect {fqdns}:1943

Parameters

Variable

Examples/Options

Description

generate

optional. sub-element inventory_settings

Combined with default_generate, allowing to override only required values.

generate.inventory_settings

optional. optional sub-elements: inventory_hostname, sempv2_host, sempv2_port, sempv2_username, sempv2_password, sempv2_is_secure_connection, vpn, virtual_router

The settings used to generate the broker service inventory.

docker_compose_settings

optional. all settings provided by community.general.docker_compose

Combined with default_docker_compose_settings, allowing to override only required values.

solace_get_available.wait_timeout_minutes

optional

wait_timeout_minutes argument for solace_get_available – check if broker semp & spool is available

Defaults

# Copyright (c) 2021, Solace Corporation, Ricardo Gomez-Ulmke, <ricardo.gomez-ulmke@solace.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
---
default_generate:
  inventory_settings:
    inventory_hostname: "{{ ansible_hostname|default(omit) }}"
    sempv2_host: "{{ ansible_host }}"
    sempv2_port: 8080
    sempv2_username: admin
    sempv2_password: admin
    sempv2_is_secure_connection: false
    sempv2_validate_certs: false
    vpn: default
    virtual_router: primary
default_docker_compose_settings:
  project_name: "{{ args.__required__ }}"
  restarted: yes
  recreate: always
  state: present
  definition:
    version: '3.3'
    services:
      primary:
        container_name: PubSubStandard_singleNode
        image: solace/solace-pubsub-standard:latest
        shm_size: 1g
        ulimits:
          core: 2
          nofile:
            soft: 2448
            hard: 38048
        deploy:
          restart_policy:
            condition: on-failure
            max_attempts: 3
        ports:
        #Port Mappings:  Ports are mapped straight through from host to
        #container.  This may result in port collisions on commonly used
        #ports that will cause failure of the container to start.
          #Web transport
          - '80:80'
          #Web transport over TLS
          - '443:443'
          #MQTT Default VPN
          - '1883:1883'
          #AMQP Default VPN over TLS
          - '5671:5671'
          #AMQP Default VPN
          - '5672:5672'
          #MQTT Default VPN over WebSockets
          - '8000:8000'
          #MQTT Default VPN over WebSockets / TLS
          - '8443:8443'
          #MQTT Default VPN over TLS
          - '8883:8883'
          #SEMP over TLS
          # - "1943:1943"
          #SEMP / PubSub+ Manager
          - "{{ combined_generate.inventory_settings.sempv2_port }}:8080"
          #REST Default VPN
          - '9000:9000'
          #REST Default VPN over TLS
          - '9443:9443'
          #SMF
          - '55554:55555'
          #SMF Compressed
          - '55003:55003'
          #SMF over TLS
          - '55443:55443'
        environment:
          - "username_admin_globalaccesslevel={{ combined_generate.inventory_settings.sempv2_username }}"
          - "username_admin_password={{ combined_generate.inventory_settings.sempv2_password }}"
          - system_scaling_maxconnectioncount=100
default_result:
  broker_service:
    inventory: null
    docker_compose_defintion: null
    docker_logs: null

Return Values

Variable

Description

solace_broker_service_result

Result dict.

solace_broker_service_result.inventory

The combined inventory for the broker service.

solace_broker_service_result.docker_compose_settings

The combined docker_compose_settings.

solace_broker_service_result.docker_logs

The docker logs from the created services. Only applies to state=present.

solace_broker_service_result.rc

The return code of the role. ok:rc=0, failed:rc=1. Returned always.

solace_broker_service_result.msg

The error details in case of failure (rc=1). Returned on error.

Example Generated Broker Service Inventory Files

The ansible_hostname variable is used as the host entry.

solace_broker_service_result.inventory

Remote VM:

all:
  hosts:
    {ansible_hostname}:
      ansible_connection: local
      broker_type: local
      sempv2_host: {FQDNS}
      sempv2_is_secure_connection: 'True'
      sempv2_password: admin
      sempv2_port: '1943'
      sempv2_timeout: '60'
      sempv2_username: admin
      virtual_router: primary
      vpn: default

Localhost:

all:
  hosts:
    {ansible_hostname}:
      ansible_connection: local
      broker_type: local
      sempv2_host: localhost
      sempv2_is_secure_connection: 'True'
      sempv2_password: admin
      sempv2_port: '1943'
      sempv2_timeout: '60'
      sempv2_username: admin
      virtual_router: primary
      vpn: default

Example Output Docker Compose Settings

solace_broker_service_result.docker_compose_settings

definition:
  services:
    primary:
      container_name: pubSubStandardSingleNode
      deploy:
        restart_policy:
          condition: on-failure
          max_attempts: 3
      environment:
      - username_admin_globalaccesslevel=admin
      - username_admin_password=admin
      - system_scaling_maxconnectioncount=100
      - tls_servercertificate_filepath=/run/secrets/asc.pem
      image: solace/solace-pubsub-standard:latest
      ports:
      - 1943:1943
      - 8080:8080
      restart: unless-stopped
      shm_size: 1g
      ulimits:
        core: 2
        nofile:
          hard: 38048
          soft: 2448
      user: '4000'
      volumes:
      - /var/local/broker_services/asc-test_roles_broker_service_single_node/secrets:/run/secrets
      - /var/local/broker_services/asc-test_roles_broker_service_single_node/data/spool/softAdb:/usr/sw/internalSpool/softAdb:Z
      - /var/local/broker_services/asc-test_roles_broker_service_single_node/data/spool:/usr/sw/internalSpool:Z
      - /var/local/broker_services/asc-test_roles_broker_service_single_node/data/jail:/usr/sw/jail:Z
      - /var/local/broker_services/asc-test_roles_broker_service_single_node/data/diagnostics:/var/lib/solace/diags:Z
      - /var/local/broker_services/asc-test_roles_broker_service_single_node/data/adbBackup:/usr/sw/adb:Z
      - /var/local/broker_services/asc-test_roles_broker_service_single_node/data/var:/usr/sw/var:Z
  version: '3.3'
project_name: asc-test_roles_broker_service_single_node
services:
- primary