{% panel style="success", title="Providing Feedback" %}
**Provide feedback at the [survey](https://www.surveymonkey.com/r/CLQBQHR)**
{% endpanel %}

{% panel style="info", title="TL;DR" %}
- Generate Secrets from files and literals with `secretGenerator`
- Generate ConfigMaps from files and literals with `configMapGenerator`
- Rolling out changes to Secrets and ConfigMaps
{% endpanel %}

# Secrets and ConfigMaps

{% panel style="info", title="Reference" %}
- [secretGenerators](../reference/kustomize.md#secretgenerator)
- [configMapGenerators](../reference/kustomize.md#configmapgenerator)
- [generatorOptions](../reference/kustomize.md#generatoroptions)
{% endpanel %}

## Motivation

The source of truth for Secret and ConfigMap Resources typically resides
somewhere else, such as a `.properties` file.  Apply offers native support
for generating both Secrets and ConfigMaps from other sources such as files and
literals.

Additionally, Secrets and ConfigMaps require rollouts to be performed
differently than for most other Resources in order for the changes to be
rolled out to Pods consuming them.

## Generators

Secret and ConfigMap Resources can be generated by adding `secretGenerator`
or `configMapGenerator` entries to the `kustomization.yaml` file.

**The generated Resources name's will have suffixes that change when their data
changes.  See [Rollouts](#rollouts) for more on this.**

### ConfigMaps From Files

{% method %}
ConfigMap Resources may be generated from files - such as a java `.properties` file.  To generate a ConfigMap
Resource for a file, add an entry to `configMapGenerator` with the filename.

**Example:** Generate a ConfigMap with a data item containing the contents of a file.

The ConfigMaps will have data values populated from the file contents.  The contents of each file will
appear as a single data item in the ConfigMap keyed by the filename.

{% sample lang="yaml" %}
**Input:** The kustomization.yaml file

```yaml
# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- name: my-application-properties
  files:
  - application.properties
```

```yaml
# application.properties
FOO=Bar
```

**Applied:** The Resource that is Applied to the cluster

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  # The name has had a suffix applied
  name: my-application-properties-c79528k426
# The data has been populated from each file's contents
data:
  application.properties: |
    FOO=Bar
```
{% endmethod %}

### ConfigMaps From Literals

ConfigMap Resources may be generated from literal key-value pairs - such as `JAVA_HOME=/opt/java/jdk`.
To generate a ConfigMap Resource from literal key-value pairs, add an entry to `configMapGenerator` with a
list of `literals`.

{% panel style="info", title="Literal Syntax" %}
- The key/value are separated by a `=` sign (left side is the key)
- The value of each literal will appear as a data item in the ConfigMap keyed by its key.
{% endpanel %}

{% method %}
**Example:** Create a ConfigMap with 2 data items generated from literals.

{% sample lang="yaml" %}
**Input:** The kustomization.yaml file

```yaml
# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- name: my-java-server-env-vars
  literals:
  - JAVA_HOME=/opt/java/jdk
  - JAVA_TOOL_OPTIONS=-agentlib:hprof
```

**Applied:** The Resource that is Applied to the cluster

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  # The name has had a suffix applied
  name: my-java-server-env-vars-k44mhd6h5f
# The data has been populated from each literal pair
data:
  JAVA_HOME: /opt/java/jdk
  JAVA_TOOL_OPTIONS: -agentlib:hprof
```
{% endmethod %}

### ConfigMaps From Environment Files

ConfigMap Resources may be generated from key-value pairs much the same as using the literals option
but taking the key-value pairs from an environment file. These generally end in `.env`.
To generate a ConfigMap Resource from an environment file, add an entry to `configMapGenerator` with a
single `env` entry, e.g. `env: config.env`.

{% panel style="info", title="Environment File Syntax" %}
- The key/value pairs inside of the environment file are separated by a `=` sign (left side is the key)
- The value of each line will appear as a data item in the ConfigMap keyed by its key.
{% endpanel %}

{% method %}
**Example:** Create a ConfigMap with 3 data items generated from an environment file.

{% sample lang="yaml" %}
**Input:** The kustomization.yaml file

```yaml
# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- name: tracing-options
  env: tracing.env
```

```bash
# tracing.env
ENABLE_TRACING=true
SAMPLER_TYPE=probabilistic
SAMPLER_PARAMETERS=0.1
```

**Applied:** The Resource that is Applied to the cluster

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  # The name has had a suffix applied
  name: tracing-options-6bh8gkdf7k
# The data has been populated from each literal pair
data:
  ENABLE_TRACING: "true"
  SAMPLER_TYPE: "probabilistic"
  SAMPLER_PARAMETERS: "0.1"
```
{% endmethod %}

{% panel style="success", title="Overriding Base ConfigMap Values" %}
ConfigMaps Values from Bases may be overridden by adding another generator for the ConfigMap
in the Variant and specifying the `behavior` field.  `behavior` may be
one of `create` (default value), `replace` (replace the base ConfigMap),
or `merge` (add or update the values the ConfigMap).  See [Bases and Variantions](../app_customization/bases_and_variants.md)
for more on using Bases.  e.g. `behavior: "merge"`
{% endpanel %}

### Secrets from Files

Secret Resources may be generated much like ConfigMaps can. This includes generating them
from literals, files or environment files.

{% panel style="info", title="Secret Syntax" %}
Secret type is set using the `type` field.
{% endpanel %}

{% method %}
**Example:** Generate a `kubernetes.io/tls` Secret from local files

{% sample lang="yaml" %}
**Input:** The kustomization.yaml file

```yaml
# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
secretGenerator:
- name: app-tls
  files:
    - "secret/tls.cert"
    - "secret/tls.key"
  type: "kubernetes.io/tls"
```

**Applied:** The Resource that is Applied to the cluster

```yaml
apiVersion: v1
kind: Secret
metadata:
  # The name has had a suffix applied
  name: app-tls-4tc9tcbd8k
type: kubernetes.io/tls
# The data has been populated from each command's output
data:
  tls.crt: LS0tLS1CRUd...tCg==
  tls.key: LS0tLS1CRUd...0tLQo=
```
{% endmethod %}

### Generator Options

{% method %}
It is also possible to specify cross-cutting options for generated objects
using  `generatorOptions`.

{% sample lang="yaml" %}

```yaml
# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
generatorOptions:
  # labels to add to all generated resources
  labels:
    kustomize.generated.resources: somevalue
  # annotations to add to all generated resources
  annotations:
    kustomize.generated.resource: somevalue
  # disableNameSuffixHash is true disables the default behavior of adding a
  # suffix to the names of generated resources that is a hash of
  # the resource contents.
  disableNameSuffixHash: true
```

{% endmethod %}

### Propagating the Name Suffix

{% method %}
Workloads that reference the ConfigMap or Secret will need to know the name of the generated Resource
including the suffix, however Apply takes care of this automatically for users.  Apply will identify
references to generated ConfigMaps and Secrets, and update them.

The generated ConfigMap name will be `my-java-server-env-vars` with a suffix unique to its contents.
Changes to the contents will change the name suffix, resulting in the creation of a new ConfigMap,
and transform Workloads to point to this one.

The PodTemplate volume references the ConfigMap by the name specified in the generator (excluding the suffix).
Apply will update the name to include the suffix applied to the ConfigMap name.

{% sample lang="yaml" %}
**Input:** The kustomization.yaml and deployment.yaml files

```yaml
# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- name: my-java-server-env-vars
  literals:
  - JAVA_HOME=/opt/java/jdk
  - JAVA_TOOL_OPTIONS=-agentlib:hprof
resources:
- deployment.yaml
```

```yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-deployment
  labels:
    app: test
spec:
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      containers:
      - name: container
        image: k8s.gcr.io/busybox
        command: [ "/bin/sh", "-c", "ls /etc/config/" ]
        volumeMounts:
        - name: config-volume
          mountPath: /etc/config
      volumes:
      - name: config-volume
        configMap:
          name: my-java-server-env-vars
```

**Applied:** The Resources that are Applied to the cluster.

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  # The name has been updated to include the suffix
  name: my-java-server-env-vars-k44mhd6h5f
data:
  JAVA_HOME: /opt/java/jdk
  JAVA_TOOL_OPTIONS: -agentlib:hprof
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: test
  name: test-deployment
spec:
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      containers:
      - command:
        - /bin/sh
        - -c
        - ls /etc/config/
        image: k8s.gcr.io/busybox
        name: container
        volumeMounts:
        - mountPath: /etc/config
          name: config-volume
      volumes:
      - configMap:
          # The name has been updated to include the
          # suffix matching the ConfigMap
          name: my-java-server-env-vars-k44mhd6h5f
        name: config-volume
```
{% endmethod %}

## Rollouts

ConfigMap values are consumed by Pods as: environment variables, command line arguments and files.

This is important because Updating a ConfigMap will:

- immediately update the files mounted by *all* Pods consuming them
- not update the environment variables or command line arguments until the Pod is restarted

Typically users want to perform a rolling update of the ConfigMap changes to Pods as soon as
the ConfigMap changes are pushed.

Apply facilitates rolling updates for ConfigMaps by creating a new ConfigMap
for each change to the data.  Workloads (e.g. Deployments, StatefulSets, etc) are updated to point to a new
ConfigMap instead of the old one.  This allows the change to be gradually rolled the same way
other Pod Template changes are rolled out.

Each generated Resources name has a suffix appended by hashing the contents.  This approach ensures a new
ConfigMap is generated each time the contents is modified.

**Note:** Because the Resource names will contain a suffix, when looking for them with `kubectl get`,
their names will not match exactly what is specified in the kustomization.yaml file.
