> ## Documentation Index
> Fetch the complete documentation index at: https://docs.siderolabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration Patches

> In this guide, we'll patch the generated machine configuration.

export const VersionWarningBanner = () => {
  const latestVersion = "v1.13";
  const [latestUrl, setLatestUrl] = useState(null);
  const [currentVersion, setCurrentVersion] = useState(null);
  const [isBeta, setIsBeta] = useState(false);
  const parseVersion = v => v.replace("v", "").split(".").map(Number);
  const isGreaterVersion = (a, b) => {
    const [aMajor, aMinor] = parseVersion(a);
    const [bMajor, bMinor] = parseVersion(b);
    if (aMajor > bMajor) return true;
    if (aMajor === bMajor && aMinor > bMinor) return true;
    return false;
  };
  useEffect(() => {
    if (typeof window === "undefined") return;
    const {pathname, hash, search} = window.location;
    const match = pathname.match(/\/talos\/(v\d+\.\d+)\//);
    if (!match) return;
    const detectedVersion = match[1];
    if (detectedVersion === latestVersion) return;
    setCurrentVersion(detectedVersion);
    if (isGreaterVersion(detectedVersion, latestVersion)) {
      setIsBeta(true);
    }
    const newPath = pathname.replace(`/talos/${detectedVersion}/`, `/talos/${latestVersion}/`);
    setLatestUrl(`${newPath}${search}${hash}`);
  }, []);
  if (!latestUrl || !currentVersion) return null;
  return <div className="not-prose sticky top-6 z-50 my-6">
      <div className="border border-yellow-500/30 bg-yellow-500/10 px-4 py-3 rounded-xl">
        <div className="text-sm">
          {isBeta ? <>
              ⚠️ You are viewing a <strong>beta version</strong> of Talos ({currentVersion}).
              This version may be unstable.
              <a href={latestUrl} className="ml-2 underline text-yellow-400 hover:text-yellow-300 font-medium">
                View latest stable version {latestVersion} →
              </a>
            </> : <>
              ⚠️ You are viewing an older version of Talos ({currentVersion}).
              <a href={latestUrl} className="ml-2 underline text-yellow-400 hover:text-yellow-300 font-medium">
                View the latest version {latestVersion} →
              </a>
            </>}
        </div>
      </div>
    </div>;
};

<VersionWarningBanner />

Talos generates machine configuration for two types of machines: controlplane and worker machines.
Many configuration options can be adjusted using `talosctl gen config` but not all of them.
Configuration patching allows modifying machine configuration to fit it for the cluster or a specific machine.

Configuration patching can also be used to mutate existing machine configuration on running Talos nodes.
See [reproducible machine configuration](./reproducible-machine-configuration) for more information on managing your patches.

### Patch machine configuration using strategic merge patches

Talos Linux supports patching machine configuration using strategic merge patches.
Strategic merge patches look like incomplete machine configuration files:

```yaml theme={null}
apiVersion: v1alpha1
kind: HostnameConfig
hostname: my-custom-hostname
auto: off
```

Multiple configuration documents can be included in the patch using multi-document YAML syntax (`---` separator).

When applied to the machine configuration, the patch gets merged with the respective section of the machine configuration.

In general, machine configuration contents are merged with the contents of the strategic merge patch, with strategic merge patch
values overriding machine configuration values.
There are some special rules:

* If the field value is a list, the patch value is appended to the list, with the following exceptions:
  * values of the fields `cluster.network.podSubnets` and `cluster.network.serviceSubnets` are overwritten on merge
  * `network.interfaces` section is merged with the value in the machine config if there is a match on `interface:` or `deviceSelector:` keys
  * `network.interfaces.vlans` section is merged with the value in the machine config if there is a match on the `vlanId:` key
  * `cluster.apiServer.auditPolicy` value is replaced on merge
  * `ExtensionServiceConfig.configFiles` section is merged matching on `mountPath` (replacing `content` if matches)

* When patching a [multi-document machine configuration](../../reference/configuration/overview), following rules apply:
  * for each document in the patch, the document is merged with the respective document in the machine configuration (matching by `kind`, `apiVersion` and `name` for named documents)
  * if the patch document doesn’t exist in the machine configuration, it is appended to the machine configuration

The strategic merge patch itself might be a multi-document YAML, and each document will be applied as a patch to the base machine configuration.

A single patch file cannot modify the same document more than once.

You can also delete parts from the configuration using `$patch: delete` syntax similar to the
[Kubernetes](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/strategic-merge-patch.md#delete-directive)
strategic merge patch.

For example, with configuration:

```yaml theme={null}
apiVersion: v1alpha1
kind: LinkConfig
name: enp0s3
mtu: 9000
up: true
```

and patch document:

```yaml theme={null}
apiVersion: v1alpha1
kind: LinkConfig
name: enp0s3
mtu:
  $patch: delete
```

The resulting configuration will be:

```yaml theme={null}
apiVersion: v1alpha1
kind: LinkConfig
name: enp0s3
up: true
```

You can also delete entire docs (but not the main `v1alpha1` configuration!) using this syntax:

```yaml theme={null}
apiVersion: v1alpha1
kind: SideroLinkConfig
$patch: delete
---
apiVersion: v1alpha1
kind: ExtensionServiceConfig
name: foo
$patch: delete
```

This will remove the documents `SideroLinkConfig` and `ExtensionServiceConfig` with name `foo` from the configuration.

## Examples

The following examples demonstrate common use cases for configuration patches.

### Machine network

Base machine configuration:

```yaml theme={null}
apiVersion: v1alpha1
kind: LinkConfig
name: eth0
up: true
```

The goal is to add a virtual IP `192.168.10.50` to the `eth0` interface and add another interface `eth1` with DHCP enabled.

```yaml theme={null}
apiVersion: v1alpha1
kind: DHCPv4Config
name: eth1
---
apiVersion: v1alpha1
kind: Layer2VIPConfig
name: 192.168.10.50
link: eth0
```

Patched machine configuration:

```yaml theme={null}
apiVersion: v1alpha1
kind: LinkConfig
name: eth0
up: true
---
apiVersion: v1alpha1
kind: DHCPv4Config
name: eth1
---
apiVersion: v1alpha1
kind: Layer2VIPConfig
name: 192.168.10.50
link: eth0
```

### Cluster network

Base machine configuration:

```yaml theme={null}
cluster:
  network:
    dnsDomain: cluster.local
    podSubnets:
      - 10.244.0.0/16
    serviceSubnets:
      - 10.96.0.0/12
```

The goal is to update pod and service subnets and disable default CNI (Flannel).

```yaml theme={null}
cluster:
  network:
    podSubnets:
      - 192.168.0.0/16
    serviceSubnets:
      - 192.0.0.0/12
    cni:
      name: none
```

Patched machine configuration:

```yaml theme={null}
cluster:
  network:
    dnsDomain: cluster.local
    podSubnets:
      - 192.168.0.0/16
    serviceSubnets:
      - 192.0.0.0/12
    cni:
      name: none
```

### Kubelet

Base machine configuration:

```yaml theme={null}
# ...
machine:
  kubelet: {}
```

The goal is to set the `kubelet` node IP to come from the subnet `192.168.10.0/24`:

```yaml theme={null}
machine:
  kubelet:
    nodeIP:
      validSubnets:
        - 192.168.10.0/24
```

Patched machine configuration:

```yaml theme={null}
machine:
  kubelet:
    nodeIP:
      validSubnets:
        - 192.168.10.0/24
```

### Admission control: Pod security policy

Base machine configuration:

```yaml theme={null}
cluster:
  apiServer:
    admissionControl:
      - name: PodSecurity
        configuration:
          apiVersion: pod-security.admission.config.k8s.io/v1alpha1
          defaults:
            audit: restricted
            audit-version: latest
            enforce: baseline
            enforce-version: latest
            warn: restricted
            warn-version: latest
          exemptions:
            namespaces:
              - kube-system
            runtimeClasses: []
            usernames: []
          kind: PodSecurityConfiguration
```

The goal is to add an exemption for the namespace `rook-ceph`.

Patch:

```yaml theme={null}
  cluster:
    apiServer:
      admissionControl:
        - name: PodSecurity
          configuration:
            exemptions:
              namespaces:
                - rook-ceph
```

Patched machine configuration:

```yaml theme={null}
cluster:
  apiServer:
    admissionControl:
      - name: PodSecurity
        configuration:
          apiVersion: pod-security.admission.config.k8s.io/v1alpha1
          defaults:
            audit: restricted
            audit-version: latest
            enforce: baseline
            enforce-version: latest
            warn: restricted
            warn-version: latest
          exemptions:
            namespaces:
              - kube-system
              - rook-ceph
            runtimeClasses: []
            usernames: []
          kind: PodSecurityConfiguration
```

## Configuration patching with `talosctl` CLI

Several `talosctl` commands accept config patches as command-line flags.
Config patches might be passed either as an inline value or as a reference to a file with `@file.patch` or `file.patch` syntax:

```shell theme={null}
talosctl ... --patch file.patch
```

If multiple config patches are specified, they are applied in the order of appearance.
The format of the patch (JSON patch or strategic merge patch) is detected automatically.

Talos machine configuration can be patched at the moment of generation with `talosctl gen config`:

```shell theme={null}
talosctl gen config test-cluster https://172.20.0.1:6443 \
  --config-patch @all.yaml \
  --config-patch-control-plane cp.yaml \
  --config-patch-worker worker.yaml
```

Generated machine configuration can also be patched after the fact with `talosctl machineconfig patch`

```shell theme={null}
talosctl machineconfig patch worker.yaml --patch patch.yaml -o worker1.yaml
```

Machine configuration on the running Talos node can be patched with `talosctl patch`:

```shell theme={null}
talosctl patch mc --nodes 172.20.0.2 --patch patch.yaml
```

## Multi-document patching

In addition to patching single-document machine configurations, Talos supports patching [multi-document machine configuration](../../reference/configuration/overview).

<iframe className="w-full aspect-video rounded-xl" src="https://www.youtube.com/embed/0lrFpqi4bOI?si=KriagQyRXF5vQpqe" title="Multi-doc configurations with Talos Linux" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />

Multi-document patching allows configuration to be modified at the document level. This makes it possible to manage and reuse small, focused configuration fragments instead of editing a single, monolithic machine configuration.

This approach is commonly used to apply targeted changes, such as updating hostnames, network settings, or kubelet configuration, without regenerating the full machine configuration.

For example, the following patch updates a machine’s hostname:

```yaml theme={null}
apiVersion: v1alpha1
kind: HostnameConfig
hostname: worker-33
auto: off
```

### Apply a multi-document patch

Multi-document patches are applied while the machine is in maintenance mode. In this state, the machine has not yet received any credentials or certificates to authenticate the client.

To bootstrap authentication, the initial machine configuration must be applied using the [the `--insecure` flag](../system-configuration/insecure), along with the multi-document patch.

```bash theme={null}
talosctl apply \
  -f <machine-configuration> \
  --insecure \
  --node <node-ip> \
  --patch @<multi-document>
```

Where:

* `<machine-configuration>` -  is the base machine configuration (for example, `controlplane.yaml` or `worker.yaml`) generated using `talosctl gen config`. This configuration contains the credentials required to authenticate the client.

* `<node-ip>` - is the IP address of the target node.

* `<multi-document>` - is the YAML file containing the multi-document patch.
