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

# Demo ForEach

> Explains Kyverno foreach usage to validate lists like containers and initContainers, enforcing image patterns and reducing rule duplication.

In this lesson we demonstrate how to use Kyverno's `foreach` construct inside validation rules to iterate over lists of elements within a resource. `foreach` simplifies policy authoring for repeated fields such as `containers`, `initContainers`, and volumes by applying a `pattern` to each element in the specified list.

How `foreach` works

* The `list` field accepts a JMESPath expression (e.g., `request.object.spec.containers`) to identify the array to iterate over.
* During each iteration a temporary variable named `element` is available to reference the current item being validated.
* The `pattern` block is evaluated against each `element`. If any element fails the pattern match, the rule fails.
* You can include multiple `foreach` entries in a single rule to validate different repeated fields (for example, both `initContainers` and `containers`) without creating separate rules.

Example: ClusterPolicy that enforces a trusted registry for every container image (including init containers)

```yaml theme={null}
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: check-images
spec:
  background: false
  validationFailureAction: Enforce
  rules:
    - name: check-registry
      match:
        any:
          - resources:
              kinds:
                - Pod
      preconditions:
        any:
          - key: "{{request.operation}}"
            operator: NotEquals
            value: DELETE
      validate:
        message: "unknown registry"
        foreach:
          - list: "request.object.spec.initContainers"
            pattern:
              image: "trusted-registry.io/*"
          - list: "request.object.spec.containers"
            pattern:
              image: "trusted-registry.io/*"
```

Policy explanation

* This is a `ClusterPolicy`, so it applies across the cluster to `Pod` resources.
* `preconditions` prevents the rule from running on `DELETE` operations (`key: "{{request.operation}}"`).
* `validationFailureAction: Enforce` blocks Pod creation when the rule fails.
* There are two `foreach` entries:
  * One iterates over `request.object.spec.initContainers`.
  * The other iterates over `request.object.spec.containers`.
* Each `pattern` is applied to each `element` in the corresponding list; the `image` field must match `trusted-registry.io/*` (the wildcard allows any image path under that registry).
* If any container or initContainer has an image that does not match the pattern, the rule will fail and the Pod will be rejected.

<Callout icon="lightbulb" color="#1CB2FE">
  Using multiple `foreach` entries inside a single rule lets you validate different repeated fields (like `initContainers` and `containers`) without writing separate rules.
</Callout>

Apply the policy

```bash theme={null}
kubectl apply -f foreach.yaml
# Output
# clusterpolicy.kyverno.io/check-images created
```

Test: Pod that violates the policy
This Pod uses `busybox:latest` from the public registry and should be rejected:

```bash theme={null}
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: bad-image-pod
spec:
  containers:
    - name: my-app
      image: busybox:latest
EOF
```

Expected rejection from the admission webhook:

```text theme={null}
Error from server: error when creating "STDIN": admission webhook "validate.kyverno.svc" denied the request:
resource Pod/default/bad-image-pod was blocked due to the following policies
check-images:
  check-registry: 'validation failure: validation error: unknown registry. rule check-registry failed at path /image/'
```

The Pod is blocked because the container image does not match `trusted-registry.io/*`.

Test: Pod that satisfies the policy
This Pod uses images from the trusted registry for both an init container and a main container and should be accepted:

```bash theme={null}
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: good-image-pod
spec:
  initContainers:
    - name: init-container
      image: trusted-registry.io/init-image:v1
  containers:
    - name: main-container
      image: trusted-registry.io/my-app:v1
EOF
```

Expected successful creation:

```text theme={null}
pod/good-image-pod created
```

Quick reference table

| Field                     | Purpose                                            | Example                          |
| ------------------------- | -------------------------------------------------- | -------------------------------- |
| `list`                    | JMESPath to the array being iterated               | `request.object.spec.containers` |
| `pattern`                 | Pattern applied to each `element` during iteration | `image: "trusted-registry.io/*"` |
| `validationFailureAction` | What happens on validation failure                 | `Enforce`                        |
| `preconditions`           | Skip rule for certain operations                   | `key: "{{request.operation}}"`   |

Summary

* `foreach` iterates over lists using a JMESPath expression (for example, `request.object.spec.containers` or `request.object.spec.initContainers`) and applies the `pattern` to each `element`.
* Using `foreach` reduces duplication and simplifies rules that validate repeated elements.
* Combining `foreach` with `preconditions` and `validationFailureAction: Enforce` provides a robust approach to block noncompliant resources.

Links and references

* Kyverno foreach documentation: [https://kyverno.io/docs/writing-policies/foreach/](https://kyverno.io/docs/writing-policies/foreach/)
* JMESPath query language: [https://jmespath.org/](https://jmespath.org/)
* Kubernetes admission webhooks: [https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/kyverno-certified-associate/module/f5dd3064-bb37-41e2-8092-362f4cd56c57/lesson/decaf28b-10ff-4c9b-b107-b0156645592d" />

  <Card title="Practice Lab" icon="flask-conical" cta="Learn more" href="https://learn.kodekloud.com/user/courses/kyverno-certified-associate/module/f5dd3064-bb37-41e2-8092-362f4cd56c57/lesson/a382ed07-7980-462f-a6d2-affbaccb313c" />
</CardGroup>
