// Module included in the following assemblies:
//
// * edge_computing/ztp-deploying-far-edge-sites.adoc

:_mod-docs-content-type: PROCEDURE
[id="ztp-deploying-user-defined-firmware-configuration-with-gitops-ztp_{context}"]
= Deploying user-defined firmware to cluster hosts with {ztp}

[role="_abstract"]
You can deploy user-defined firmware settings to cluster hosts by creating custom node templates that include `HostFirmwareSettings` CRs, and referencing them in the `ClusterInstance` CR.
You can configure hardware profiles to apply to hosts in the following scenarios:

* All hosts in the cluster
* Individual hosts in the cluster

[IMPORTANT]
====
You can configure host hardware profiles to be applied in a hierarchy.
Node-level profiles override cluster-wide settings.
====

.Prerequisites

* You have installed the OpenShift CLI (`oc`).

* You have installed {rh-rhacm-first} version 2.12 or later and logged in to the hub cluster as a user with `cluster-admin` privileges.

* You have installed the SiteConfig Operator in the hub cluster.

* You created a Git repository where you manage your custom site configuration data.
The repository must be accessible from the hub cluster and be defined as a source repository for the Argo CD application.

.Procedure

. Create the `HostFirmwareSettings` CR that contains the firmware settings you want to apply.
For example, create the following YAML file:
+
.host-firmware-settings.yaml
[source,yaml]
----
apiVersion: metal3.io/v1alpha1
kind: HostFirmwareSettings
metadata:
  name: "site1-sno-du"
  namespace: "site1-sno-du"
spec:
  settings:
    BootMode: "Uefi"
    LogicalProc: "Enabled"
    ProcVirtualization: "Enabled"
----

. Save the `HostFirmwareSettings` CR file relative to the `kustomization.yaml` file that you use to provision the cluster.
For example:
+
[source,terminal]
----
site-configs/
  └── site1-sno-du/
        ├── clusterinstance-site1-sno-du.yaml
        ├── kustomization.yaml
        └── host-firmware-settings.yaml
----

. Create a `ConfigMap` to store the `HostFirmwareSettings` CR.
You can use a `kustomization.yaml` file with `configMapGenerator` to create the `ConfigMap`.
For example:
+
[source,yaml]
----
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - clusterinstance-site1-sno-du.yaml
configMapGenerator:
  - name: host-firmware-settings-cm
    namespace: site1-sno-du
    files:
      - host-firmware-settings.yaml
generatorOptions:
  disableNameSuffixHash: true
----
+
* `namespace` must match the `ClusterInstance` namespace.
* `host-firmware-settings.yaml` is the name of the `HostFirmwareSettings` CR.


. To apply a hardware profile to all hosts in the cluster, reference the `ConfigMap` in the `spec.templateRefs` field of your `ClusterInstance` CR.
For example:
+
[source,yaml]
----
apiVersion: siteconfig.open-cluster-management.io/v1alpha1
kind: ClusterInstance
metadata:
  name: "site1-sno-du"
  namespace: "site1-sno-du"
spec:
  clusterName: "site1-sno-du"
  # ...
  templateRefs:
    - name: host-firmware-settings-cm
      namespace: site1-sno-du
  nodes:
    - hostName: "node1.example.com"
      # ...
----
+
* `templateRefs` applies the firmware profile to all hosts in the cluster.


. Optional: To apply a hardware profile to a specific host in the cluster, reference the `ConfigMap` in the `spec.nodes[].templateRefs` field.
For example:
+
[source,yaml]
----
apiVersion: siteconfig.open-cluster-management.io/v1alpha1
kind: ClusterInstance
metadata:
  name: "site1-sno-du"
  namespace: "site1-sno-du"
spec:
  clusterName: "site1-sno-du"
  # ...
  nodes:
    - hostName: "node1.example.com"
      # ...
      templateRefs:
        - name: host-firmware-node1-cm
          namespace: site1-sno-du
    - hostName: "node2.example.com"
      # ...
----
+
* `nodes[].templateRefs` applies the firmware profile only to the `node1.example.com` host.
+
[NOTE]
====
Node-level `templateRefs` settings override cluster-level `templateRefs` settings.
====

. Commit the `ClusterInstance` CR, `ConfigMap`, and associated `kustomization.yaml` changes in your Git repository and push the changes.
+
The Argo CD pipeline detects the changes and begins the managed cluster deployment.
+
[NOTE]
====
Cluster deployment proceeds even if an invalid firmware setting is detected.
To apply a correction using {ztp}, re-deploy the cluster with the corrected hardware profile.
====

.Verification

* Check that the firmware settings have been applied in the managed cluster host.
For example, run the following command:
+
[source,terminal]
----
$ oc get hfs -n <managed_cluster_namespace> <managed_cluster_name> -o jsonpath='{.status.conditions[?(@.type=="Valid")].status}'
----
+
* `<managed_cluster_namespace>` is the namespace of the managed cluster and `<managed_cluster_name>` is the name of the managed cluster.
+
The following example output shows valid firmware settings:
+
[source,terminal]
----
True
----
