github.com/wmuizelaar/kpt@v0.0.0-20221018115725-bd564717b2ed/site/book/07-effective-customizations/02-limiting-package-changes.md (about) 1 ## Scenario: 2 3 I’d like to limit what my package consumers can do with my package and it feels 4 safer to just provide a string replacement in one place so they know not to 5 alter the configuration outside of the few places that I designated as OK 6 places to change. 7 8 Example deployment: 9 ```yaml 10 apiVersion: apps/v1 11 kind: Deployment 12 metadata: # kpt-merge: /nginx-deploy 13 name: nginx-deploy 14 spec: 15 selector: 16 matchLabels: 17 app: nginx 18 template: 19 metadata: 20 labels: 21 app: nginx 22 spec: 23 containers: 24 - name: backend 25 image: nginx:1.16.1 # kpt-set: nginx:${tag} 26 ``` 27 28 kpt configuration that uses a setter: 29 ```yaml 30 apiVersion: kpt.dev/v1 31 kind: Kptfile 32 metadata: 33 name: dont-change-much 34 pipeline: 35 mutators: 36 - image: gcr.io/kpt-fn/apply-setters:v0.2.0 37 configMap: 38 tag: 1.21 39 ``` 40 41 ## Problems: 42 43 1. The limitation by parameters does not guarantee that consumers are in fact 44 going to limit their changes to the parameters. A popular pattern is using 45 kustomize to change output of other tools no matter what parameters had. In 46 this particular case I am able to fork or patch this package and add: 47 48 ```yaml 49 securityContext: 50 runAsNonRoot: false 51 ``` 52 53 2. String replacements rarely describe the intent of the package author. 54 When additional resources are added I need additional places where parameters 55 need to be applied. I can easily add other containers to this deployment and 56 the package author's rules are not clear and not easily validated. 57 58 ## Solutions: 59 60 1. General ways to describe policy already exist. kpt has a [gatekeeper] 61 function that allows the author to describe intended limitations for a class 62 of resources or the entire package giving the consumer the freedom to customize 63 and get an error or a warning when the policy is violated. 64 65 In the sample provided by the function we see how to provide a policy that will 66 clearly describe the intent using rego: 67 68 ```yaml 69 apiVersion: templates.gatekeeper.sh/v1 70 kind: ConstraintTemplate 71 metadata: # kpt-merge: /disallowroot 72 name: disallowroot 73 spec: 74 crd: 75 spec: 76 names: 77 kind: DisallowRoot 78 targets: 79 - target: admission.k8s.gatekeeper.sh 80 rego: |- 81 package disallowroot 82 violation[{"msg": msg}] { 83 not input.review.object.spec.template.spec.securityContext.runAsNonRoot 84 msg := "Containers must not run as root" 85 } 86 --- 87 apiVersion: constraints.gatekeeper.sh/v1beta1 88 kind: DisallowRoot 89 metadata: # kpt-merge: /disallowroot 90 name: disallowroot 91 spec: 92 match: 93 kinds: 94 - apiGroups: 95 - 'apps' 96 kinds: 97 - Deployment 98 ``` 99 100 The Kptfile can enforce that resources comply with this policy every time 101 `kpt fn render` is used: 102 103 ```yaml 104 apiVersion: kpt.dev/v1 105 kind: Kptfile 106 metadata: 107 name: gatekeeper-disallow-root-user 108 pipeline: 109 validators: 110 - image: gcr.io/kpt-fn/gatekeeper:v0.2 111 ``` 112 113 [gatekeeper]: https://catalog.kpt.dev/gatekeeper/v0.2/