Skip to content

Commit 2ffb851

Browse files
feat(grafana): add variable for JWT TLS key and issue cert via role
1 parent 92dad08 commit 2ffb851

4 files changed

Lines changed: 33 additions & 40 deletions

File tree

roles/grafana/README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ grafana__root_url: 'https://monitoring.example.com/grafana'
4848
| `grafana__auth_anonymous_org_name` | The organization name that should be used for unauthenticated users. | `'Main Org.'` |
4949
| `grafana__auth_anonymous_org_role` | The role for unauthenticated users. | `'Viewer'` |
5050
| `grafana__auth_jwt` | Enable JWT-based authentication for Grafana requests. | `false` |
51-
| `grafana__auth_jwt_key_file` | Path to the public key file used to verify JWT signatures for Grafana authentication. | `/etc/grafana/icinga.pem` |
51+
| `grafana__auth_jwt__priv_key_file` | Path to the private key file used to verify JWT signatures for Grafana authentication. | `'/etc/grafana/jwt.key.priv'` |
52+
| `grafana__auth_jwt__pub_key_file` | Path to the public key file used to verify JWT signatures for Grafana authentication. | `'/etc/grafana/jwt.key.pub'` |
5253
| `grafana__bitwarden_collection_id` | Will be used to store the token of the created service accounts to this Bitwarden Collection. Can be obtained from the URL in Bitwarden WebGUI. | `'{{ lfops__bitwarden_collection_id | default() }}'` |
5354
| `grafana__bitwarden_organization_id` | Will be used to store the token of the created service accounts to this Bitwarden Organization. Can be obtained from the URL in Bitwarden WebGUI. | `'{{ lfops__bitwarden_organization_id | default() }}'` |
5455
| `grafana__cookie_samesite` | The [SameSite cookie attribute](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite). Possible options:<br> * disabled<br> * lax<br> * none<br> * strict | `'lax'` |
@@ -74,7 +75,8 @@ grafana__auth_anonymous_enabled: false
7475
grafana__auth_anonymous_org_name: 'Main Org.'
7576
grafana__auth_anonymous_org_role: 'Viewer'
7677
grafana__auth_jwt: false
77-
grafana__auth_jwt_key_file: '/etc/grafana/icinga.pem'
78+
grafana__auth_jwt__priv_key_file: '/etc/grafana/jwt.key.priv'
79+
grafana__auth_jwt__pub_key_file: '/etc/grafana/jwt.key.pub'
7880
grafana__cookie_samesite: 'lax'
7981
grafana__https_config:
8082
cert_file: '/etc/ssl/ssl-certificate.crt'

roles/grafana/defaults/main.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
grafana__allow_embedding: true
22
grafana__api_url: '{{ grafana__root_url }}'
3+
grafana__auth_jwt: false
4+
grafana__auth_jwt__priv_key_file: '/etc/grafana/jwt.key.priv'
5+
grafana__auth_jwt__pub_key_file: '/etc/grafana/jwt.key.pub'
36
grafana__auth_anonymous_enabled: false
47
grafana__auth_anonymous_org_name: 'Main Org.'
58
grafana__auth_anonymous_org_role: 'Viewer'
69
grafana__bitwarden_collection_id: '{{ lfops__bitwarden_collection_id | default() }}'
710
grafana__bitwarden_organization_id: '{{ lfops__bitwarden_organization_id | default() }}'
811
grafana__cookie_samesite: 'lax'
9-
grafana__auth_jwt: false
10-
grafana__auth_jwt_key_file: '/etc/grafana/icinga.pem'
1112
grafana__plugins__dependent_var: []
1213
grafana__plugins__group_var: []
1314
grafana__plugins__host_var: []

roles/grafana/tasks/main.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,23 @@
2626
when:
2727
- 'grafana__https_config is defined and grafana__https_config | length > 0'
2828

29+
- name: 'generate JWT RSA private key'
30+
community.crypto.openssl_privatekey:
31+
path: '{{ grafana__auth_jwt__priv_key_file }}'
32+
size: 2048
33+
type: 'RSA'
34+
owner: 'apache'
35+
group: 'icingaweb2'
36+
mode: 0o644
37+
38+
- name: 'generate JWT RSA public key'
39+
community.crypto.openssl_publickey:
40+
path: '{{ grafana__auth_jwt__pub_key_file }}'
41+
privatekey_path: '{{ grafana__auth_jwt__priv_key_file }}'
42+
owner: 'apache'
43+
group: 'icingaweb2'
44+
mode: 0o644
45+
2946
- name: 'deploy /etc/grafana/grafana.ini'
3047
ansible.builtin.template:
3148
src: 'etc/grafana/grafana.ini.j2'

roles/grafana/templates/etc/grafana/grafana.ini.j2

Lines changed: 9 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# {{ ansible_managed }}
2-
# 2026032301
2+
# 2026032701
33

44
##################### Grafana Configuration Example #####################
55
#
@@ -606,16 +606,18 @@ hide_version = true
606606

607607
#################################### Auth JWT ##########################
608608
[auth.jwt]
609-
;enabled = true
610-
;header_name = X-JWT-Assertion
611-
;email_claim = sub
612-
;username_claim = sub
609+
enabled = {{ grafana__auth_jwt | lower }}
610+
header_name = X-JWT-Assertion
611+
email_claim = sub
612+
username_claim = sub
613613
;jwk_set_url = https://foo.bar/.well-known/jwks.json
614614
;jwk_set_file = /path/to/jwks.json
615615
;cache_ttl = 60m
616616
;expected_claims = {"aud": ["foo", "bar"]}
617-
;key_file = /path/to/key/file
618-
;auto_sign_up = false
617+
key_file = {{ grafana__auth_jwt__pub_key_file }}
618+
auto_sign_up = false
619+
url_login = true
620+
skip_org_role_sync = true
619621

620622
#################################### Auth LDAP ##########################
621623
[auth.ldap]
@@ -1217,32 +1219,3 @@ interval_year = YYYY
12171219

12181220
# Enable or disable loading other base map layers
12191221
;enable_custom_baselayers = true
1220-
1221-
{% if grafana__auth_jwt %}
1222-
[auth.jwt]
1223-
# By default, auth.jwt is disabled.
1224-
enabled = true
1225-
1226-
# HTTP header to look into to get a JWT token.
1227-
header_name = X-JWT-Assertion
1228-
1229-
# Specify a claim to use as a username to sign in.
1230-
username_claim = sub
1231-
1232-
# Specify a claim to use as an email to sign in.
1233-
email_claim = sub
1234-
1235-
# enable JWT authentication in the URL
1236-
url_login = true
1237-
1238-
# PEM-encoded key file in PKIX, PKCS #1, PKCS #8 or SEC 1 format.
1239-
key_file = {{ grafana__auth_jwt_key_file }}
1240-
1241-
# This can be seen as a required "subset" of a JWT Claims Set.
1242-
# expect_claims = {"iss": "https://icinga.yourdomain"}
1243-
1244-
# role_attribute_path = contains(roles[*], 'admin') && 'Admin' || contains(roles[*], 'editor') && 'Editor' || 'Viewer'
1245-
1246-
# To skip the assignment of roles and permissions upon login via JWT and handle them via other mechanisms like the user interface, we can skip the organization role synchronization with the following configuration.
1247-
skip_org_role_sync = true
1248-
{% endif %}

0 commit comments

Comments
 (0)