Setting & Retrieving Ansible-Solace Log Files
When running Ansible Playbooks on a remote host, e.g. a ‘bastion’ or ‘jump’ host, we want to retrieve the log files generated by the Ansible-Solace modules to our local host (our Ansible controller) for debugging purposes.
Consider the following inventory file:
describes a bastion host
describes a solace cloud service
---
all:
hosts:
my-solace-cloud-service: # name of solace cloud service
# start: bastion host config
ansible_become: true
ansible_host: {ip-address-of-bastion-host}
ansible_python_interpreter: /usr/bin/python3
ansible_user: {ansible-user-on-bastion-host}
# log path on bastion host
# note: ensure that the ansible_user (here: root) has write access to the path
ansible_solace_log_base_path: /var/local
# end: bastion host config
# start: solace cloud service config
broker_type: solace_cloud
meta:
datacenterId: aws-ca-central-1a
sc_service_id: d9x91ert6e
serviceClassDisplayedAttributes:
Clients: '250'
High Availability: HA Group
Message Broker Tenancy: Dedicated
Network Speed: 450 Mbps
Network Usage: 50 GB per month
Queues: '250'
Storage: 25 GB
serviceClassId: enterprise-250-nano
serviceTypeId: enterprise
service_name: asct_sc_bastion_2
sempv2_host: {dns-or-ip-of-semp-service-of-broker-service}
sempv2_is_secure_connection: true
sempv2_password: {password}
sempv2_port: 943
sempv2_timeout: '60'
sempv2_username: {username}
solace_cloud_service_id: d9x91ert6e
virtual_router: primary
vpn: my-solace-cloud-service
# end: solace cloud service config
We can use the following playbook to:
create a dynamic log file name with date/time stamp & inventory hostname
define & setup two handlers, one to fetch the log file from the remote host, the other one to delete it
a block for all the ansible-solace tasks:
this ensures the handlers are always executed, regardless of error or success
set the environment variables for logging: ANSIBLE_SOLACE_ENABLE_LOGGING & ANSIBLE_SOLACE_LOG_PATH
a variable ANSIBLE_SOLACE_LOCAL_LOG_BASE_PATH with the path on the ansible controller for the log files
hosts: all
gather_facts: yes
any_errors_fatal: true
collections:
- solace.pubsub_plus
module_defaults:
# ... define additional module defaults
solace_queue:
host: "{{ sempv2_host }}"
port: "{{ sempv2_port }}"
secure_connection: "{{ sempv2_is_secure_connection }}"
username: "{{ sempv2_username }}"
password: "{{ sempv2_password }}"
timeout: "{{ sempv2_timeout }}"
msg_vpn: "{{ vpn }}"
handlers:
- name: Fetch log file
fetch:
src: "{{ remote_ansible_solace_log_path }}"
dest: "{{ ANSIBLE_SOLACE_LOCAL_LOG_BASE_PATH }}/"
flat: yes
fail_on_missing: no
listen: log-file-handler
no_log: true
- name: Delete log file
file:
path: "{{ remote_ansible_solace_log_path }}"
state: absent
listen: log-file-handler
pre_tasks:
# generate the name of the log file with timestamp and inventory host
- set_fact:
# Note: use this custom formatting, no ':' in file name!
date_time_file: "{{ lookup('pipe','date +%Y-%m-%d-%H-%M-%S') }}"
- set_fact:
# e.g. resulting in: /var/local/my-solace-cloud-service.2021-05-14-09-01-00.ansible-solace.log
remote_ansible_solace_log_path: "{{ ansible_solace_log_base_path }}/{{ inventory_hostname }}.{{ date_time_file }}.ansible-solace.log"
tasks:
# ensure the handler is notified at least once
- name: Set up Handler
debug:
msg: setup handler
changed_when: true
notify: log-file-handler
- name: Block of ansible-solace tasks
block:
- name: Create Queue
solace_queue:
name: my-queue
state: present
environment:
ANSIBLE_SOLACE_ENABLE_LOGGING: true
ANSIBLE_SOLACE_LOG_PATH: "{{ remote_ansible_solace_log_path }}"
always:
# ensure handlers are called no matter if a task inside the block fails or not
- meta: flush_handlers
… and call the playbook with the local log path:
bastionVmPrivateKeyFile="bastionvm_key"
ansibleSolaceLocalLogBasePath="my/path/to/my/log/files"
mkdir -p $ansibleSolaceLocalLogBasePath
ansible-playbook \
-i inventory.yml \
playbook.yml \
--private-key $bastionVmPrivateKeyFile \
--extra-vars "ANSIBLE_SOLACE_LOCAL_LOG_BASE_PATH=$ansibleSolaceLocalLogBasePath"