Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions operations/helm/charts/alloy/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ internal API changes are not present.
Unreleased
----------

### Enhancements

- Add support for mounting configuration from Kubernetes Secrets via `alloy.secret` values. (@claude-code)

### Bug fixes

- Correct `extraEnv` indentation in container template (@orkhan-huseyn)
Expand Down
19 changes: 19 additions & 0 deletions operations/helm/charts/alloy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ useful if just using the default DaemonSet isn't sufficient.
| alloy.configMap.create | bool | `true` | Create a new ConfigMap for the config file. |
| alloy.configMap.key | string | `nil` | Key in ConfigMap to get config from. |
| alloy.configMap.name | string | `nil` | Name of existing ConfigMap to use. Used when create is false. |
| alloy.secret.content | string | `""` | Content to assign to the new Secret. This is passed into `tpl` allowing for templating from values. |
| alloy.secret.create | bool | `false` | Create a new Secret for the config file. Takes precedence over configMap if both are configured. |
| alloy.secret.key | string | `nil` | Key in Secret to get config from. |
| alloy.secret.name | string | `nil` | Name of existing Secret to use. Used when create is false. |
| alloy.enableHttpServerPort | bool | `true` | Enables Grafana Alloy container's http server port. |
| alloy.enableReporting | bool | `true` | Enables sending Grafana Labs anonymous usage stats to help improve Grafana Alloy. |
| alloy.envFrom | list | `[]` | Maps all the keys on a ConfigMap or Secret as environment variables. https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#envfromsource-v1-core |
Expand Down Expand Up @@ -254,6 +258,21 @@ used. When provided, `alloy.configMap.content` must hold a valid Alloy configura

[default-config]: ./config/example.alloy

### alloy.secret

You can use `alloy.secret` to mount configuration from a Kubernetes Secret instead of a ConfigMap.
This provides better security for configurations containing sensitive credentials.

When `alloy.secret.create` is set to `true` or `alloy.secret.name` is specified, the Secret takes
precedence over the ConfigMap configuration. The ConfigMap will not be created in this case.

`alloy.secret.content` holds the Grafana Alloy configuration to store in the Secret.
When provided, it must hold a valid Alloy configuration file and is passed through `tpl` for templating.

You can reference an existing Secret by setting `alloy.secret.create` to `false` and specifying
the Secret name in `alloy.secret.name`. Optionally set `alloy.secret.key` if the configuration
is stored under a different key than the default `config.alloy`.

### alloy.securityContext

`alloy.securityContext` sets the securityContext passed to the Grafana
Expand Down
15 changes: 15 additions & 0 deletions operations/helm/charts/alloy/README.md.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,21 @@ used. When provided, `alloy.configMap.content` must hold a valid Alloy configura

[default-config]: ./config/example.alloy

### alloy.secret

You can use `alloy.secret` to mount configuration from a Kubernetes Secret instead of a ConfigMap.
This provides better security for configurations containing sensitive credentials.

When `alloy.secret.create` is set to `true` or `alloy.secret.name` is specified, the Secret takes
precedence over the ConfigMap configuration. The ConfigMap will not be created in this case.

`alloy.secret.content` holds the Grafana Alloy configuration to store in the Secret.
When provided, it must hold a valid Alloy configuration file and is passed through `tpl` for templating.

You can reference an existing Secret by setting `alloy.secret.create` to `false` and specifying
the Secret name in `alloy.secret.name`. Optionally set `alloy.secret.key` if the configuration
is stored under a different key than the default `config.alloy`.

### alloy.securityContext

`alloy.securityContext` sets the securityContext passed to the Grafana
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
alloy:
secret:
create: true
content: |
logging {
level = "info"
format = "logfmt"
}

discovery.kubernetes "pods" {
role = "pod"
}

discovery.relabel "pods" {
targets = discovery.kubernetes.pods.targets

rule {
action = "labelmap"
regex = "__meta_kubernetes_pod_label_(.+)"
replacement = "k8s_pod_label_$1"
}
}

prometheus.scrape "pods" {
targets = discovery.relabel.pods.output
forward_to = [prometheus.remote_write.default.receiver]
}

prometheus.remote_write "default" {
endpoint {
url = "https://prometheus.example.com/api/v1/write"
basic_auth {
username = "my-username"
password = "my-secret-password"
}
}
}
5 changes: 5 additions & 0 deletions operations/helm/charts/alloy/ci/existing-secret-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
alloy:
secret:
create: false
name: existing-secret
key: my-config.alloy
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Test case for empty RBAC rules arrays
rbac:
create: true
rules: []
clusterRules: []
60 changes: 60 additions & 0 deletions operations/helm/charts/alloy/templates/_config.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,63 @@ ConfigMap.
config.alloy
{{- end }}
{{- end }}

{{/*
Retrieve Secret name from the name of the chart or the Secret the user
specified.
*/}}
{{- define "alloy.secret.name" -}}
{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}}
{{- if $values.secret.name -}}
{{- $values.secret.name }}
{{- else -}}
{{- include "alloy.fullname" . }}
{{- end }}
{{- end }}

{{/*
The name of the config file is the default or the key the user specified in the
Secret.
*/}}
{{- define "alloy.secret.key" -}}
{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}}
{{- if $values.secret.key -}}
{{- $values.secret.key }}
{{- else -}}
config.alloy
{{- end }}
{{- end }}

{{/*
Determine if using Secret for config (Secret takes precedence over ConfigMap).
*/}}
{{- define "alloy.config-source.use-secret" -}}
{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}}
{{- if or $values.secret.create $values.secret.name -}}
true
{{- else -}}
false
{{- end }}
{{- end }}

{{/*
Get the config source name (Secret or ConfigMap).
*/}}
{{- define "alloy.config-source.name" -}}
{{- if eq (include "alloy.config-source.use-secret" .) "true" -}}
{{- include "alloy.secret.name" . }}
{{- else -}}
{{- include "alloy.config-map.name" . }}
{{- end }}
{{- end }}

{{/*
Get the config source key (Secret or ConfigMap).
*/}}
{{- define "alloy.config-source.key" -}}
{{- if eq (include "alloy.config-source.use-secret" .) "true" -}}
{{- include "alloy.secret.key" . }}
{{- else -}}
{{- include "alloy.config-map.key" . }}
{{- end }}
{{- end }}
2 changes: 1 addition & 1 deletion operations/helm/charts/alloy/templates/configmap.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}}
{{- if $values.configMap.create }}
{{- if and $values.configMap.create (not (or $values.secret.create $values.secret.name)) }}
apiVersion: v1
kind: ConfigMap
metadata:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
imagePullPolicy: {{ .Values.image.pullPolicy }}
args:
- run
- /etc/alloy/{{ include "alloy.config-map.key" . }}
- /etc/alloy/{{ include "alloy.config-source.key" . }}
- --storage.path={{ $values.storagePath }}
- --server.http.listen-addr={{ $values.listenAddr }}:{{ $values.listenPort }}
- --server.http.ui-path-prefix={{ $values.uiPathPrefix }}
Expand Down
11 changes: 10 additions & 1 deletion operations/helm/charts/alloy/templates/controllers/_pod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
metadata:
annotations:
kubectl.kubernetes.io/default-container: alloy
{{- if and (not .Values.configReloader.enabled) $values.configMap.create $values.configMap.content }}
{{- if not .Values.configReloader.enabled }}
{{- if and $values.secret.create $values.secret.content }}
checksum/config: {{ (tpl $values.secret.content .) | sha256sum | trunc 63 }}
{{- else if and $values.configMap.create $values.configMap.content }}
checksum/config: {{ (tpl $values.configMap.content .) | sha256sum | trunc 63 }}
{{- end }}
{{- end }}
{{- with .Values.controller.podAnnotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
Expand Down Expand Up @@ -71,8 +75,13 @@ spec:
{{- end }}
volumes:
- name: config
{{- if eq (include "alloy.config-source.use-secret" .) "true" }}
secret:
secretName: {{ include "alloy.secret.name" . }}
{{- else }}
configMap:
name: {{ include "alloy.config-map.name" . }}
{{- end }}
{{- if $values.mounts.varlog }}
- name: varlog
hostPath:
Expand Down
8 changes: 8 additions & 0 deletions operations/helm/charts/alloy/templates/rbac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ metadata:
{{- include "alloy.labels" $ | nindent 4 }}
app.kubernetes.io/component: rbac
rules:
{{- if $.Values.rbac.rules }}
{{- $.Values.rbac.rules | toYaml | nindent 2 }}
{{- else }}
[]
{{- end }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
Expand Down Expand Up @@ -40,8 +44,12 @@ metadata:
{{- include "alloy.labels" . | nindent 4 }}
app.kubernetes.io/component: rbac
rules:
{{- if or .Values.rbac.rules .Values.rbac.clusterRules }}
{{- .Values.rbac.rules | toYaml | nindent 2 }}
{{- .Values.rbac.clusterRules | toYaml | nindent 2 }}
{{- else }}
[]
{{- end }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
Expand Down
18 changes: 18 additions & 0 deletions operations/helm/charts/alloy/templates/secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}}
{{- if $values.secret.create }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "alloy.secret.name" . }}
namespace: {{ include "alloy.namespace" . }}
labels:
{{- include "alloy.labels" . | nindent 4 }}
app.kubernetes.io/component: config
type: Opaque
stringData:
{{- if $values.secret.content }}
{{ include "alloy.secret.key" . }}: |- {{- (tpl $values.secret.content .) | nindent 4 }}
{{- else }}
{{ include "alloy.secret.key" . }}: |- {{- .Files.Get "config/example.alloy" | trim | nindent 4 }}
{{- end }}
{{- end }}
11 changes: 11 additions & 0 deletions operations/helm/charts/alloy/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ alloy:
# -- Key in ConfigMap to get config from.
key: null

secret:
# -- Create a new Secret for the config file. Takes precedence over configMap if both are configured.
create: false
# -- Content to assign to the new Secret. This is passed into `tpl` allowing for templating from values.
content: ''

# -- Name of existing Secret to use. Used when create is false.
name: null
# -- Key in Secret to get config from.
key: null

clustering:
# -- Deploy Alloy in a cluster to allow for load distribution.
enabled: false
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
# Source: alloy/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: alloy
namespace: default
labels:
helm.sh/chart: alloy
app.kubernetes.io/name: alloy
app.kubernetes.io/instance: alloy
app.kubernetes.io/version: "vX.Y.Z"
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: config
data:
config.alloy: |-
logging {
level = "info"
format = "logfmt"
}

discovery.kubernetes "pods" {
role = "pod"
}

discovery.kubernetes "nodes" {
role = "node"
}

discovery.kubernetes "services" {
role = "service"
}

discovery.kubernetes "endpoints" {
role = "endpoints"
}

discovery.kubernetes "endpointslices" {
role = "endpointslice"
}

discovery.kubernetes "ingresses" {
role = "ingress"
}
Loading