> For the complete documentation index, see [llms.txt](https://docs.prismacloud.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.prismacloud.io/content-collections/runtime-security/install/deploy-defender/kubernetes/declarative-object.md).

# Deploy Defender with Declarative Object Management

Defender is installed as a DaemonSet, which ensures that an instance of Defender runs on every node in the cluster. Use *twistcli* to generate a YAML configuration file or Helm chart for the Defender DaemonSet, then deploy it using *oc*. You can use the same method to deploy Defender DaemonSets from both macOS and Linux.

The benefit of declarative object management, where you work directly with YAML configuration files, is that you get the full "source code" for the objects you create in your cluster. You can use a version control tool to manage and track modifications to config files so that you can delete and reliably recreate DaemonSets in your environment.

If you don’t have kubectl access to your cluster (or oc access for OpenShift), you can deploy Defender DaemonSets directly from the [Console UI](https://github.com/PaloAltoNetworks/pc-docs-md/tree/main/enterprise-edition/content-collections/runtime-security/install/deploy-defender/container/container.md).

The following procedure shows you how to deploy Defender DaemonSets with twistcli using declarative object management. Alternatively, you can generate Defender DaemonSet install commands in the Console UI under **Manage > Defenders > Deploy > DaemonSet**. Install scripts work on Linux hosts only. For macOS and Windows hosts, use twistcli to generate Defender DaemonSet YAML configuration files, and then deploy it with oc, as described in the following procedure.

## Get connection strings

When calling twistcli to generate your YAML files and Helm charts, you’ll need to specify a couple of addresses.

1. Retrieve Console’s URL (PRISMA\_CLOUD\_COMPUTE\_CONSOLE\_URL).
   1. Sign into Prisma Cloud.
   2. Go to **Runtime Security > Manage > System > Utilities**.
   3. Copy the URL under **Path to Console**.
2. Retrieve Console’s hostname (PRISMA\_CLOUD\_COMPUTE\_HOSTNAME).

   The hostname can be derived from the URL by removing the protocol scheme and path. It is simply the host part of the URL. You can also retrieve the hostname directly.

   1. Go to **Runtime Security > Manage > Defenders > Defenders: Deployed > Manual deploy > Orchestrator**.
   2. Select **OpenShift** from **Step 2** (**Choose the orchestrator type**)
   3. Copy the hostname from **Step 3** (**The name that Defender will use to connect to this Console**)

## Option #1: Deploy with YAML files

Deploy the Defender DaemonSet with YAML files.

The *twistcli defender export* command can be used to generate native Kubernetes YAML files to deploy the Defender as a DaemonSet.

1. Generate a *defender.yaml* file, where:

   The following command connects to Console (specified in *--address*) as user \<ADMIN> (specified in *--user*), and generates a Defender DaemonSet YAML config file according to the configuration options passed to *twistcli*. The *--cluster-address* option specifies the address Defender uses to connect to Console.

   ```
   $ <PLATFORM>/twistcli defender export openshift \
     --user <ADMIN_USER> \
     --address <PRISMA_CLOUD_COMPUTE_CONSOLE_URL> \
     --cluster-address <PRISMA_CLOUD_COMPUTE_HOSTNAME> \
     --container-runtime crio
   ```

   * \<PLATFORM> can be linux, osx, or windows.
   * \<ADMIN\_USER> is the name of a Prisma Cloud user with the System Admin role.
2. Deploy the Defender DaemonSet.

   ```
   $ oc create -f ./defender.yaml
   ```

## Option #2: Deploy with Helm chart

Deploy the Defender DaemonSet with a Helm chart.

Prisma Cloud Defenders Helm charts fail to install on OpenShift 4 clusters due to a Helm bug. If you generate a Helm chart, and try to install it in an OpenShift 4 cluster, you’ll get the following error:

```
Error: unable to recognize "": no matches for kind "SecurityContextConstraints" in version "v1"
```

To work around the issue, manually modify the generated Helm chart.

1. Generate the Defender DaemonSet helm chart.

   A number of command variations are provided. Use them as a basis for constructing your own working command.

   The following commands connects to Console (specified in *--address*) as user \<ADMIN> (specified in *--user*), and generates a Defender DaemonSet YAML config file according to the configuration options passed to *twistcli*. The *--cluster-address* option specifies the address Defender uses to connect to Console.

   **Outside the OpenShift cluster + pull the Defender image from the Prisma Cloud cloud registry.** Use the OpenShift external route for your Prisma Cloud Console, *--address <https://twistlock-console.apps.ose.example.com>*. Designate Prisma Cloud’s cloud registry by omitting the *--image-name* flag. Defining CRI-O as the default container engine by using the `--container-runtime crio` flag.

   ```
   $ <PLATFORM>/twistcli defender export openshift \
     --user <ADMIN_USER> \
     --address <PRISMA_CLOUD_COMPUTE_CONSOLE_URL> \
     --cluster-address <PRISMA_CLOUD_COMPUTE_HOSTNAME> \
     --container-runtime crio \
     --helm
   ```

   **Outside the OpenShift cluster + pull the Defender image from the OpenShift internal registry.** Use the *--image-name* flag to designate an image from the OpenShift internal registry. Defining CRI-O as the default container engine by using the `--container-runtime crio` flag.

   ```
   $ <PLATFORM>/twistcli defender export openshift \
     --user <ADMIN_USER> \
     --address <PRISMA_CLOUD_COMPUTE_CONSOLE_URL> \
     --cluster-address <PRISMA_CLOUD_COMPUTE_HOSTNAME> \
     --image-name 172.30.163.181:5000/twistlock/private:defender_<VERSION> \
     --container-runtime crio \
     --helm
   ```

   **Inside the OpenShift cluster + pull the Defender image from the Prisma Cloud cloud registry.** When generating the Defender DaemonSet YAML with twistcli from a node inside the cluster, use Console’s service name (twistlock-console) or cluster IP in the *--cluster-address* flag. This flag specifies the endpoint for the Prisma Cloud Compute API and must include the port number. Defining CRI-O as the default container engine by using the `--container-runtime crio` flag.

   ```
   $ <PLATFORM>/twistcli defender export openshift \
     --user <ADMIN_USER> \
     --address <PRISMA_CLOUD_COMPUTE_CONSOLE_URL> \
     --cluster-address <PRISMA_CLOUD_COMPUTE_HOSTNAME> \
     --container-runtime crio \
     --helm
   ```

   **Inside the OpenShift cluster + pull the Defender image from the OpenShift internal registry.** Use the *--image-name* flag to designate an image in the OpenShift internal registry. Defining CRI-O as the default container engine by using the `--container-runtime crio` flag.

   ```
   $ <PLATFORM>/twistcli defender export openshift \
     --user <ADMIN_USER> \
     --address <PRISMA_CLOUD_COMPUTE_CONSOLE_URL> \
     --cluster-address <PRISMA_CLOUD_COMPUTE_HOSTNAME> \
     --image-name 172.30.163.181:5000/twistlock/private:defender_<VERSION> \
     --container-runtime crio \
     --helm
   ```
2. Unpack the chart into a temporary directory.

   ```
   $ mkdir helm-defender
   $ tar xvzf twistlock-defender-helm.tar.gz -C helm-defender/
   ```
3. Open *helm-console/twistlock-defender/templates/securitycontextconstraints.yaml* for editing.
4. Change `apiVersion` from `v1` to `security.openshift.io/v1`.

   ```yaml
   {{- if .Values.openshift }}
   apiVersion: security.openshift.io/v1
   kind: SecurityContextConstraints
   metadata:
   name: twistlock-console
   ...
   ```
5. Repack the Helm chart

   ```
   $ cd helm-defender/
   $ tar cvzf twistlock-defender-helm.tar.gz twistlock-defender/
   ```
6. Install the new helm chart via the helm command

   ```
   $ helm install --namespace=twistlock -g twistlock-defender-helm.tar.gz
   ```

## Confirm Defenders were deployed

Confirm the installation was successful.

1. In Prisma Cloud Console, go to **Runtime Security > Manage > Defenders > Defenders: Deployed** to see a list of deployed Defenders.

   <figure><img src="/files/uCBdxBNlBCWMzMyC7vvg" alt="install openshift tl defenders"><figcaption></figcaption></figure>
2. In the OpenShift Web Console, go to the Prisma Cloud project’s monitoring window to see which pods are running.

   <figure><img src="/files/iLxn30lKUaOwmhq5evZR" alt="install openshift ose defenders"><figcaption></figcaption></figure>
3. Use the OpenShift CLI to see the DaemonSet pod count.

   ```
   $ oc get ds -n twistlock

   NAME                    DESIRED   CURRENT   READY     UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
   twistlock-defender-ds   4         3         3         3            3           <none>          29m
   ```

   The *desired* and *current* pod counts do not match. This is a job for the nodeSelector.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.prismacloud.io/content-collections/runtime-security/install/deploy-defender/kubernetes/declarative-object.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
