Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add shallow substitution docs #1377

Merged
merged 5 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/check-links.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
with:
fail: true
debug: false
args: --no-progress --include-fragments --github-token ${{secrets.GITHUB_TOKEN}} -c lychee.toml -E content/
args: --no-progress --include-fragments --github-token ${{secrets.GITHUB_TOKEN}} --config config/lychee.toml -E content/

# Deactivated. The --include-fragments flag is causing failures because rendered links
# have a trailing '#' which is probably a result of the link style change plus the new
Expand Down
File renamed without changes.
77 changes: 76 additions & 1 deletion content/en/docs/writing-policies/variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ weight: 90

Variables make policies smarter and reusable by enabling references to data in the policy definition, the [admission review request](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#webhook-request-and-response), and external data sources like ConfigMaps, the Kubernetes API Server, OCI image registries, and even external service calls.

In Kyverno, you can use the double braces syntax e.g., `{{ ... }}`, to reference a variable. For variables in policy declarations the `$( ... )` syntax is used instead.

Variables are stored as JSON and Kyverno supports using [JMESPath](http://jmespath.org/) (pronounced "James path") to select and transform JSON data. With JMESPath, values from data sources are referenced in the format of `{{key1.key2.key3}}`. For example, to reference the name of an new/incoming resource during a `kubectl apply` action such as a Namespace, you would write this as a variable reference: `{{request.object.metadata.name}}`. The policy engine will substitute any values with the format `{{ <JMESPath> }}` with the variable value before processing the rule. For a page dedicated to exploring JMESPath's use in Kyverno see [here](jmespath.md). Variables may be used in most places in a Kyverno rule or policy with one exception being in `match` or `exclude` statements.

## Pre-defined Variables
Expand Down Expand Up @@ -172,7 +174,7 @@ The result of the mutation of this Pod with respect to the `OTEL_RESOURCE_ATTRIB
rule_applied=imbue-pod-spec
```

### Variables in Helm
## Variables in Helm

Both Kyverno and Helm use Golang-style variable substitution syntax and, as a result, Kyverno policies containing variables deployed through Helm may need to be "wrapped" to avoid Helm interpreting them as Helm variables.

Expand All @@ -196,6 +198,7 @@ value: {{ `"{{ element.securityContext.capabilities.drop[].to_upper(@) || `}}`[]

in order to render properly.


## Variables from admission review requests

Kyverno operates as a webhook inside Kubernetes. Whenever a new request is made to the Kubernetes API server, for example to create a Pod, the API server sends this information to the webhooks registered to listen to the creation of Pod resources. This incoming data to a webhook is passed as a [`AdmissionReview`](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#webhook-request-and-response) object. There are four commonly used data properties available in any AdmissionReview request:
Expand Down Expand Up @@ -482,6 +485,78 @@ spec:

In this example, AdmissionReview data is first collected in the inner expression in the form of `{{request.object.metadata.labels.app}}` while the outer expression is built from a ConfigMap context named `LabelsCM`.


## Shallow substitution

By default, Kyverno performs nested substitution of variables. However, in some cases, nested substitution may not be desireable.

The syntax `{{- ... }}` can be used for shallow (one time only) substitution of variables.

Here is a more detailed example.

Consider a policy that loads a ConfigMap that contains [HCL](https://developer.hashicorp.com/terraform/language/syntax/configuration) synytax data, and patches resource configurations:

Policy:

```yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: vault-auth-backend
spec:
validationFailureAction: Audit
background: true
mutateExistingOnPolicyUpdate: true
rules:
- name: vault-injector-config-blue-to-green-auth-backend
context:
- name: hcl
variable:
jmesPath: replace_all( '{{ request.object.data.config }}', 'from_string','to_string')
match:
any:
- resources:
kinds:
- ConfigMap
names:
- test-*
namespaces:
- corp-tech-ap-team-ping-ep
mutate:
patchStrategicMerge:
data:
config: '{{- hcl }}'
targets:
- apiVersion: v1
kind: ConfigMap
name: '{{ request.object.metadata.name }}'
namespace: '{{ request.object.metadata.namespace }}'
name: vault-injector-config-blue-to-green-auth-backend
```

ConfigfMap:

```yaml
apiVersion: v1
data:
config: |-
from_string
{{ some hcl tempalte }}
kind: ConfigMap
metadata:
annotations:
labels:
argocd.development.cpl.<removed>.co.at/app: corp-tech-ap-team-ping-ep
name: vault-injector-config-http-echo
namespace: corp-tech-ap-team-ping-ep

```

In this case, since HCL also uses the `{{ ... }}` variable syntax, Kyverno needs to be instructed to not attempt to resolve variables in the HCL.

To only substitute the rule data with the HCL, and not perform nested subsitutions, the declaration `'{{- hcl }}'` uses the shallow substitution syntax.


## Evaluation Order

Kyverno policies can contain variables in:
Expand Down