diff --git a/examples/grafana_keycloak_sso/README.md b/examples/grafana_keycloak_sso/README.md new file mode 100644 index 000000000..982d8dbea --- /dev/null +++ b/examples/grafana_keycloak_sso/README.md @@ -0,0 +1,91 @@ +--- +title: "Grafana deployment with Keycloak OAuth2 SSO configuration" +linkTitle: "Grafana deployment with Keycloak OAuth2 SSO configuration" +--- + +A basic example of a Grafana Deployment that overrides generic oauth configuration, it's important to note that most configuration that is valid in the `grafana` container can be done with grafana-operator. + +## Steps + +### Create Keycloak Client for Grafana + +Follow official Grafana guide in how to create a Keycloak client and role mappers for Grafana [here](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/keycloak/#keycloak-configuration). + +### Create a Kubernetes Secret + +In order to safely store the client-id and client-secret for the Keycloak client you have created in the first step, we recommend you creating a Kubernetes secrets to store the client-id and client-secret that Keycloak will use. + +The grafana-operator is agnostic to any secret management solution you might use to get this secret (Vault, external-secrets, vanilla K8s secrets, etc). + +```yaml +apiVersion: v1 +data: + client-id: c29tZXJlYWxseWxvbmdzZWNyZXRqdXN0dG9jb3ZlcnN0dWZmCg== + client-secret: c29tZXJlYWxseWxvbmdzZWNyZXRqdXN0dG9jb3ZlcnN0dWZmCg== +kind: Secret +metadata: + name: grafana-oauth +type: Opaque +``` + +### Creating our Grafana Instance + +Create a Grafana instance overriding the configuration for `auth.generic_oauth:`. + +```yaml +apiVersion: grafana.integreatly.org/v1beta1 +kind: Grafana +metadata: + name: grafana + labels: + dashboards: "grafana" +spec: + config: + log: + mode: "console" + auth: + disable_login_form: "false" + auth.generic_oauth: + # For variables see https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#env-provider + enabled: "true" + name: "Keycloak SSO" + allow_sign_up: "true" + client_id: ${AUTH_CLIENT_ID} + client_secret: ${AUTH_CLIENT_SECRET} + scopes: "openid email profile offline_access roles" + email_attribute_path: email + login_attribute_path: username + name_attribute_path: full_name + groups_attribute_path: groups + auth_url: "https:///realms//protocol/openid-connect/auth" + token_url: "https:///realms//protocol/openid-connect/token" + api_url: "https:///realms//protocol/openid-connect/userinfo" + role_attribute_path: "contains(roles[*], 'admin') && 'Admin' || contains(roles[*], 'editor') && 'Editor' || 'Viewer'" +... +``` +Now, we need to set `secretKeyRef` to the Grafana container to pass the values inside the secret you have created in the previous step as environment variables. Please make sure to point to the right secret name and key. + +```yaml +... + deployment: + spec: + template: + spec: + containers: + - name: grafana + env: + - name: AUTH_CLIENT_ID + valueFrom: + secretKeyRef: + name: grafana-oauth + key: client-id + - name: AUTH_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: grafana-oauth + key: client-secret +... +``` +Full configuration is below. + +{{< readfile file="resources.yaml" code="true" lang="yaml" >}} diff --git a/examples/grafana_keycloak_sso/resources.yaml b/examples/grafana_keycloak_sso/resources.yaml new file mode 100644 index 000000000..09c6b3266 --- /dev/null +++ b/examples/grafana_keycloak_sso/resources.yaml @@ -0,0 +1,81 @@ +apiVersion: v1 +data: + client-id: c29tZXJlYWxseWxvbmdzZWNyZXRqdXN0dG9jb3ZlcnN0dWZmCg== + client-secret: c29tZXJlYWxseWxvbmdzZWNyZXRqdXN0dG9jb3ZlcnN0dWZmCg== +kind: Secret +metadata: + name: grafana-oauth + namespace: monitoring +type: Opaque +--- +apiVersion: grafana.integreatly.org/v1beta1 +kind: Grafana +metadata: + name: grafana + labels: + dashboards: "grafana" +spec: + config: + log: + mode: "console" + auth: + disable_login_form: "false" + auth.generic_oauth: + # For variables see https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#env-provider + enabled: "true" + name: "Keycloak SSO" + allow_sign_up: "true" + client_id: ${AUTH_CLIENT_ID} + client_secret: ${AUTH_CLIENT_SECRET} + scopes: "openid email profile offline_access roles" + email_attribute_path: email + login_attribute_path: username + name_attribute_path: full_name + groups_attribute_path: groups + auth_url: "https:///realms//protocol/openid-connect/auth" + token_url: "https:///realms//protocol/openid-connect/token" + api_url: "https:///realms//protocol/openid-connect/userinfo" + role_attribute_path: "contains(roles[*], 'admin') && 'Admin' || contains(roles[*], 'editor') && 'Editor' || 'Viewer'" + server: + root_url: https://grafana.your-domain.com + deployment: + spec: + template: + spec: + containers: + - name: grafana + env: + - name: AUTH_CLIENT_ID + valueFrom: + secretKeyRef: + name: grafana-oauth + key: client-id + - name: AUTH_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: grafana-oauth + key: client-secret + image: grafana/grafana:10.0.3 + ingress: + metadata: + annotations: + kubernetes.io/ingress.class: nginx + external-dns.alpha.kubernetes.io/hostname: grafana.your-domain.com + cert-manager.io/cluster-issuer: letsencrypt-prod + spec: + ingressClassName: nginx + rules: + - host: grafana.your-domain.com + http: + paths: + - backend: + service: + name: grafana-service + port: + number: 3000 + path: / + pathType: Prefix + tls: + - hosts: + - grafana.your-domain.com + secretName: grafana-tls-secret diff --git a/examples/persistent_volume/README.md b/examples/persistent_volume/README.md new file mode 100644 index 000000000..d292d7c43 --- /dev/null +++ b/examples/persistent_volume/README.md @@ -0,0 +1,8 @@ +--- +title: "Grafana deployment with a Persistent Volume" +linkTitle: "Grafana deployment with a Persistent Volume" +--- + +A basic deployment of Grafana with a persistent volume attached using existing Storage Class. + +{{< readfile file="resources.yaml" code="true" lang="yaml" >}} diff --git a/examples/persistent_volume/resources.yaml b/examples/persistent_volume/resources.yaml new file mode 100644 index 000000000..177845fa2 --- /dev/null +++ b/examples/persistent_volume/resources.yaml @@ -0,0 +1,40 @@ +--- +apiVersion: grafana.integreatly.org/v1beta1 +kind: Grafana +metadata: + name: grafana + labels: + dashboards: "grafana" +spec: + persistentVolumeClaim: + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageClassName: + config: + log: + mode: "console" + auth: + disable_login_form: "false" + security: + admin_user: root + admin_password: secret + deployment: + spec: + template: + spec: + containers: + - name: grafana + image: grafana/grafana:9.4.3 + securityContext: + allowPrivilegeEscalation: true + readOnlyRootFilesystem: false + readinessProbe: + failureThreshold: 3 + volumes: + - name: grafana-data + persistentVolumeClaim: + claimName: grafana-pvc