Skip to content

feat: add TLS certificate and key support for Grafana for HTTPS#284

Merged
richm merged 1 commit intolinux-system-roles:mainfrom
richm:feat-grafana-cert-key
Jan 20, 2026
Merged

feat: add TLS certificate and key support for Grafana for HTTPS#284
richm merged 1 commit intolinux-system-roles:mainfrom
richm:feat-grafana-cert-key

Conversation

@richm
Copy link
Copy Markdown
Collaborator

@richm richm commented Jan 19, 2026

Feature:
Add the ability to configure TLS/HTTPS for the Grafana graphing service
using the following new role variables:

  • metrics_grafana_certificates - use the certificate role to generate certs
  • metrics_grafana_cert/metrics_grafana_private_key - paths to existing certs
  • metrics_grafana_cert_src/metrics_grafana_private_key_src - copy local files

Reason:
Users need the ability to secure Grafana connections with TLS/HTTPS to
protect metrics data in transit, which is a common security requirement
for production deployments.

Result:
The metrics role can now configure Grafana to use HTTPS by either:

  1. Generating certificates via the certificate system role
  2. Using existing certificate files on the target system
  3. Copying certificate files from the control node

All tests updated to verify HTTPS functionality, and a new test added
to verify certificate role integration.

In addition - the tests were written incorrectly to run the handlers.
In order to refresh the services, the handlers must be run immediately
after running the role, so that the checks and verify tasks are testing
the actual result of running the role. This fixes several test flakes
that are caused when the services were not refreshed when doing the
verification.

Signed-off-by: Rich Megginson rmeggins@redhat.com

Summary by Sourcery

Add TLS certificate support for the Grafana metrics graphing service and stabilize service-dependent tests by flushing handlers before verification.

New Features:

  • Allow configuring Grafana to use HTTPS via either generated certificates, existing cert/key paths, or copied cert/key files.
  • Integrate optional use of the certificate system role to provision Grafana server certificates and keys.

Enhancements:

  • Introduce role variables and defaults for managing Grafana TLS certificate and key locations.
  • Add internal variables for standard certificate and private key directories used by Grafana.

Documentation:

  • Document new Grafana TLS-related variables, including usage examples and guidance on using the certificate role and self-signed certificates.

Tests:

  • Extend Grafana tests to cover HTTPS access and certificate-role integration, including certificate creation and cleanup.
  • Update existing tests to flush handlers immediately after running the role so that service state is refreshed before verification, reducing test flakiness.

@richm richm requested a review from natoscott as a code owner January 19, 2026 18:53
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Jan 19, 2026

Reviewer's Guide

Adds configurable TLS/HTTPS support for the Grafana metrics graphing service via new role variables and certificate role integration, and fixes test flakiness by flushing handlers before verification while extending tests to cover HTTPS and certificate workflows.

Sequence diagram for configuring Grafana HTTPS with certificate role

sequenceDiagram
    actor Admin
    participant AnsibleController
    participant MetricsRole
    participant CertificateRole
    participant Filesystem
    participant GrafanaRole
    participant GrafanaService

    Admin->>AnsibleController: Run playbook with metrics_graph_service true
    Admin->>AnsibleController: Set metrics_grafana_certificates

    AnsibleController->>MetricsRole: Include linux_system_roles.metrics

    MetricsRole->>MetricsRole: Compute grafana_cert and grafana_private_key

    alt metrics_grafana_certificates not empty and os_family RedHat
        MetricsRole->>MetricsRole: Validate distribution_version and ca
        MetricsRole-->>Admin: Fail if distribution_version 7 and ca self_sign
        MetricsRole->>CertificateRole: Include fedora.linux_system_roles.certificate
        CertificateRole->>Filesystem: Create key and certificate
        CertificateRole-->>MetricsRole: certificate_requests completed
    else metrics_grafana_certificates empty
        MetricsRole-->>MetricsRole: Skip certificate_role
    end

    MetricsRole->>MetricsRole: Optionally copy cert and key from src paths
    MetricsRole->>Filesystem: Copy grafana_cert_src to grafana_cert
    MetricsRole->>Filesystem: Copy grafana_private_key_src to grafana_private_key

    MetricsRole->>GrafanaRole: Include grafana role with grafana_metrics_provider
    GrafanaRole->>GrafanaService: Configure and restart with TLS cert and key
    GrafanaService-->>Admin: HTTPS endpoint available
Loading

Sequence diagram for fixing tests to flush handlers before verification

sequenceDiagram
    actor Tester
    participant AnsibleController
    participant MetricsRole
    participant Handlers
    participant VerifyTasks
    participant Services

    Tester->>AnsibleController: Run metrics role tests
    AnsibleController->>MetricsRole: Apply linux_system_roles.metrics
    MetricsRole->>Handlers: Notify service handlers

    AnsibleController->>Handlers: meta flush_handlers
    Handlers->>Services: Restart or reload services
    Services-->>Handlers: Services refreshed

    AnsibleController->>VerifyTasks: Run verification tasks
    VerifyTasks->>Services: Check metrics and HTTPS endpoints
    Services-->>VerifyTasks: Return actual post_handler state
    VerifyTasks-->>Tester: Deterministic test results (no flakes)
Loading

Class diagram for metrics role variables and related roles for Grafana TLS

classDiagram
    class MetricsRole {
      +bool metrics_graph_service
      +string metrics_provider
      +list~dict~ metrics_grafana_certificates
      +string metrics_grafana_cert
      +string metrics_grafana_private_key
      +string metrics_grafana_cert_src
      +string metrics_grafana_private_key_src
      +string __metrics_grafana_cert_dir
      +string __metrics_grafana_private_key_dir
      +void manage_graphing_service()
    }

    class CertificateRole {
      +list~dict~ certificate_requests
      +void create_certificates()
    }

    class GrafanaRole {
      +string grafana_metrics_provider
      +string grafana_cert
      +string grafana_private_key
      +void configure_grafana()
    }

    class Filesystem {
      +string cert_dir
      +string private_key_dir
      +void write_cert()
      +void write_key()
    }

    MetricsRole --> CertificateRole : uses
    MetricsRole --> GrafanaRole : includes
    MetricsRole --> Filesystem : copies_cert_and_key
    CertificateRole --> Filesystem : generates_files
    GrafanaRole --> Filesystem : reads_cert_and_key
Loading

File-Level Changes

Change Details Files
Introduce configurable TLS certificate/key handling for Grafana in the metrics role.
  • Add new role defaults for Grafana certificate and key configuration, including integration with the certificate role and support for existing or copied cert files.
  • Compute effective grafana_cert and grafana_private_key paths based on metrics_grafana_certificates, explicit paths, or source files with sane defaults.
  • Wrap Grafana setup in a block that optionally invokes the certificate role on Red Hat-family systems, including a guard against self-signed certificates on RHEL/CentOS 7, and copies cert/key files into place before including the Grafana role.
defaults/main.yml
tasks/main.yml
vars/main.yml
Document Grafana TLS configuration options and usage patterns.
  • Add README section describing metrics_grafana_certificates and its interaction with the certificate role, including constraints when also specifying direct cert/key variables.
  • Document metrics_grafana_cert, metrics_grafana_cert_src, metrics_grafana_private_key, and metrics_grafana_private_key_src with examples and path semantics.
README.md
Update tests to validate Grafana over HTTPS, exercise certificate role integration, and ensure handlers are flushed before verification to avoid flakes.
  • Modify Grafana URI checks to support configurable protocol and disable certificate validation for test HTTPS access.
  • Extend existing graph verification test to generate a cert/key, configure the role to use them over HTTPS, and clean up tracked certificates and files afterward.
  • Add a new test that drives Grafana TLS via metrics_grafana_certificates using the certificate role, including environment gating and cleanup.
  • Reorder or add meta: flush_handlers steps across multiple tests so services are refreshed before verification tasks, and adjust restore_services_state and cleanup tagging.
tests/check_grafana.yml
tests/tests_verify_graph.yml
tests/tests_verify_graph_use_cert_role.yml
tests/tests_verify_auth.yml
tests/tests_bz1855539.yml
tests/tests_bz1855544.yml
tests/tests_verify_basic.yml
tests/tests_verify_bpftrace.yml
tests/tests_verify_from_elasticsearch.yml
tests/tests_verify_from_spark.yml
tests/tests_verify_fullstack.yml
tests/tests_verify_into_elasticsearch.yml
tests/tests_verify_into_spark.yml
tests/tests_verify_mssql.yml
tests/tests_verify_notification.yml
tests/tests_verify_pmie_webhook.yml
tests/tests_verify_postfix.yml
tests/tests_verify_query.yml
tests/tests_verify_retention.yml
tests/restore_services_state.yml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 3 issues, and left some high level feedback:

  • In tasks/main.yml the copy tasks use grafana_cert_src/grafana_private_key_src as src, but those variables are never defined (the user-facing vars are metrics_grafana_cert_src/metrics_grafana_private_key_src), so the copy will fail or not behave as intended; consider wiring the copy tasks directly to the metrics_* variables or defining grafana_*_src in the vars block.
  • The Jinja expressions that derive grafana_cert and grafana_private_key combine multiple conditions and fallbacks in a single line, which is hard to read and reason about; consider breaking this into a few simpler set_fact steps or using ternary/default to make the precedence between the three configuration modes more explicit.
  • Since metrics_grafana_certificates is intended to be mutually exclusive with metrics_grafana_cert/metrics_grafana_private_key and their *_src variants, it would be helpful to add an explicit assert/fail early in the role when conflicting variables are set, instead of silently ignoring the latter.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In tasks/main.yml the copy tasks use `grafana_cert_src`/`grafana_private_key_src` as `src`, but those variables are never defined (the user-facing vars are `metrics_grafana_cert_src`/`metrics_grafana_private_key_src`), so the copy will fail or not behave as intended; consider wiring the copy tasks directly to the metrics_* variables or defining `grafana_*_src` in the vars block.
- The Jinja expressions that derive `grafana_cert` and `grafana_private_key` combine multiple conditions and fallbacks in a single line, which is hard to read and reason about; consider breaking this into a few simpler `set_fact` steps or using `ternary`/`default` to make the precedence between the three configuration modes more explicit.
- Since `metrics_grafana_certificates` is intended to be mutually exclusive with `metrics_grafana_cert`/`metrics_grafana_private_key` and their *_src variants, it would be helpful to add an explicit `assert`/`fail` early in the role when conflicting variables are set, instead of silently ignoring the latter.

## Individual Comments

### Comment 1
<location> `tasks/main.yml:179-181` </location>
<code_context>
+          vars:
+            certificate_requests: "{{ metrics_grafana_certificates }}"
+
+    - name: Copy grafana cert
+      copy:
+        src: "{{ grafana_cert_src }}"
+        dest: "{{ grafana_cert }}"
+        mode: "0644"
</code_context>

<issue_to_address>
**issue (bug_risk):** `grafana_cert_src` and `grafana_private_key_src` are used but never defined as variables.

The defaults only define `metrics_grafana_cert_src` / `metrics_grafana_private_key_src`, and the `vars:` block defines only the destination paths (`grafana_cert`, `grafana_private_key`). Using the current `src` values will cause an undefined variable error at runtime. Consider switching to:

```yaml
actions:
  - name: Copy grafana cert
    copy:
      src: "{{ metrics_grafana_cert_src }}"
      dest: "{{ grafana_cert }}"
```

(and similarly for the private key).
</issue_to_address>

### Comment 2
<location> `README.md:192-193` </location>
<code_context>
+
+For generating a new certificate for grafana it is recommended to set the
+`metrics_grafana_certificates` variable.  If you have your own certs/keys, or
+will create them from your own CA provider, see below `metrics_grafana_cert` et.
+al. for information about how to pass in and/or use your own certs.
+
+The value of `metrics_grafana_certificates` is passed on to the
</code_context>

<issue_to_address>
**issue (typo):** Use the correct form "et al." instead of "et."

Use "et al." (with a single period at the end), e.g. `metrics_grafana_cert et al.`

```suggestion
will create them from your own CA provider, see below `metrics_grafana_cert` et al. for information about how to pass in and/or use your own certs.
```
</issue_to_address>

### Comment 3
<location> `README.md:226` </location>
<code_context>
+`ca: self-sign` or `ca: local`, depending on your certmonger usage, see the
+[linux-system-roles.certificate documentation](https://github.com/linux-system-roles/certificate/#cas-and-providers) for details.
+
+NOTE: This creating a self-signed certificate is not supported on RHEL/CentOS-7.
+
+### metrics_grafana_cert: ''
</code_context>

<issue_to_address>
**issue (typo):** Fix the ungrammatical phrase "This creating" in the NOTE sentence

For example: "NOTE: Creating a self-signed certificate is not supported on RHEL/CentOS-7."

```suggestion
NOTE: Creating a self-signed certificate is not supported on RHEL/CentOS-7.
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@richm
Copy link
Copy Markdown
Collaborator Author

richm commented Jan 19, 2026

[citest]

@richm richm force-pushed the feat-grafana-cert-key branch from 33c6bde to a150999 Compare January 19, 2026 19:00
@richm
Copy link
Copy Markdown
Collaborator Author

richm commented Jan 19, 2026

[citest]

@richm richm requested a review from spetrosi January 19, 2026 19:27
@natoscott natoscott requested review from kurik and sfeifer January 19, 2026 20:50
@richm
Copy link
Copy Markdown
Collaborator Author

richm commented Jan 20, 2026

[citest]

Feature:
Add the ability to configure TLS/HTTPS for the Grafana graphing service
using the following new role variables:

* metrics_grafana_certificates - use the certificate role to generate certs
* metrics_grafana_cert/metrics_grafana_private_key - paths to existing certs
* metrics_grafana_cert_src/metrics_grafana_private_key_src - copy local files

Reason:
Users need the ability to secure Grafana connections with TLS/HTTPS to
protect metrics data in transit, which is a common security requirement
for production deployments.

Result:
The metrics role can now configure Grafana to use HTTPS by either:

1. Generating certificates via the certificate system role
2. Using existing certificate files on the target system
3. Copying certificate files from the control node

All tests updated to verify HTTPS functionality, and a new test added
to verify certificate role integration.

In addition - the tests were written incorrectly to run the handlers.
In order to refresh the services, the handlers must be run immediately
after running the role, so that the checks and verify tasks are testing
the actual result of running the role.  This fixes several test flakes
that are caused when the services were not refreshed when doing the
verification.

Signed-off-by: Rich Megginson <rmeggins@redhat.com>
@richm richm force-pushed the feat-grafana-cert-key branch from a150999 to 829a5e2 Compare January 20, 2026 15:44
@richm
Copy link
Copy Markdown
Collaborator Author

richm commented Jan 20, 2026

fedora-42 failure is selinux - needs policy update

@richm
Copy link
Copy Markdown
Collaborator Author

richm commented Jan 20, 2026

[citest]

@richm richm merged commit ae4b043 into linux-system-roles:main Jan 20, 2026
28 of 29 checks passed
@richm richm deleted the feat-grafana-cert-key branch January 20, 2026 17:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant