Logs That Leave Over TLS, With The Collector Checked

rsyslog ships logs in clear over port 514, which is what most examples do. This role configures the sending side with the gtls driver, the collector's CA and x509/name, so a host with a certificate from elsewhere in the estate cannot collect your logs. The live test watches a line arrive and reads the handshake. Original role, live-tested on Rocky Linux 10.

ansibleObservability

Verification

Live-tested

Really deployed to a container sandbox, proven idempotent (a second run changes nothing), verified against the role’s assertions, then torn down.

Conformance

  • Static validation (yamllint · ansible-lint)

Provenance

  • SHA-256 checksum
  • Signature (pending)

Functional

  • Live-tested - applied, verified, destroyed

Last verified 2026-09-27 · podman 4.9.3 · ansible 2.21.4 · how we verify

Cite it in your README

badge · attribution

Paste this beside the module in the repository that uses it. The badge is rendered from this artifact's verification record, so it reads live-tested because the record says so, and the link lands on this page.

README.md, GitLab, Gitea
[![IaC Bazaar: live-tested](https://www.iac-bazaar.com/api/artifacts/ansible-rsyslog-forward/badge)](https://www.iac-bazaar.com/catalog/ansible-rsyslog-forward?utm_source=syndication&utm_medium=readme&utm_campaign=artifact)

Ansible role 1.0.0, live-tested on IaC Bazaar: [Logs That Leave Over TLS, With The Collector Checked](https://www.iac-bazaar.com/catalog/ansible-rsyslog-forward?utm_source=syndication&utm_medium=readme&utm_campaign=artifact)

```yaml
# Logs That Leave Over TLS, With The Collector Checked: https://www.iac-bazaar.com/catalog/ansible-rsyslog-forward (download from your IaC Bazaar account)
```

Preview:IaC Bazaar: live-tested

Documentation

rsyslog-forward

Logs leave this host over TLS, and the collector has to prove who it is. rsyslog will happily ship to a collector in clear over port 514, and that is what most examples do. This role configures the sending side with the gtls driver, the collector's CA, and x509/name - so a host with a valid certificate from somewhere else in the estate cannot collect your logs - and gives the action its own queue so a collector that is down does not stop the host writing its own log.

No download, and no version to pin. rsyslog and rsyslog-gnutls are EL 10 packages. What the role owns is one file in /etc/rsyslog.d and the proof that a message logged here arrives there, over a session whose certificate validates.

There is no global() block and no module(load="omfwd") line, and both omissions are deliberate. omfwd is compiled into rsyslogd on EL, and a module() line naming it takes the whole configuration down with it - which is what killed the first two attempts at this role in this catalogue. rsyslogd -N1 validates the whole configuration and runs on every converge.

This role was dropped twice before it was written. Wave BA tried it and could not get a message to cross a TLS session, twice, and recorded the failure rather than shipping an untested TLS half. What it took on the third attempt: the global() object carrying the driver name with the CA, certificate and key; the listener's StreamDriver.Name, .Mode and .AuthMode given as module and input parameters; and the omfwd action carrying its own StreamDriver, StreamDriverMode, StreamDriverAuthMode and StreamDriverPermittedPeers. Both anon and x509 deliver; the role ships x509/name.

Nothing here is global, and that is a compatibility requirement rather than a preference. rsyslog allows exactly one global() object: a second one setting the same parameter is refused with "specified more than once", and rsyslog then refuses the whole configuration rather than the file that caused it. The rsyslog-remote role in this catalogue writes a global() of its own, with the ossl driver where this role uses gtls, so a version of this role that configured the driver globally could never have shared a host with it. rsyslogd -N1 caught that on the first run, which is the second reason it is a task and not a comment.

"It arrived" is not enough on its own. A message crossing proves bytes moved, not that they moved over a verified session - so the live test also asks openssl s_client what the collector presents, and requires "Verify return code: 0 (ok)" against the CA. The two assertions together are the claim.

A collector that is down must not take local logging with it, and the live test checks that - it points the forwarder at a port nobody answers, restarts rsyslog, and requires that the host's own /var/log/messages still receives a line and that rsyslog is still running. What that assertion does NOT prove is the queue: turning rsyslog_forward_queue_enabled off and running the whole test again left every assertion green, so rsyslog does not block its main path on this action either way. The queue and action.resumeRetryCount="-1" are there so a message WAITS for a collector that is away instead of being dropped, and that half is not demonstrated here - the collector this test stands up is the same rsyslogd, so it cannot be stopped and restarted on its own. Said plainly rather than implied, because a passing assertion next to a setting invites the reader to connect them.

The role refuses to run without the collector's CA file. Without it rsyslog cannot verify anything and every message sits in the queue while nothing explains why, so the role checks first and stops with a message naming the file.

License

Commercial - IaC Bazaar EULA. (c) IaC Bazaar.

Usage code & full reference need an account

The complete copy-paste usage, the full input/output reference, and operational notes are free with an account - shown here and bundled in the download. Sign in and this section fills in.

  • Variables
  • Test

Related modules

Live-tested

ansible-alertmanager

Prometheus Alertmanager from the upstream release (sha256-verified) as a hardened system service on loopback, its cluster gossip listener switched off and its configuration checked by amtool before it lands. The live test posts an alert through the API and reads it back active, held by the default receiver, and expects no 9094 listener at all. Original role, live-tested on Rocky Linux 10.

View module
Live-tested

ansible-alloy

Grafana Alloy from the upstream release (sha256-verified) as a hardened system service on loopback with --disable-reporting, a self-scrape pipeline that proves the collector runs, and its configuration checked by alloy validate before it lands. The live test reads Alloy's own metrics and asks the component API for the scrape component's health. Original role, live-tested on Rocky Linux 10.

View module
Live-tested

ansible-blackbox-exporter

Prometheus Blackbox exporter from the upstream release (sha256-verified) as a hardened system service on loopback with HTTP and TCP modules, checked by --config.check before the file lands. The live test has it probe itself over HTTP and TCP (probe_success 1) and a port with nothing behind it (probe_success 0): it measures, not only answers. Original role, live-tested on Rocky Linux 10.

View module
Live-tested

ansible-grafana-server

Grafana on loopback with a secret key of yours: every install that never set one shares the package's, which encrypts the data-source credentials in its database. Secure cookies and HSTS for the TLS proxy in front; public snapshots, plugin update checks, feedback links and Gravatar switched off. Settings verified through the API, not the file. Original role, live-tested on Rocky Linux 10.

View module
Live-tested

ansible-grafana

Grafana (sha256-verified) on EL 10 from the upstream release, as a hardened systemd service on loopback; the live test reads back the datasource this role provisioned, creates a dashboard and finds it by search, sees anonymous and wrong-password requests refused, and reads the build metric naming the version installed. Original role, live-tested on Rocky Linux 10.

View module
Live-tested

ansible-jaeger

Jaeger v2, the tracing backend built on the OpenTelemetry Collector, from the upstream release (sha256-verified against the right checksum file) as a hardened system service on loopback with badger storage and the query API on loopback. The live test pushes a span over OTLP and reads the trace back by id with its name and service. Original role, live-tested on Rocky Linux 10.

View module