Metricbeat supports templates for modules:

["source","yaml",subs="attributes"]
-------------------------------------------------------------------------------------
metricbeat.autodiscover:
  providers:
    - type: kubernetes
      include_annotations: ["prometheus.io.scrape"]
      templates:
        - condition:
            contains:
              kubernetes.annotations.prometheus.io/scrape: "true"
          config:
            - module: prometheus
              metricsets: ["collector"]
              hosts: "${data.host}:${data.port}"
-------------------------------------------------------------------------------------

This configuration launches a `prometheus` module for all containers of pods annotated `prometheus.io/scrape=true`.

[float]
===== Manually Defining Ports with Kubernetes

Declare exposed ports in your pod spec if possible. Otherwise, you will need to use
multiple templates with complex filtering rules. The {port} variable will not be
present, and you will need to hardcode ports. Example: `{data.host}:1234`

When ports are not declared, Autodiscover generates a config using your provided
template once per pod, and once per container. These generated configs are
de-duplicated after they are generated. If the generated configs for multiple
containers are identical, they will be merged into one config.

Pods share an identical host. If only the `{data.host}` variable is interpolated,
then one config will be generated per host. The configs will be identical.
After they are de-duplicated, only one will be used.

In order to target one specific exposed port `{data.host}:{data.ports.web}` can be used
in template config, where `web` is the name of the exposed container port.

[float]
[[kubernetes-secrets]]
===== Metricbeat Autodiscover Secret Management

[float]
====== Local Keystore
Metricbeat autodiscover supports leveraging <<keystore>> in order to retrieve sensitive data like passwords.
Here is an example of how a configuration using keystore would look like:

["source","yaml",subs="attributes"]
-------------------------------------------------------------------------------------
metricbeat.autodiscover:
  providers:
    - type: kubernetes
      templates:
        - condition:
            contains:
              kubernetes.labels.app: "redis"
          config:
            - module: redis
              metricsets: ["info", "keyspace"]
              hosts: "${data.host}:6379"
              password: "${REDIS_PASSWORD}"
-------------------------------------------------------------------------------------

where `REDIS_PASSWORD` is a key stored in local keystore of Metricbeat.

[float]
===== Kubernetes Secrets
Metricbeat autodiscover supports leveraging https://kubernetes.io/docs/concepts/configuration/secret/[Kubernetes secrets]
in order to retrieve sensitive data like passwords. In order to enable this future add the following section
in Metricbeat's `ClusterRole` rules:

["source","yaml",subs="attributes"]
-------------------------------------------------------------------------------------
- apiGroups: [""]
  resources:
    - secrets
  verbs: ["get"]
-------------------------------------------------------------------------------------

CAUTION: The above rule will give permission to Metricbeat Pod to access Kubernetes Secrets API.
This means that anyone who have access to Metricbeat Pod (`kubectl exec` for example) will be able to access
Kubernetes Secrets API and get a specific secret no matter which namespace it belongs to. In this,
this option should be carefully considered, specially when used with hints.

One option to give permissions only for one namespace, and not cluster-scoped, is to use
a specific Role for a targeted namespace so as to better control access:

["source","yaml",subs="attributes"]
-------------------------------------------------------------------------------------
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: marketing-team
  name: secret-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["secrets"]
  verbs: ["get"]
-------------------------------------------------------------------------------------

One can find more info about Role and ClusterRole in the official Kubernetes
https://kubernetes.io/docs/reference/access-authn-authz/rbac/[documentation].

Here is an example of how a configuration using Kubernetes secrets would look like:

["source","yaml",subs="attributes"]
-------------------------------------------------------------------------------------
metricbeat.autodiscover:
  providers:
    - type: kubernetes
      templates:
        - condition:
            contains:
              kubernetes.labels.app: "redis"
          config:
            - module: redis
              metricsets: ["info", "keyspace"]
              hosts: "${data.host}:6379"
              password: "${kubernetes.default.somesecret.value}"
-------------------------------------------------------------------------------------

where `kubernetes.default.somesecret.value` specifies a key stored as Kubernetes secret as following:

. Kubernetes Namespace: `default`
. Kubernetes Secret Name: `somesecret`
. Secret Data Key: `value`

This secret can be created in a Kubernetes environment using the following the command:
["source","yaml",subs="attributes"]
-------------------------------------------------------------------------------------
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: somesecret
type: Opaque
data:
  value: $(echo -n "passpass" | base64)
EOF
-------------------------------------------------------------------------------------


Note that Pods can only consume secrets that belong to the same Kubernetes namespace. For instance if Pod `my-redis`
is running under `staging` namespace, it cannot access a secret under `testing` namespace for example `kubernetes.testing.xxx.yyy`.
