{"id":15192050,"url":"https://github.com/arikkfir/kude","last_synced_at":"2025-10-27T14:31:19.918Z","repository":{"id":38036728,"uuid":"457075014","full_name":"arikkfir/kude","owner":"arikkfir","description":"Kubernetes Deployments","archived":false,"fork":false,"pushed_at":"2023-10-14T19:04:33.000Z","size":462,"stargazers_count":3,"open_issues_count":3,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-01T06:31:46.350Z","etag":null,"topics":["devops","devops-pipeline","devops-tools","k8s","k8s-deployment","kubernetes","kubernetes-deployment"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arikkfir.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"arikkfir","patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2022-02-08T19:29:52.000Z","updated_at":"2022-08-07T14:03:54.000Z","dependencies_parsed_at":"2024-06-19T11:23:55.456Z","dependency_job_id":"84013f99-edf2-4aa4-9cb5-ca626b8295f2","html_url":"https://github.com/arikkfir/kude","commit_stats":{"total_commits":183,"total_committers":1,"mean_commits":183.0,"dds":0.0,"last_synced_commit":"2887ca92d9f4475fc5014c365375962b5b36d7cd"},"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arikkfir%2Fkude","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arikkfir%2Fkude/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arikkfir%2Fkude/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arikkfir%2Fkude/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arikkfir","download_url":"https://codeload.github.com/arikkfir/kude/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238508868,"owners_count":19484215,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["devops","devops-pipeline","devops-tools","k8s","k8s-deployment","kubernetes","kubernetes-deployment"],"created_at":"2024-09-27T21:04:08.251Z","updated_at":"2025-10-27T14:31:19.560Z","avatar_url":"https://github.com/arikkfir.png","language":"Go","funding_links":["https://github.com/sponsors/arikkfir"],"categories":[],"sub_categories":[],"readme":"# kude\n\n![Maintainer](https://img.shields.io/badge/maintainer-arikkfir-blue)\n![GoVersion](https://img.shields.io/github/go-mod/go-version/arikkfir/kude.svg)\n[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://godoc.org/github.com/arikkfir/kude)\n[![GoReportCard](https://goreportcard.com/badge/github.com/arikkfir/kude)](https://goreportcard.com/report/github.com/arikkfir/kude)\n[![codecov](https://codecov.io/gh/arikkfir/kude/branch/main/graph/badge.svg?token=QP3OAILB25)](https://codecov.io/gh/arikkfir/kude)\n\nKude (**Ku**bernetes **De**ployment) is a tool for deploying Kubernetes applications. It stands on the shoulders of\ngiants such as [kustomize](https://kustomize.io/), [kpt](https://kpt.dev/) and [helm](https://helm.sh/), but unifies\nthem to one coherent model, while drawing the best features into one cohesive tool.\n\n👉 [Yeah yeah, just take me to an example, I can figure it out!](#Example)\n\nKude is built as a pipeline, which starts by reading a set of resources, processing them by invoking a chain of\nfunctions (more on that below), and producing an output of resources; those can be the same resources, usually enriched\nin some way, and potentially new resources as well.\n\nEach such \"pipeline\" is called a Kude Package - basically a directory with a `kude.yaml` file that describes the process\nand optionally an additional set of Kubernetes manifests used by that pipeline. Kude packages can also include external\nresources - local or remote. Those resources (referred to in the `kude.yaml` file) can be simple Kubernetes manifests,\nHelm charts, or even other Kude packages. All of those can be either local or remote.\n\nThe pipeline functions are where the magic happens - each function receives the set of resources read so far, and is\nresponsible for doing some kind of manipulation - either enriching them, or producing new ones. The function's output\nwill be provided as input to the next function, and so forth. What makes Kude so extensible is the fact that each\nfunction is a Docker image! This allows anyone to write Kude functions using any tool, language or method one wants!\n\n### High level features\n\n- Package inheritance \u0026 composition\n  - Similar to Kustomize's overlay concept\n  - Supports:\n    - Local files\n    - Git repositories\n    - Remote directory/file URLs\n    - Other Kude packages (local \u0026 remote)\n    - [More](https://github.com/hashicorp/go-getter)!\n- Name hashes for `ConfigMap` and `Secret` resources\n  - This is a useful feature introduced in `kustomize`, where the name of a `ConfigMap` or `Secret` is suffixed with a\n    hash (computed from its contents). Other resources referencing that `ConfigMap` or `Secret` are updaed to correctly\n    reference the hashed-name. \n  - By doing this, whenever the contents of such `ConfigMap` or `Secret` are changed, their hash suffix (and hence their\n    name) would change as well, resulting in a reload of the dependent pods.\n- Extensible!\n  - Kude packages are a pipeline of functions\n  - Each function is just a Docker image adhering to a very (very!) simple contract (see below)\n  - You can use any Kude function you want, and you can even write your own!\n- Team player!\n  - Can work with existing technologies such as Helm, Kustomize (coming soon!) and Kpt (coming soon!)\n  - Works with `kubectl` easily - just run `kude | kubectl apply -f -` to deploy!\n- Growing functions catalog\n  - [See the catalog](#Kude-Functions-Catalog)\n\n## Status\n\nThis is currently alpha, with some features still in development, and not full test coverage. We're on it! 💪\n\n## Example\n\nGiven this directory structure:\n```\n└── my-kude-package\n    ├── kude.yaml\n    ├── deployment.yaml\n    └── service.yaml\n```\n\nThe `kude.yaml` contains:\n```yaml\napiVersion: kude.kfirs.com/v1alpha2\nkind: Pipeline\nresources:\n  # Define two local input resources:\n  - deployment.yaml\n  - service.yaml\nsteps:\n  # Define just one function to process resources\n  # It will add an annotation to each resource\n  - image: ghcr.io/arikkfir/kude/functions/annotate\n    config:\n      name: purpose\n      value: kude-example\n```\n\nThe `deployment.yaml` contains:\n```yaml\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: super-microservice\nspec:\n  selector:\n    matchLabels:\n      app.kubernetes.io/name: super-microservice\n  template:\n    metadata:\n      labels:\n        app.kubernetes.io/name: super-microservice\n    spec:\n      containers:\n        - image: \"examples/super-microservice:v1\"\n          name: microservice\n          ports:\n            - containerPort: 8080\n```\n\nThe `service.yaml` contains:\n```yaml\napiVersion: v1\nkind: Service\nmetadata:\n  name: super-microservice\nspec:\n  ports:\n    - name: http\n      port: 80\n      targetPort: 8080\n  selector:\n    app.kubernetes.io/name: test\n```\n\nRun `kude` to generate the following resources:\n```shell\n/home/test/my-kude-package: $ kude build\n```\n\nExpect the following output (notice the annotations for each resource):\n\n```yaml\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  annotations:\n    purpose: kude-example # \u003c-- ANNOTATED!\n  name: super-microservice\nspec:\n  selector:\n    matchLabels:\n      app.kubernetes.io/name: super-microservice\n  template:\n    metadata:\n      labels:\n        app.kubernetes.io/name: super-microservice\n    spec:\n      containers:\n        - image: \"examples/super-microservice:v1\"\n          name: microservice\n          ports:\n            - containerPort: 8080\n---\napiVersion: v1\nkind: Service\nmetadata:\n  annotations:\n    purpose: kude-example # \u003c-- ANNOTATED!\n  name: super-microservice\nspec:\n  ports:\n    - name: http\n      port: 80\n      targetPort: 8080\n  selector:\n    app.kubernetes.io/name: test\n```\n\n## Configuration\n\n### Targeting\n\nOften in a pipeline, you would want a function to only apply its effects to a subset of the resources. For example, to\nadd an Ingress annotation only to `Ingress` objects. This can be done like so:\n\n```yaml\napiVersion: kude.kfirs.com/v1alpha2\nkind: Pipeline\nresources:\n  ...\nsteps:\n  - image: ghcr.io/arikkfir/kude/functions/annotate\n    config:\n      name: foo1\n      value: bar1\n      includes:\n        - apiVersion: v1 # \u003c-- only apply to objects in this API group\n          kind: Secret  # \u003c-- and only apply to objects of type Secret\n      excludes:\n        - name: guarded-secret # \u003c-- but do not annotate any object named \"guarded-secret\" \n  - image: ghcr.io/arikkfir/kude/functions/annotate\n    config:\n      name: foo2\n      value: bar2\n      includes:\n        - apiVersion: v1 # \u003c-- only apply to objects in this API group\n          kind: Secret  # \u003c-- and only apply to objects of type Secret\n          name: my-secret # \u003c-- and only apply to objects with this name \n  - image: ghcr.io/arikkfir/kude/functions/annotate\n    config:\n      name: foo3\n      value: bar3\n      includes:\n        - apiVersion: v1 # \u003c-- only apply to objects in this API group\n          kind: Secret  # \u003c-- and only apply to objects of type Secret\n          name: my-secret # \u003c-- and only apply to objects with this name \n          namespace: my-namespace # \u003c-- and only in this namespace\n  - image: ghcr.io/arikkfir/kude/functions/annotate\n    config:\n      name: foo4\n      value: bar4\n      includes:\n        - apiVersion: v1 # \u003c-- only apply to objects in this API group\n          kind: Secret  # \u003c-- and only apply to objects of type Secret\n          name: my-secret # \u003c-- and only apply to objects with this name \n          namespace: my-namespace # \u003c-- and only in this namespace\n          labelSelector: app=my-app # \u003c-- and only to objects with label 'app' equaling 'my-app'\n```\n\nEach one of the properties in the `includes` array is optional, but at least one of them must be specified. The format\nfor the `excludes` array is the same as for `includes`, and also requires at least one of the properties to be\nspecified.\n\nTargeting will only match objects that match at least one of the filters in the `includes` array, and do not match any\nof the filters in the `excludes` array. If the `includes` array is empty, all objects will be matched (but the\n`excludes` array will still be applied). If the `excludes` array is empty, only objects in the `includes` array will be\nmatched (or all, if the `includes` array is empty as well).\n\n### Mounting local files\n\nSome function configuration values might need to come from local files, rather than hard-coded into the pipelines. This\ncan be useful for reusing the same values across multiple functions or even multiple packages, as well as for providing\nsecrets.\n\nLuckily Kude makes this super easy! Here's how:\n\n```yaml\napiVersion: kude.kfirs.com/v1alpha2\nkind: Pipeline\nresources:\n  ...\nsteps:\n  - image: ghcr.io/arikkfir/kude/functions/annotate\n    config:\n      name: purpose1\n      path: purpose.txt\n    mounts:\n      - purpose.txt # \u003c-- local file called \"purpose.txt\" will be mounted to the function as \"/workspace/purpose.txt\"\n  - image: ghcr.io/arikkfir/kude/functions/annotate\n    config:\n      name: purpose2\n      path: a-file\n    mounts:\n      - purpose.txt:a-file # \u003c-- local file called \"purpose.txt\" will be mounted to the function as \"/workspace/a-file\"\n  - image: ghcr.io/arikkfir/kude/functions/annotate\n    config:\n      name: purpose3\n      path: /tmp/my-file\n    mounts:\n      - purpose.txt:/tmp/my-file # \u003c-- local file called \"purpose.txt\" will be mounted to the function as \"/tmp/my-file\"\n```\n\n## Kude Functions\n\nThe following functions are available:\n\n- [annotate](./cmd/functions/annotate/README.md) - Annotate Kubernetes resources with metadata\n- [create-configmap](cmd/functions/create-configmap/README.md) - Generate a Kubernetes ConfigMap\n- [create-namespace](cmd/functions/create-namespace/README.md) - Generate a Kubernetes namespace\n- [create-secret](cmd/functions/create-secret/README.md) - Generate a Kubernetes Secret\n- [helm](./cmd/functions/helm/README.md) - Invoke Helm for any purpose (mainly used for `helm template ...` command)\n- [label](./cmd/functions/label/README.md) - Label Kubernetes resources\n- [set-namespace](./cmd/functions/set-namespace/README.md) - Set namespace for resources.\n- [yq](./cmd/functions/yq/README.md) - Patch resources using `yq`\n\n## Writing Kude Functions\n\nUntil we document this, please see the functions [source code](./cmd/functions).\n\n## Contributing\n\nWe welcome any contributions from the community - help us out! Have a look at our \n[contribution guide](.github/CONTRIBUTING.md) for more information on how to get started on sending your first PR.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farikkfir%2Fkude","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farikkfir%2Fkude","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farikkfir%2Fkude/lists"}