> ## 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 Match Statements

> Demonstrates Kyverno match blocks to enforce non-empty env label on Pods and Deployments, and how to scope the rule to specific namespaces

This guide demonstrates how Kyverno `match` blocks control which resources a policy evaluates. We'll enforce that Pods and Deployments include a non-empty `env` label using a ClusterPolicy, then refine the rule to target a specific namespace.

## Policy: require an `env` label

Create the following ClusterPolicy to validate that `metadata.labels.env` exists and is non-empty for Pods and Deployments:

```yaml theme={null}
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: check-label-env
spec:
  validationFailureAction: enforce
  rules:
    - name: check-label-env
      match:
        any:
          - resources:
              kinds:
                - Pod
                - Deployment
      validate:
        message: "The label `env` is required."
        pattern:
          metadata:
            labels:
              env: "?*"
```

The key parts:

* `match` selects which resources Kyverno evaluates (here: kinds Pod and Deployment).
* `validate.pattern` enforces the presence and a non-empty value for `metadata.labels.env`.

<Callout icon="lightbulb" color="#1CB2FE">
  The `?*` pattern in Kyverno matches any non-empty string, ensuring the `env` label exists and is not empty.
</Callout>

<Callout icon="warning" color="#FF6B6B">
  This policy uses `validationFailureAction: enforce`, which will block resource creation or updates that don't meet the rule. Use `audit` if you prefer non-blocking checks.
</Callout>

## Apply the policy

Apply the policy manifest and verify the ClusterPolicy is ready:

```bash theme={null}
kubectl apply -f check-label.yaml
kubectl get cpol check-label-env
# NAME              ADMISSION   BACKGROUND   READY   AGE    MESSAGE
# check-label-env   true        true         true    10s    Ready
```

## Test the policy

1. Create a Pod without labels (expected: rejected, because Pod is matched by the rule):

```bash theme={null}
kubectl run my-pod --image=nginx
```

Example admission webhook response:

```text theme={null}
Error from server: admission webhook "validate.kyverno.svc" denied the request:
resource Pod/default/my-pod was blocked due to the following policies

check-label-env:
  check-label-env: validation error: The label `env` is required. rule check-label-env
```

2. Create a Deployment without the `env` label (expected: rejected):

```bash theme={null}
kubectl create deployment my-deployment --image=nginx
```

Example error:

```text theme={null}
error: failed to create deployment: admission webhook "validate.kyverno.svc" denied the request:
resource Deployment/default/my-deployment was blocked due to the following policies

check-label-env:
  check-label-env: validation error: The label `env` is required. rule check-label-env failed at path /metadata/labels/env/
```

3. Create a Pod with the `env` label (expected: allowed):

```bash theme={null}
kubectl run my-pod --image=nginx --labels=env=dev
# pod/my-pod created
```

These steps confirm the policy enforces the `env` label for the matched kinds.

## Scope the rule to a namespace

You can narrow the `match` block to specific namespaces. The example below restricts enforcement to the `restricted-ns` namespace:

```yaml theme={null}
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: check-label-env
spec:
  validationFailureAction: enforce
  rules:
    - name: check-label-env
      match:
        any:
          - resources:
              kinds:
                - Pod
                - Deployment
              namespaces:
                - restricted-ns
      validate:
        message: "The label `env` is required."
        pattern:
          metadata:
            labels:
              env: "?*"
```

Apply the updated policy and create the namespace:

```bash theme={null}
kubectl apply -f check-label.yaml
kubectl create namespace restricted-ns
# namespace/restricted-ns created
```

Test the namespace-scoped behavior:

* Create a Pod in `restricted-ns` without labels (expected: rejected):

```bash theme={null}
kubectl run my-pod --image=nginx -n restricted-ns
```

Example webhook response:

```text theme={null}
Error from server: admission webhook "validate.kyverno.svc" denied the request:
resource Pod/restricted-ns/my-pod was blocked due to the following policies

check-label-env:
  check-label-env: validation error: The label `env` is required. rule check-label-env failed at path /metadata/labels/env/
```

* Create a Pod in the `default` namespace without labels (expected: allowed, because it doesn't match the `namespaces` filter):

```bash theme={null}
kubectl run test-pod --image=nginx
# pod/test-pod created
```

## Quick reference

| Topic              | Behavior                                       | Example command                              |
| ------------------ | ---------------------------------------------- | -------------------------------------------- |
| Match by kind      | Targets resources by kind (Pod, Deployment)    | `match: resources.kinds: - Pod - Deployment` |
| Match by namespace | Further restricts scope to specific namespaces | `namespaces: - restricted-ns`                |
| Validation pattern | Enforces non-empty `env` label                 | `metadata.labels.env: "?*"`                  |
| Apply policy       | Install or update ClusterPolicy                | `kubectl apply -f check-label.yaml`          |

## Summary

* Use the `match` block to control which resources Kyverno evaluates (kinds, namespaces, selectors).
* Use `validate.pattern` to require fields—`?*` ensures a string is present and non-empty.
* Adding `namespaces` to `match` scopes enforcement to specific namespaces (e.g., `restricted-ns`) while leaving other namespaces unaffected.

## Links and references

* [Kyverno Documentation](https://kyverno.io/)
* [Kubernetes Documentation](https://kubernetes.io/docs/)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/kyverno-certified-associate/module/65cbd27d-801d-4468-b4c5-47391c833127/lesson/b2e99306-7378-4cf1-93b0-d6f2b3031f2e" />

  <Card title="Practice Lab" icon="flask-conical" cta="Learn more" href="https://learn.kodekloud.com/user/courses/kyverno-certified-associate/module/65cbd27d-801d-4468-b4c5-47391c833127/lesson/a8ce8906-5078-4c36-9fd2-eb27504c3b04" />
</CardGroup>
