Skip to content

Commit 2d1a735

Browse files
committed
docs: add operator policy guide
ref: https://redhat.atlassian.net/browse/ACM-10409 Signed-off-by: Janelle Law <jalaw@redhat.com>
1 parent a4c8ad9 commit 2d1a735

3 files changed

Lines changed: 306 additions & 0 deletions

File tree

content/en/docs/getting-started/integration/policy-controllers/_index.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,9 @@ View the following sections to learn more about the Policy Add-on:
3434
Gatekeeper is a validating webhook with auditing capabilities that can enforce custom resource definition-based
3535
policies that are run with the Open Policy Agent (OPA). Gatekeeper `ConstraintTemplates` and constraints can be
3636
provided in an OCM `Policy` to sync to managed clusters that have Gatekeeper installed on them.
37+
38+
- #### [Operator policy]({{< ref "docs/getting-started/integration/policy-controllers/operator-policy" >}})
39+
40+
The `OperatorPolicy` is provided by OCM and defines a desired state for operators managed by Operator Lifecycle Manager (OLM)
41+
on managed clusters. It enables automated installation, configuration, and lifecycle management of operators across your
42+
cluster fleet using the same policy framework as `ConfigurationPolicy`.
Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
---
2+
title: Operator Policy
3+
weight: 5
4+
hide_summary: true
5+
---
6+
7+
The `OperatorPolicy` defines a desired state for operators managed by the Operator Lifecycle Manager (OLM) on managed clusters. The Operator policy controller is provided by Open Cluster Management and runs on managed clusters as part of the `config-policy-controller` deployment.
8+
9+
View the [Policy API concepts]({{< ref "docs/getting-started/integration/policy-controllers/policy#managed-cluster-policy-controllers" >}}) page to learn more about the `OperatorPolicy` API.
10+
11+
## Prerequisites
12+
13+
You must meet the following prerequisites to use the Operator policy controller:
14+
15+
- Ensure [`kubectl`](https://kubernetes.io/docs/tasks/tools/install-kubectl) and [`kustomize`](https://kubectl.docs.kubernetes.io/installation/kustomize/) are installed.
16+
17+
- Ensure [Golang](https://golang.org/doc/install) is installed, if you are planning to install from the source.
18+
19+
- Ensure the `open-cluster-management` _policy framework_ is installed. See [Policy Framework]({{< ref "docs/getting-started/integration/policy-controllers/policy-framework" >}}) for more information.
20+
21+
- Ensure Operator Lifecycle Manager (OLM) is installed on the managed clusters where you plan to deploy operators. See the [OLM Quick Start guide](https://olm.operatorframework.io/docs/getting-started/) for installation instructions.
22+
23+
## Installing the operator policy controller
24+
25+
The operator policy controller and the configuration policy controller run in the same `config-policy-controller` pod on managed clusters. The operator policy controller is disabled by default.
26+
27+
Steps 1 and 2 will install the configuration policy controller, matching the steps in [Installing the configuration policy controller]({{< ref "docs/getting-started/integration/policy-controllers/configuration-policy">}}).
28+
29+
If configuration policy controller is already installed, complete Step 3 onwards.
30+
31+
### Deploy via Clusteradm CLI
32+
33+
Ensure `clusteradm` CLI is installed and is newer than v0.3.0. Download and extract the [clusteradm binary](https://github.com/open-cluster-management-io/clusteradm/releases/latest). For more details see the [clusteradm GitHub page](https://github.com/open-cluster-management-io/clusteradm/blob/main/README.md#quick-start).
34+
35+
1. Deploy the configuration policy controller (which includes the operator policy controller) to the managed clusters:
36+
37+
```Shell
38+
$ clusteradm addon enable addon --names config-policy-controller --clusters <cluster_name> --context ${CTX_HUB_CLUSTER}
39+
Deploying config-policy-controller add-on to namespaces open-cluster-management-agent-addon of managed cluster: <cluster_name>
40+
```
41+
42+
2. Ensure the pod is running on the managed cluster with the following command:
43+
44+
```Shell
45+
$ kubectl get pods -n open-cluster-management-agent-addon --context ${CTX_MANAGED_CLUSTER}
46+
NAME READY STATUS RESTARTS AGE
47+
config-policy-controller-7f8fb64d8c-pmfx4 1/1 Running 0 44s
48+
```
49+
50+
3. To enable operator policy controller on managed cluster `cluster1`, annotate the ManagedClusterAddon in the hub cluster:
51+
52+
```Shell
53+
$ kubectl annotate -n cluster1 managedclusteraddon config-policy-controller operator-policy-disabled=false --context ${CTX_HUB_CLUSTER}
54+
```
55+
56+
4. On the managed cluster, confirm the operator policy controller was enabled by examining the `config-policy-controller` pod container arguments:
57+
58+
```Shell
59+
$ kubectl get pods -n open-cluster-management-agent-addon --context ${CTX_MANAGED_CLUSTER}
60+
NAME READY STATUS RESTARTS AGE
61+
config-policy-controller-5888b6cbc5-lvwdj 1/1 Running 0 30s
62+
63+
$ kubectl describe pod config-policy-controller-5888b6cbc5-lvwdj -n open-cluster-management-agent-addon --context ${CTX_MANAGED_CLUSTER} | grep enable-operator-policy
64+
- --enable-operator-policy=true
65+
```
66+
67+
## Sample operator policy
68+
69+
After a successful deployment, test the policy framework and operator policy controller with a sample policy.
70+
71+
For more information on how to use an `OperatorPolicy`, read the [Policy API concept section]({{< ref "docs/getting-started/integration/policy-controllers/policy-framework#policy" >}}).
72+
73+
### Example: Deploy an external secrets operator
74+
75+
The following example deploys an external secrets operator to a managed cluster using an `OperatorPolicy`. The ESO operator was chosen arbitrarily for the example.
76+
77+
1. Create a Policy in Inform mode to scan for an external secrets operator in managed cluster `cluster1` in the `default` namespace. The `Policy` remediation action of `inform` will override the remediation action of the `OperatorPolicy`:
78+
79+
```Yaml
80+
apiVersion: policy.open-cluster-management.io/v1
81+
kind: Policy
82+
metadata:
83+
name: policy-eso
84+
annotations:
85+
policy.open-cluster-management.io/standards: NIST SP 800-53
86+
policy.open-cluster-management.io/categories: CM Configuration Management
87+
policy.open-cluster-management.io/controls: CM-2 Baseline Configuration
88+
spec:
89+
remediationAction: inform
90+
disabled: false
91+
policy-templates:
92+
- objectDefinition:
93+
apiVersion: policy.open-cluster-management.io/v1beta1
94+
kind: OperatorPolicy
95+
metadata:
96+
name: policy-eso
97+
spec:
98+
remediationAction: inform
99+
severity: medium
100+
complianceType: musthave
101+
upgradeApproval: None
102+
operatorGroup:
103+
namespace: default
104+
name: external-secrets-operator-group
105+
targetNamespaces:
106+
- default
107+
subscription:
108+
namespace: default
109+
name: external-secrets-operator
110+
channel: alpha
111+
source: operatorhubio-catalog
112+
sourceNamespace: olm
113+
startingCSV: external-secrets-operator.v0.11.0
114+
versions:
115+
- external-secrets-operator.v0.11.0
116+
---
117+
apiVersion: policy.open-cluster-management.io/v1
118+
kind: PlacementBinding
119+
metadata:
120+
name: binding-policy-eso
121+
placementRef:
122+
name: placement-policy-eso
123+
kind: Placement
124+
apiGroup: cluster.open-cluster-management.io
125+
subjects:
126+
- name: policy-eso
127+
kind: Policy
128+
apiGroup: policy.open-cluster-management.io
129+
---
130+
apiVersion: cluster.open-cluster-management.io/v1beta1
131+
kind: Placement
132+
metadata:
133+
name: placement-policy-eso
134+
spec:
135+
predicates:
136+
- requiredClusterSelector:
137+
celSelector:
138+
celExpressions:
139+
- managedCluster.metadata.name == "cluster1"
140+
```
141+
142+
2. Apply the policy to the hub cluster:
143+
144+
```Shell
145+
$ kubectl apply -n default -f policy-eso.yaml --context ${CTX_HUB_CLUSTER}
146+
```
147+
148+
3. Ensure the `default` namespace has a `ManagedClusterSetBinding` for a `ManagedClusterSet` with at least one managed cluster resource. See [Bind ManagedClusterSet to a namespace]({{< ref "docs/concepts/cluster-inventory/managedclusterset#bind-managedclusterset-to-a-namespace" >}}) for more information.
149+
150+
4. Verify the managed cluster is selected by the `Placement`:
151+
152+
```Shell
153+
$ kubectl get -n default placementdecision placement-policy-eso-decision-1 -o yaml --context ${CTX_HUB_CLUSTER}
154+
155+
...
156+
status:
157+
decisions:
158+
- clusterName: cluster1
159+
```
160+
161+
The output shows the managed cluster `cluster1` is selected.
162+
163+
5. Verify the Policy was propagated to the managed cluster:
164+
165+
```Shell
166+
$ kubectl get policy -A --context ${CTX_MANAGED_CLUSTER}
167+
NAMESPACE NAME REMEDIATION ACTION COMPLIANCE STATE AGE
168+
cluster1 default.policy-eso inform NonCompliant 11s
169+
```
170+
171+
6. The policy is `NonCompliant`. Inspect the policy status:
172+
173+
```Shell
174+
$ kubectl describe policy default.policy-eso --context ${CTX_MANAGED_CLUSTER} -n cluster1
175+
...
176+
Status:
177+
Compliant: NonCompliant
178+
Details:
179+
Compliant: NonCompliant
180+
History:
181+
Event Name: default.policy-eso.18ab8e1a8ff67343
182+
Last Timestamp: 2026-05-01T21:25:22Z
183+
Message: NonCompliant; the policy spec is valid, ... the Subscription required by the policy was not found ...
184+
```
185+
186+
The policy is in `NonCompliant` state because the external secrets operator was not found on the managed cluster in the `default` namespace.
187+
188+
7. To automatically install the operator on the managed cluster, edit the policy remediation action to `enforce`, then re-apply the policy:
189+
190+
```Yaml
191+
apiVersion: policy.open-cluster-management.io/v1
192+
kind: Policy
193+
metadata:
194+
name: policy-eso
195+
annotations:
196+
policy.open-cluster-management.io/standards: NIST SP 800-53
197+
policy.open-cluster-management.io/categories: CM Configuration Management
198+
policy.open-cluster-management.io/controls: CM-2 Baseline Configuration
199+
spec:
200+
remediationAction: enforce # This top-level 'enforce' will override the OperatorPolicy `spec.remediationAction`
201+
```
202+
203+
```Shell
204+
$ kubectl apply -n default -f policy-eso.yaml --context ${CTX_HUB_CLUSTER}
205+
```
206+
207+
8. Verify the external secrets operator subscription was created:
208+
209+
```Shell
210+
$ kubectl get subscription -n default --context ${CTX_MANAGED_CLUSTER}
211+
NAME PACKAGE SOURCE CHANNEL
212+
external-secrets-operator external-secrets-operator operatorhubio-catalog alpha
213+
```
214+
215+
The output shows the external secrets operator subscription is active.
216+
217+
9. Verify the external secrets operator deployment is running:
218+
219+
```Shell
220+
$ kubectl get deployment -n default --context ${CTX_MANAGED_CLUSTER}
221+
NAME READY UP-TO-DATE AVAILABLE AGE
222+
external-secrets-operator-controller-manager 1/1 1 1 10m
223+
```
224+
225+
The output shows the external secrets operator is deployed and running.
226+
227+
### Cleanup: Remove the example operator
228+
229+
By default, the operator policy controller will delete most of the objects created by the policy when the OperatorPolicy `spec.complianceType` is changed to `mustnothave` AND the policy `remediationAction` is set to `enforce`.
230+
231+
1. Optional: edit the OperatorPolicy `spec.removalBehavior` to customize the objects to keep or delete. The default settings are:
232+
233+
```Yaml
234+
removalBehavior:
235+
clusterServiceVersions: Delete
236+
customResourceDefinitions: Keep
237+
subscriptions: Delete
238+
operatorGroups: DeleteIfUnused
239+
```
240+
241+
2. Edit the `complianceType` to `mustnothave` in the OperatorPolicy spec, then re-apply the policy:
242+
243+
```Yaml
244+
apiVersion: policy.open-cluster-management.io/v1
245+
kind: Policy
246+
metadata:
247+
name: policy-eso
248+
annotations:
249+
policy.open-cluster-management.io/standards: NIST SP 800-53
250+
policy.open-cluster-management.io/categories: CM Configuration Management
251+
policy.open-cluster-management.io/controls: CM-2 Baseline Configuration
252+
spec:
253+
remediationAction: enforce
254+
disabled: false
255+
policy-templates:
256+
- objectDefinition:
257+
apiVersion: policy.open-cluster-management.io/v1beta1
258+
kind: OperatorPolicy
259+
metadata:
260+
name: policy-eso
261+
spec:
262+
complianceType: mustnothave # Edit this line to `mustnothave`
263+
```
264+
265+
```Shell
266+
$ kubectl apply -n default -f policy-eso.yaml --context ${CTX_HUB_CLUSTER}
267+
```
268+
269+
3. Verify the external secrets operator and all other objects created by the Policy were deleted in the managed cluster:
270+
271+
```Shell
272+
$ kubectl get deployment -n default --context ${CTX_MANAGED_CLUSTER}
273+
No resources found in default namespace.
274+
275+
$ kubectl get subscription -n default --context ${CTX_MANAGED_CLUSTER}
276+
No resources found in default namespace.
277+
278+
# repeat for other objects
279+
```
280+
281+
4. Delete the Policy on the hub cluster.
282+
283+
```Shell
284+
$ kubectl delete -n default policy policy-eso --context ${CTX_HUB_CLUSTER}
285+
policy.policy.open-cluster-management.io "policy-eso" deleted
286+
```
287+
288+
## Additional resources
289+
290+
- [Policy API Concepts]({{< ref "docs/getting-started/integration/policy-controllers/policy" >}})
291+
- [Policy Collection - Community examples](https://github.com/open-cluster-management-io/policy-collection)
292+
- [Operator Lifecycle Manager (OLM) documentation](https://olm.operatorframework.io/docs/)
293+
- [OperatorHub.io registry](https://operatorhub.io/)

content/en/docs/getting-started/integration/policy-controllers/policy.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,13 @@ controller on the managed cluster. The policy framework supports delivering the
187187
the page on [Configuration Policy]({{< ref "docs/getting-started/integration/policy-controllers/configuration-policy" >}}) for more
188188
information.
189189

190+
- Operator policy
191+
192+
The `OperatorPolicy` is provided by OCM and defines a desired state for operators managed by Operator Lifecycle Manager (OLM)
193+
on managed clusters. It enables declarative lifecycle management of operators, including installation, configuration, upgrades,
194+
and removal across your cluster fleet. See the page on [Operator Policy]({{< ref "docs/getting-started/integration/policy-controllers/operator-policy" >}}) for more
195+
information.
196+
190197
- Open Policy Agent Gatekeeper
191198

192199
Gatekeeper is a validating webhook with auditing capabilities that can enforce custom resource definition-based

0 commit comments

Comments
 (0)