From 8d4e58e21e15f0a65a6dad5b3dac089b2285559f Mon Sep 17 00:00:00 2001 From: Kent Rancourt Date: Fri, 4 Oct 2024 16:51:10 -0400 Subject: [PATCH] docs: document built-in promotion steps (#2640) Signed-off-by: Kent Rancourt --- docs/docs/15-concepts.md | 170 +-- docs/docs/20-quickstart.md | 20 +- docs/docs/35-references/10-promotion-steps.md | 1140 +++++++++++++++++ docs/docs/35-references/_category_.json | 4 + 4 files changed, 1221 insertions(+), 113 deletions(-) create mode 100644 docs/docs/35-references/10-promotion-steps.md create mode 100644 docs/docs/35-references/_category_.json diff --git a/docs/docs/15-concepts.md b/docs/docs/15-concepts.md index 4fd198435..bb10be0f7 100644 --- a/docs/docs/15-concepts.md +++ b/docs/docs/15-concepts.md @@ -154,7 +154,7 @@ A `Stage` resource's `spec` field decomposes into three main areas of concern: * Requested freight -* Promotion mechanisms +* Promotion template * Verification @@ -163,10 +163,11 @@ The following sections will explore each of these in greater detail. #### Requested Freight The `spec.requestedFreight` field is used to describe one or more "types" of -`Freight`, as specified by an `origin`, that the `Stage`'s promotion mechanisms -will operate on, and the acceptable sources from which to obtain that `Freight`. -Those sources may include the origin itself (e.g. a `Warehouse`) and/or any -number of "upstream" `Stage` resources. +`Freight`, as specified by an `origin`, that the `Stage`'s promotion process, as +specified by `spec.promotionTemplate`, will operate on, and the acceptable +sources from which to obtain that `Freight`. Those sources may include the +origin itself (e.g. a `Warehouse`) and/or any number of "upstream" `Stage` +resources. :::info `Warehouse`s are the only type of origin at present, but it is anticipated that @@ -267,118 +268,81 @@ the delivery of microservices that are developed and deployed in parallel, although other uses of this feature are anticipated in the future. ::: -#### Promotion Mechanisms +#### Promotion Templates -The `spec.promotionMechanisms` field is used to describe _how_ to transition -`Freight` into the `Stage`. +The `spec.promotionTemplate` field is used to describe _how_ to transition +`Freight` into the `Stage`. The `spec.promotionTemplate.steps` field describes +the discrete steps of a promotion process in detail. -There are two general methods of accomplishing this: +In the following, very common example, the `promotionTemplate` describes steps +to: -* Committing changes to a GitOps repository. +1. Clone a Git repository containing Kubernetes manifests and Kustomize + configuration, checking out two different branches to two different + directories. -* Making changes to an Argo CD `Application` resource. (Often, the only change - is to force a sync and refresh of the `Application`.) +1. Clears the contents of one working tree, with intentions to fully replace its + contents. -These two approaches are, in many cases, used in conjunction with one another. -The Kargo controller always applies Git-based promotion mechanisms first _then_ -Argo CD-based promotion mechanisms. +1. Runs the equivalent of `kustomize edit set image` to update a + `kustomization.yaml` file with a reference to an updated + `public.ecr.aws/nginx/nginx` container image. -Included among the Git-based promotion mechanisms is specialized support for: +1. Renders the updated manifests using the equivalent of `kustomize build`. -* Running `kustomize edit set image` for specific images in specified - directories to update the version of that image used, then committing the - changes, if any. +1. Commits the updated manifests and pushes them to the `stage/test` of the + remote repository. -* Updating the values of a keys in Helm values files to reference new versions - of specific images, then committing the changes, if any. - -* Updating `Chart.yaml` files in Helm charts to reference new versions of - specific chart dependencies, then committing the changes, if any. - -And among the Argo CD-based promotion mechanisms, there is specialized support -for: - -* Updating the `kustomize.images` section of a specified Argo CD `Application` - resource to reference new versions of specific images. - -* Updating the `helm.parameters` section of a specified Argo CD `Application` to - reference new versions of specific images. - -* Updating the `targetRevision` field of a specified Argo CD `Application` - resource to reference a specific commit in a Git repository or a specific - version of a Helm chart. - -* Forcing a specified Argo CD `Application` to refresh and sync. (This is - automatic for any `Application` resource a `Stage` interacts with.) - -:::info -Additionally, interaction with any Argo CD `Application` resources(s) as -described above implicitly results in periodic evaluation of `Stage` health by -aggregating the results of sync/health state for all such `Application` -resources(s). -::: - -:::tip -It is suggested that automatic syncing typically be disabled for Argo CD -`Application` resources that are orchestrated by Kargo. -::: - -The following example shows that transitioning `Freight` into the `test` -`Stage` requires: - -1. Updating the `https://github.com/example/kargo-demo.git` repository by - running `kustomize edit set image` in the `stages/test` directory and - committing those changes to a stage-specific `stages/test` branch. - -1. Forcing the Argo CD `Application` named `kargo-demo-test` in the `argocd` - namespace to refresh and sync. +1. Forces Argo CD to sync the `kargo-demo-test` application to the latest commit + of the `stage/test` branch. ```yaml -apiVersion: kargo.akuity.io/v1alpha1 -kind: Stage -metadata: - name: test - namespace: kargo-demo -spec: - # ... - promotionMechanisms: - gitRepoUpdates: - - repoURL: https://github.com/example/kargo-demo.git - writeBranch: stages/test - kustomize: +promotionTemplate: + spec: + steps: + - uses: git-clone + config: + repoURL: https://github.com/example/repo.git + checkout: + - fromFreight: true + path: ./src + - branch: stage/test + create: true + path: ./out + - uses: git-clear + config: + path: ./out + - uses: kustomize-set-image + as: update-image + config: + path: ./src/base images: - image: public.ecr.aws/nginx/nginx - path: stages/test - argoCDAppUpdates: - - appName: kargo-demo-test - appNamespace: argocd + - uses: kustomize-build + config: + path: ./src/stages/test + outPath: ./out + - uses: git-commit + as: commit + config: + path: ./out + messageFromSteps: + - update-image + - uses: git-push + config: + path: ./out + targetBranch: stage/test + - uses: argocd-update + config: + apps: + - name: kargo-demo-test + sources: + - repoURL: https://github.com/example/repo.git + desiredCommitFromStep: commit ``` -:::info -Promotion mechanisms can be thought of as expressing, "when I see this kind of -artifact, I want to do this kind of thing with it." Because `Stage` resources -may request different kinds of `Freight` from different sources, it is possible -that, at times, there may be ambiguity over _what version_ of a given artifact -a promotion mechanism should operate on. - -Consider, for instance, the case of two `Warehouse` resources, both subscribed -to the _same_ GitOps monorepo, but each using different `includePaths` to -effectively subscribe to manifest changes for only a single microservice. A -`Stage` that requests `Freight` having originated from _both_ `Warehouses` will, -when describing promotion mechanisms that operate on commits from the monorepo, -need to specify whether to operate on the commit found by one `Warehouse` and -included in one of the requested pieces of `Freight`, or the commit found by the -other `Warehouse` and included in the _other_ requested piece of `Freight`. - -To this end, all promotion mechanisms accept `origin.kind` and `origin.name` -fields to permit this kind of disambiguation. These fields need not be specified -when there is no possible ambiguity, but they become required when Kargo can not -infer, on its own, the correct artifact on which to operate. - -To prevent disambiguation from becoming overly burdensome in such cases, all -"child" promotion mechanisms also inherit `origin` settings from their parent -promotion mechanism and may also override them as necessary. -::: +__For complete documentation of all of Kargo's built-in promotion steps, refer +to the [Promotion Steps Reference](./35-references/10-promotion-steps.md).__ #### Verifications diff --git a/docs/docs/20-quickstart.md b/docs/docs/20-quickstart.md index 773e3c334..755a113a0 100644 --- a/docs/docs/20-quickstart.md +++ b/docs/docs/20-quickstart.md @@ -359,7 +359,7 @@ the previous section. repoURL: ${GITOPS_REPO_URL} checkout: - branch: main - path: ./main + path: ./src - branch: stage/test create: true path: ./out @@ -369,12 +369,12 @@ the previous section. - uses: kustomize-set-image as: update-image config: - path: ./main/base + path: ./src/base images: - image: public.ecr.aws/nginx/nginx - uses: kustomize-build config: - path: ./main/stages/test + path: ./src/stages/test outPath: ./out/manifests.yaml - uses: git-commit as: commit @@ -415,7 +415,7 @@ the previous section. repoURL: ${GITOPS_REPO_URL} checkout: - branch: main - path: ./main + path: ./src - branch: stage/uat create: true path: ./out @@ -425,12 +425,12 @@ the previous section. - uses: kustomize-set-image as: update-image config: - path: ./main/base + path: ./src/base images: - image: public.ecr.aws/nginx/nginx - uses: kustomize-build config: - path: ./main/stages/test + path: ./src/stages/test outPath: ./out/manifests.yaml - uses: git-commit as: commit @@ -471,7 +471,7 @@ the previous section. repoURL: ${GITOPS_REPO_URL} checkout: - branch: main - path: ./main + path: ./src - branch: stage/prod create: true path: ./out @@ -481,12 +481,12 @@ the previous section. - uses: kustomize-set-image as: update-image config: - path: ./main/base + path: ./src/base images: - image: public.ecr.aws/nginx/nginx - uses: kustomize-build config: - path: ./main/stages/test + path: ./src/stages/test outPath: ./out/manifests.yaml - uses: git-commit as: commit @@ -792,7 +792,7 @@ the previous section. "commit": "707412fa2be1aae72767c0acb652684c233a2802" }, "update-image": { - "commitMessage": "Updated ./main/base to use new image\n\n- public.ecr.aws/nginx/nginx:1.27.1" + "commitMessage": "Updated ./src/base to use new image\n\n- public.ecr.aws/nginx/nginx:1.27.1" } } } diff --git a/docs/docs/35-references/10-promotion-steps.md b/docs/docs/35-references/10-promotion-steps.md new file mode 100644 index 000000000..0986ad338 --- /dev/null +++ b/docs/docs/35-references/10-promotion-steps.md @@ -0,0 +1,1140 @@ +--- +sidebar_label: Promotion Steps Reference +description: Learn about all of Kargo's built-in promotion steps +--- + +# Promotion Steps Reference + +This reference document describes the promotion steps that are built directly +into Kargo. Steps are presented roughly in the order in which they might appear +in a typical promotion process. Similarly, configuration options for each step +are laid out in order of their applicability to typical use cases. + +## `git-clone` + +`git-clone` is often the first step in a promotion process. It creates a +[bare clone](https://git-scm.com/docs/git-clone#Documentation/git-clone.txt-code--barecode) +of a remote Git repository, then checks out one or more branches, tags, or +commits to working trees at specified paths. Checking out different revisions to +different paths is useful for the common scenarios of combining content from +multiple sources or rendering Stage-specific manifests to a Stage-specific +branch. + +:::note +It is a noteworthy limitation of Git that one branch cannot be checked out in +multiple working trees. +::: + +### `git-clone` Configuration + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `repoURL` | `string` | Y | The URL of a remote Git repository to clone. | +| `insecureSkipTLSVerify` | `boolean` | N | Whether to bypass TLS certificate verification when cloning (and for all subsequent operations involving this clone). Setting this to `true` is highly discouraged in production. | +| `checkout` | `[]object` | Y | The commits, branches, or tags to check out from the repository and the paths where they should be checked out. At least one must be specified. | +| `checkout[].branch` | `string` | N | A branch to check out. Mutually exclusive with `tag` and `fromFreight=true`. If none of these is specified, the default branch will be checked out. | +| `checkout[].create` | `boolean` | N | In the event `branch` does not already exist on the remote, whether a new, empty, orphaned branch should be created. Default is `false`, but should commonly be set to `true` for Stage-specific branches, which may not exist yet at the time of a Stage's first promotion. | +| `checkout[].tag` | `string` | N | A tag to check out. Mutually exclusive with `branch` and `fromFreight=true`. If none of these is specified, the default branch will be checked out. | +| `checkout[].fromFreight` | `boolean` | N | Whether a commit to check out should be obtained from the Freight being promoted. A value of `true` is mutually exclusive with `branch` and `tag`. If none of these is specified, the default branch will be checked out. Default is `false`, but is often set to `true`. | +| `checkout[].fromOrigin` | `object` | N | See [specifying origins](#specifying-origins). | +| `checkout[].path` | `string` | Y | The path for a working tree that will be created from the checked out revision. This path is relative to the temporary workspace that Kargo provisions for use by the promotion process. | + +### `git-clone` Examples + + + + + +The most common usage of this step is to check out a commit specified by the +Freight being promoted as well as a Stage-specific branch. Subsequent steps are +likely to perform actions that revise the contents of the Stage-specific branch +using the commit from the Freight as input. + +```yaml +steps: +- uses: git-clone + config: + repoURL: https://github.com/example/repo.git + checkout: + - fromFreight: true + path: ./src + - branch: stage/test + create: true + path: ./out +# Prepare the contents of ./out ... +# Commit, push, etc... +``` + + + + + +For this more advanced example, consider a Stage that requests Freight from two +Warehouses, where one provides Kustomize "base" configuration, while the other +provides a Stage-specific Kustomize overlay. Rendering the manifests intended +for such a Stage will require combining the base and overlay configurations +with the help of a [`copy`](#copy) step. For this case, a `git-clone` step may be +configured similarly to the following: + +```yaml +steps: +- uses: git-clone + config: + repoURL: https://github.com/example/repo.git + checkout: + - fromFreight: true + fromOrigin: + kind: Warehouse + name: base + path: ./src + - fromFreight: true + fromOrigin: + kind: Warehouse + name: test-overlay + path: ./overlay + - branch: stage/test + create: true + path: ./out +- uses: git-clear + config: + path: ./out +- uses: copy + config: + inPath: ./overlay/stages/test/kustomization.yaml + outPath: ./src/stages/test/kustomization.yaml +- uses: kustomize-build + config: + path: ./src/stages/test + outPath: ./out +# Commit, push, etc... +``` + + + + + +## `git-clear` + +`git-clear` deletes the _the entire contents_ of a specified Git working tree +(except for the `.git` file). It is equivalent to executing +`git add . && git rm -rf --ignore-unmatch .`. This step is useful for the common +scenario where the entire content of a Stage-specific branch is to be replaced +with content from another branch or with content rendered using some +configuration management tool. + +### `git-clear` Configuration + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `path` | `string` | Y | Path to a Git working tree whose entire contents are to be deleted. | + +### `git-clear` Example + +```yaml +steps: +- uses: git-clone + config: + repoURL: https://github.com/example/repo.git + checkout: + - branch: stage/test + create: true + path: ./out +- uses: git-clear + config: + path: ./out +# Prepare the contents of ./out ... +# Commit, push, etc... +``` + +## `copy` + +`copy` copies files or the contents of entire directories from one specified +location to another. + +### `copy` Configuration + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `inPath` | `string` | Y | Path to the file or directory to be copied. This path is relative to the temporary workspace that Kargo provisions for use by the promotion process. | +| `outPath` | `string` | Y | Path to the destination. This path is relative to the temporary workspace that Kargo provisions for use by the promotion process. | + +### `copy` Example + +The most common (though still advanced) usage of this step is to combine content +from two working trees to use as input to a subsequent step, such as one that +renders Stage-specific manifests. + +Consider a Stage that requests Freight from two Warehouses, where one provides +Kustomize "base" configuration, while the other provides a Stage-specific +Kustomize overlay. Rendering the manifests intended for such a Stage will +require combining the base and overlay configurations: + +```yaml +steps: +- uses: git-clone + config: + repoURL: https://github.com/example/repo.git + checkout: + - fromFreight: true + fromOrigin: + kind: Warehouse + name: base + path: ./src + - fromFreight: true + fromOrigin: + kind: Warehouse + name: test-overlay + path: ./overlay + - branch: stage/test + create: true + path: ./out +- uses: git-clear + config: + path: ./out +- uses: copy + config: + inPath: ./overlay/stages/test/kustomization.yaml + outPath: ./src/stages/test/kustomization.yaml +# Render manifests to ./out, commit, push, etc... +``` + +## `kustomize-set-image` + +`kustomize-set-image` updates the `kustomization.yaml` file in a specified +directory to reflect a different revision of a container image. It is equivalent +to executing `kustomize edit set image`. This step is commonly followed by a +[`kustomize-build`](#kustomize-build) step. + +### `kustomize-set-image` Configuration + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `path` | `string` | Y | Path to a directory containing a `kustomization.yaml` file. This path is relative to the temporary workspace that Kargo provisions for use by the promotion process. | +| `images` | `[]object` | Y | The details of changes to be applied to the `kustomization.yaml` file. At least one must be specified. | +| `images[].image` | `string` | Y | Name/URL of the image being updated. The Freight being promoted presumably contains a reference to a revision of this image. | +| `images[].fromOrigin` | `object` | N | See [specifying origins](#specifying-origins). | +| `images[].newName` | `string` | N | A substitution for the name/URL of the image being updated. This is useful when different Stages have access to different container image repositories (assuming those different repositories contain equivalent images that are tagged identically). This may be a frequent consideration for users of Amazon's Elastic Container Registry. | +| `images[].useDigest` | `boolean` | N | Whether to update the `kustomization.yaml` file using the container image's digest instead of its tag. | + +### `kustomize-set-image` Examples + + + + + +```yaml +steps: +- uses: git-clone + config: + repoURL: https://github.com/example/repo.git + checkout: + - fromFreight: true + fromOrigin: + kind: Warehouse + name: base + path: ./src + - branch: stage/test + create: true + path: ./out +- uses: git-clear + config: + path: ./out +- uses: kustomize-set-image + config: + path: ./src/base + images: + - image: my/image +# Render manifests to ./out, commit, push, etc... +``` + + + + + +For this example, consider the promotion of Freight containing a reference to +some revision of the container image +`123456789012.dkr.ecr.us-east-1.amazonaws.com/my-image`. This image exists in the +`us-east-1` region of Amazon's Elastic Container Registry. However, assuming the +Stage targeted by the promotion is backed by environments in the `us-west-2` +region, it will be necessary to make a substitution when updating the +`kustomization.yaml` file. This can be accomplished like so: + +```yaml +steps: +- uses: git-clone + config: + repoURL: https://github.com/example/repo.git + checkout: + - fromFreight: true + fromOrigin: + kind: Warehouse + name: base + path: ./src + - branch: stage/test + create: true + path: ./out +- uses: git-clear + config: + path: ./out +- uses: kustomize-set-image + config: + path: ./src/base + images: + - image: 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-image + newName: 123456789012.dkr.ecr.us-west-2.amazonaws.com/my-image +# Render manifests to ./out, commit, push, etc... +``` + + + + + +### `kustomize-set-image` Output + +| Name | Type | Description | +|------|------|-------------| +| `commitMessage` | `string` | A description of the change(s) applied by this step. Typically, a subsequent [`git-commit`](#git-commit) step will reference this output and aggregate this commit message fragment with other like it to build a comprehensive commit message that describes all changes. | + +## `kustomize-build` + +`kustomize-build` renders manifests from a specified directory containing a +`kustomization.yaml` file to a specified file or to many files in a specified +directory. This step is useful for the common scenario of rendering +Stage-specific manifests to a Stage-specific branch. This step is commonly +preceded by a [`git-clear`](#git-clear) step and followed by +[`git-commit`](#git-commit) and [`git-push`](#git-push) steps. + +### `kustomize-build` Configuration + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `path` | `string` | Y | Path to a directory containing a `kustomization.yaml` file. This path is relative to the temporary workspace that Kargo provisions for use by the promotion process. | +| `outPath` | `string` | Y | Path to the file or directory where rendered manifests are to be written. If the path ends with `.yaml` or `.yml` it is presumed to indicate a file and is otherwise presumed to indicate a directory. This path is relative to the temporary workspace that Kargo provisions for use by the promotion process. | + +### `kustomize-build` Examples + + + + + +```yaml +steps: +- uses: git-clone + config: + repoURL: https://github.com/example/repo.git + checkout: + - fromFreight: true + path: ./src + - branch: stage/test + create: true + path: ./out +- uses: git-clear + config: + path: ./out +- uses: kustomize-build + config: + path: ./src/stages/test + outPath: ./out/manifests.yaml +# Commit, push, etc... +``` + + + + + +```yaml +steps: +- uses: git-clone + config: + repoURL: https://github.com/example/repo.git + checkout: + - fromFreight: true + path: ./src + - branch: stage/test + create: true + path: ./out +- uses: git-clear + config: + path: ./out +- uses: kustomize-build + config: + path: ./src/stages/test + outPath: ./out +# Commit, push, etc... +``` + + + + + +## `helm-update-image` + +`helm-update-image` updates the values of specified keys in a specified Helm +values file (e.g. `values.yaml`) to reflect a new version of a container image. +This step is useful for the common scenario of updating such a `values.yaml` +file with new version information which is referenced by the Freight being +promoted. This step is commonly followed by a [`helm-template`](#helm-template) +step. + +### `helm-update-image` Configuration + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `path` | `string` | Y | Path to Helm values file (e.g. `values.yaml`). This path is relative to the temporary workspace that Kargo provisions for use by the promotion process. | +| `images` | `[]object` | Y | The details of changes to be applied to the values file. At least one must be specified. | +| `images[].image` | `string` | Y | Name/URL of the image being updated. The Freight being promoted presumably contains a reference to a revision of this image. | +| `images[].fromOrigin` | `object` | N | See [specifying origins](#specifying-origins) | +| `images[].key` | `string` | Y | The key to update within the values file. See Helm documentation on the [format and limitations](https://helm.sh/docs/intro/using_helm/#the-format-and-limitations-of---set) of the notation used in this field. | +| `images[].value` | `string` | Y | Specifies how the value of `key` is to be updated. Possible values for this field are limited to: | + +### `helm-update-image` Example + +```yaml +steps: +- uses: git-clone + config: + repoURL: https://github.com/example/repo.git + checkout: + - fromFreight: true + path: ./src + - branch: stage/test + create: true + path: ./out +- uses: git-clear + config: + path: ./out +- uses: helm-update-image + config: + path: ./src/charts/my-chart/values.yaml + images: + - image: my/image + key: image.tag + value: Tag +# Render manifests to ./out, commit, push, etc... +``` + +### `helm-update-image` Output + +| Name | Type | Description | +|------|------|-------------| +| `commitMessage` | `string` | A description of the change(s) applied by this step. Typically, a subsequent [`git-commit`](#git-commit) step will reference this output and aggregate this commit message fragment with other like it to build a comprehensive commit message that describes all changes. | + +## `helm-update-chart` + +`helm-update-chart` performs specified updates on the `dependencies` section of +a specified Helm chart's `Chart.yaml` file. This step is useful for the common +scenario of updating a chart's dependencies to reflect new versions of charts +referenced by the Freight being promoted. This step is commonly followed by a +[`helm-template`](#helm-template) step. + +### `helm-update-chart` Configuration + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `path` | `string` | Y | Path to a Helm chart (i.e. to a directory containing a `Chart.yaml` file). This path is relative to the temporary workspace that Kargo provisions for use by the promotion process. | +| `charts` | `[]string` | Y | The details of dependency (subschart) updates to be applied to the chart's `Chart.yaml` file. | +| `charts[].repository` | `string` | Y | The URL of the Helm chart repository in the `dependencies` entry whose `version` field is to be updated. Must _exactly_ match the `repository` field of that entry. | +| `charts[].name` | `string` | Y | The name of the chart in in the `dependencies` entry whose `version` field is to be updated. Must exactly match the `name` field of that entry. | +| `charts[].fromOrigin` | `object` | N | See [specifying origins](#specifying-origins) | + +### `helm-update-chart` Examples + + + + + +Given a `Chart.yaml` file such as the following: + +```yaml +apiVersion: v2 +name: example +type: application +version: 0.1.0 +appVersion: 0.1.0 +dependencies: +- repository: https://example-chart-repo + name: some-chart + version: 1.2.3 +``` + +The `dependencies` can be updated to reflect the version of `some-chart` +referenced by the Freight being promoted like so: + +```yaml +steps: +- uses: git-clone + config: + repoURL: https://github.com/example/repo.git + checkout: + - fromFreight: true + path: ./src + - branch: stage/test + create: true + path: ./out +- uses: git-clear + config: + path: ./out +- uses: helm-update-chart + config: + path: ./src/charts/my-chart + charts: + - repository: https://example-chart-repo + name: some-chart +# Render manifests to ./out, commit, push, etc... +``` + + + + + +:::caution +Classic (HTTP/HTTPS) Helm chart repositories can contain many differently named +charts. A specific chart, therefore, can be identified by a repository URL and +a chart name. + +OCI repositories, on the other hand, are organizational constructs within OCI +_registries._ Each OCI repository is presumed to contain versions of only a +single chart. As such, a specific chart can be identified by a repository URL +alone. + +Kargo Warehouses understand this distinction well, so a subscription to an OCI +chart repository will utilize its URL only, _without_ specifying a chart name. +For example: + +```yaml +apiVersion: kargo.akuity.io/v1alpha1 +kind: Warehouse +metadata: + name: my-warehouse + namespace: kargo-demo +spec: + subscriptions: + - chart: + repoURL: oci://example-chart-registry/some-chart + semverConstraint: ^1.0.0 +``` + +Helm deals with this difference somewhat more awkwardly, however. When a Helm +chart references a chart in an OCI repository, it must reference the _registry_ +by URL in the `repository` field and _still_ specify a chart name in the name +field. For example: + +```yaml +apiVersion: v2 +name: example +type: application +version: 0.1.0 +appVersion: 0.1.0 +dependencies: +- repository: oci://example-chart-registry + name: some-chart + version: 1.2.3 +``` + +__When using `helm-update-chart` to update the dependencies in a `Chart.yaml` +file, you must play by Helm's rules and use the _registry_ URL in the +`repository` field and the _repository_ name (chart name) in the `name` field.__ +::: + +:::info +As a general rule, when configuring Kargo to update something, observe the +conventions of the thing being updated, even if those conventions differ from +Kargo's own. Kargo is aware of such differences and will adapt accordingly. +::: + +Given a `Chart.yaml` file such as the following: + +```yaml +apiVersion: v2 +name: example +type: application +version: 0.1.0 +appVersion: 0.1.0 +dependencies: +- repository: oci://example-chart-registry + name: some-chart + version: 1.2.3 +``` + +The `dependencies` can be updated to reflect the version of +`oci://example-chart-registry/some-chart` referenced by the Freight being +promoted like so: + +```yaml +steps: +- uses: git-clone + config: + repoURL: https://github.com/example/repo.git + checkout: + - fromFreight: true + path: ./src + - branch: stage/test + create: true + path: ./out +- uses: git-clear + config: + path: ./out +- uses: helm-update-chart + config: + path: ./src/charts/my-chart + charts: + - repository: oci://example-chart-registry + name: some-chart +# Render manifests to ./out, commit, push, etc... +``` + + + + + +### `helm-update-chart` Output + +| Name | Type | Description | +|------|------|-------------| +| `commitMessage` | `string` | A description of the change(s) applied by this step. Typically, a subsequent [`git-commit`](#git-commit) step will reference this output and aggregate this commit message fragment with other like it to build a comprehensive commit message that describes all changes. | + +## `helm-template` + +`helm-template` renders a specified Helm chart to a specified directory or to +many files in a specified directory. This step is useful for the common scenario +of rendering Stage-specific manifests to a Stage-specific branch. This step is +commonly preceded by a [`git-clear`](#git-clear) step and followed by +[`git-commit`](#git-commit) and [`git-push`](#git-push) steps. + +### `helm-template` Configuration + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `path` | `string` | Y | Path to a Helm chart (i.e. to a directory containing a `Chart.yaml` file). This path is relative to the temporary workspace that Kargo provisions for use by the promotion process. | +| `outPath` | `string` | Y | Path to the file or directory where rendered manifests are to be written. If the path ends with `.yaml` or `.yml` it is presumed to indicate a file and is otherwise presumed to indicate a directory. | +| `releaseName` | `string` | N | Optional release name to use when rendering the manifests. This is commonly omitted. | +| `namespace` | `string` | N | Optional namespace to use when rendering the manifests. This is commonly omitted. GitOps agents such as Argo CD will generally ensure the installation of manifests into the namespace specified by their own configuration. | +| `valuesFiles` | `[]string` | N | Helm values files (apart from the chart's default `values.yaml`) to be used when rendering the manifests. | +| `includeCRDs` | `boolean` | N | Whether to include CRDs in the rendered manifests. This is `false` by default. | +| `kubeVersion` | `string` | N | Optionally specifies a Kubernetes version to be assumed when rendering manifests. This is useful for charts that may contain logic specific to different Kubernetes versions. | +| `apiVersions` | `[]string` | N | Allows a manual set of supported API versions to be specified. | + +### `helm-template` Examples + + + + + +```yaml +steps: +- uses: git-clone + config: + repoURL: https://github.com/example/repo.git + checkout: + - fromFreight: true + path: ./src + - branch: stage/test + create: true + path: ./out +- uses: git-clear + config: + path: ./out +- uses: helm-template + config: + path: ./src/charts/my-chart + valuesFiles: + - ./src/charts/my-chart/test-values.yaml + outPath: ./out/manifests.yaml +# Commit, push, etc... +``` + + + + + +```yaml +steps: +- uses: git-clone + config: + repoURL: https://github.com/example/repo.git + checkout: + - fromFreight: true + path: ./src + - branch: stage/test + create: true + path: ./out +- uses: git-clear + config: + path: ./out +- uses: helm-template + config: + path: ./src/charts/my-chart + valuesFiles: + - ./src/charts/my-chart/test-values.yaml + outPath: ./out +# Commit, push, etc... +``` + + + + + +## `git-commit` + +`git-commit` commits all changes in a working tree to its checked out branch. +This step is often used after previous steps have put the working tree into the +desired state and is commonly followed by a [`git-push`](#git-push) step. + +### `git-commit` Configuration + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `path` | `string` | Y | Path to a Git working tree containing changes to be committed. This path is relative to the temporary workspace that Kargo provisions for use by the promotion process. | +| `message` | `string` | N | The commit message. Mutually exclusive with `messageFromSteps`. | +| `messageFromSteps` | `[]string` | N | References the `commitMessage` output of previous steps. When one or more are specified, the commit message will be constructed by concatenating the messages from individual steps. Mutually exclusive with `message`. | +| `author` | `[]object` | N | Optionally provider authorship information for the commit. | +| `author.name` | `string` | N | The committer's name. | +| `author.email` | `string` | N | The committer's email address. | + +### `git-commit` Example + +```yaml +steps: +- uses: git-clone + config: + repoURL: https://github.com/example/repo.git + checkout: + - fromFreight: true + path: ./src + - branch: stage/test + create: true + path: ./out +- uses: git-clear + config: + path: ./out +- uses: kustomize-set-image + as: update-image + config: + images: + - image: my/image +- uses: kustomize-build + config: + path: ./src/stages/test + outPath: ./out +- uses: git-commit + config: + path: ./out + messageFromSteps: + - update-image +# Push, etc... +``` + +### `git-commit` Output + +| Name | Type | Description | +|------|------|-------------| +| `commit` | `string` | The ID (SHA) of the commit created by this step. If the step short-circuited and did not create a new commit because there were no differences from the current head of the branch, this value will be the ID of the existing commit at the head of the branch instead. Typically, a subsequent [`argocd-update`](#argocd-update) step will reference this output to learn the ID of the commit that an applicable Argo CD `ApplicationSource` should be observably synced to under healthy conditions. | + +## `git-push` + +`git-push` pushes the committed changes in a specified working tree to a +specified branch in the remote repository. This step typically follows a `git-commit` step and is often followed by a `git-open-pr` step. + +### `git-push` Configuration + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `path` | `string` | Y | Path to a Git working tree containing committed changes. | +| `targetBranch` | `string` | N | The branch to push to in the remote repository. Mutually exclusive with `generateTargetBranch=true`. If neither of these is provided, the target branch will be the same as the branch currently checked out in the working tree. | +| `generateTargetBranch` | `boolean` | N | Whether to push to a remote branch named like `kargo///promotion`. If such a branch does not already exist, it will be created. A value of 'true' is mutually exclusive with `targetBranch`. If neither of these is provided, the target branch will be the currently checked out branch. This option is useful when a subsequent promotion step will open a pull request against a Stage-specific branch. In such a case, the generated target branch pushed to by the `git-push` step can later be utilized as the source branch of the pull request. | + +### `git-push` Examples + + + + + +```yaml +steps: +# Clone, prepare the contents of ./out, etc... +- uses: git-commit + config: + path: ./out + message: rendered updated manifests +- uses: git-push + config: + path: ./out +``` + + + + + +```yaml +steps: +# Clone, prepare the contents of ./out, etc... +- uses: git-commit + config: + path: ./out + message: rendered updated manifests +- uses: git-push + as: push + config: + path: ./out + generateTargetBranch: true +# Open a PR and wait for it to be merged or closed... +``` + + + + + +### `git-push` Output + +| Name | Type | Description | +|------|------|-------------| +| `branch` | `string` | The name of the remote branch pushed to by this step. This is especially useful when the `generateTargetBranch=true` option has been used, in which case a subsequent [`git-open-pr`](#git-open-pr) will typically reference this output to learn what branch to use as the head branch of a new pull request. | +| `commit` | `string` | The ID (SHA) of the commit pushed by this step. | + +## `git-open-pr` + +`git-open-pr` opens a pull request in a specified remote repository using +specified source and target branches. This step is often used after a `git-push` +and is commonly followed by a `git-wait-for-pr` step. + +At present, this feature only supports GitHub pull requests and GitLab merge +requests. + +### `git-open-pr` Configuration + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `repoURL` | `string` | Y | The URL of a remote Git repository. | +| `provider` | `string` | N | The name of the Git provider to use. Currently only `github` and `gitlab` are supported. Kargo will try to infer the provider if it is not explicitly specified. | +| `insecureSkipTLSVerify` | `boolean` | N | Indicates whether to bypass TLS certificate verification when interfacing with the Git provider. Setting this to `true` is highly discouraged in production. | +| `sourceBranch` | `string` | N | Specifies the source branch for the pull request. Mutually exclusive with `sourceBranchFromStep`. | +| `sourceBranchFromStep` | `string` | N | Indicates the source branch should be determined by the `branch` key in the output of a previous promotion step with the specified alias. Mutually exclusive with `sourceBranch`. | +| `targetBranch` | `string` | N | The branch to which the changes should be merged. | +| `createTargetBranch` | `boolean` | N | Indicates whether a new, empty orphaned branch should be created and pushed to the remote if the target branch does not already exist there. Default is `false`. | + +### `git-open-pr` Example + +```yaml +steps: +# Clone, prepare the contents of ./out, commit, etc... +- uses: git-push + as: push + config: + path: ./out + generateTargetBranch: true +- uses: git-open-pr + as: open-pr + config: + repoURL: https://github.com/example/repo.git + createTargetBranch: true + sourceBranchFromStep: push + targetBranch: stage/prod +# Wait for the PR to be merged or closed... +``` + +### `git-open-pr` Output + +| Name | Type | Description | +|------|------|-------------| +| `prNumber` | `number` | The numeric identifier of the pull request opened by this step. Typically, a subsequent [`git-wait-for-pr`](#git-wait-for-pr) step will reference this output to learn what pull request to monitor. | + +## `git-wait-for-pr` + +`git-wait-for-pr` waits for a specified open pull request to be merged or +closed. This step commonly follows a `git-open-pr` step and is commonly followed +by an `argocd-update` step. + +### `git-wait-for-pr` Configuration + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `repoURL` | `string` | Y | The URL of a remote Git repository. | +| `provider` | `string` | N | The name of the Git provider to use. Currently only `github` and `gitlab` are supported. Kargo will try to infer the provider if it is not explicitly specified. | +| `insecureSkipTLSVerify` | `boolean` | N | Indicates whether to bypass TLS certificate verification when interfacing with the Git provider. Setting this to `true` is highly discouraged in production. | +| `prNumber` | `string` | N | The number of the pull request to wait for. Mutually exclusive with `prNumberFromStep`. | +| `prNumberFromStep` | `string` | N | References the `prNumber` output from a previous step. Mutually exclusive with `prNumber`. | + +### `git-wait-for-pr` Output + +| Name | Type | Description | +|------|------|-------------| +| `commit` | `string` | The ID (SHA) of the new commit at the head of the target branch after merge. Typically, a subsequent [`argocd-update`](#argocd-update) step will reference this output to learn the ID of the commit that an applicable Argo CD `ApplicationSource` should be observably synced to under healthy conditions. | + +### `git-wait-for-pr` Example + +```yaml +steps: +# Clone, prepare the contents of ./out, commit, etc... +- uses: git-push + as: push + config: + path: ./out + generateTargetBranch: true +- uses: git-open-pr + as: open-pr + config: + repoURL: https://github.com/example/repo.git + createTargetBranch: true + sourceBranchFromStep: push + targetBranch: stage/prod +- uses: git-wait-for-pr + as: wait-for-pr + config: + repoURL: https://github.com/example/repo.git + prNumberFromStep: open-pr +``` + +## `argocd-update` + +`argocd-update` updates one or more Argo CD `Application` resources in various +ways. Among other scenarios, this step is useful for the common one of forcing +an Argo CD `Application` to sync after previous steps have updated a remote +branch referenced by the `Application`. This step is commonly the last step in a +promotion process. + +### `argocd-update` Configuration + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `apps` | `[]object` | Y | Describes Argo CD `Application` resources to update and how to update them. At least one must be specified. | +| `apps[].name` | `string` | Y | The name of the Argo CD `Application`. | +| `apps[].namespace` | `string` | N | The namespace of the Argo CD `Application` resource to be updated. If left unspecified, the namespace will be the Kargo controller's configured default -- typically `argocd`. | +| `apps[].sources` | `[]object` | N | Describes Argo CD `ApplicationSource`s to update and how to update them. | +| `apps[].sources[].repoURL` | `string` | Y | The value of the target `ApplicationSource`'s own `repoURL` field. This must match exactly. | +| `apps[].sources[].chart` | `string` | N | Applicable only when the target `ApplicationSource` references a Helm chart repository, the value of the target `ApplicationSource`'s own `chart` field. This must match exactly. | +| `apps[].sources[].desiredCommitFromStep` | `string` | N | Applicable only when `repoURL` references a Git repository, this field references the `commit` output from a previous step and uses it as the desired revision for the source. If this is left undefined, the desired revision will be determined by Freight (if possible). Note that the source's `targetRevision` will not be updated to this commit unless `updateTargetRevision=true` is set. The utility of this field is to ensure that health checks on Argo CD `ApplicationSource`s can account for scenarios where the desired revision differs from what may be found in Freight, likely due to the use of rendered branches and/or PR-based promotion workflows. | +| `apps[].sources[].updateTargetRevision` | `boolean` | Y | Indicates whether the target `ApplicationSource` should be updated such that its `targetRevision` field points at the most recently Git commit (if `repoURL` references a Git repository) or chart version (if `repoURL` references a chart repository). | +| `apps[].sources[].kustomize` | `object` | N | Describes updates to an Argo CD `ApplicationSource`'s Kustomize-specific properties. | +| `apps[].sources[].kustomize.images` | `[]object` | Y | Describes how to update an Argo CD `ApplicationSource`'s Kustomize-specific properties to reference specific versions of container images. | +| `apps[].sources[].kustomize.images[].repoURL` | `string` | Y | URL of the image being updated. The Freight being promoted must contain a reference to a revision of this image. | +| `apps[].sources[].kustomize.images[].newName` | `string` | N | A substitution for the name/URL of the image being updated. This is useful when different Stages have access to different container image repositories (assuming those different repositories contain equivalent images that are tagged identically). This may be a frequent consideration for users of Amazon's Elastic Container Registry. | +| `apps[].sources[].kustomize.images[].useDigest` | `boolean` | N | Whether to use the container image's digest instead of its tag. | +| `apps[].sources[].kustomize.images[].fromOrigin` | `object` | N | See [specifying origins](#specifying-origins). If not specified, may inherit a value from `apps[].sources[].kustomize.fromOrigin`. | +| `apps[].sources[].kustomize.fromOrigin` | `object` | N | See [specifying origins](#specifying-origins). If not specified, may inherit a value from `apps[].sources[].fromOrigin`. | +| `apps[].sources[].helm` | `object` | N | Describes updates to an Argo CD `ApplicationSource`'s Helm parameters. | +| `apps[].sources[].helm.images` | `[]object` | Y | Describes how to update an Argo CD `ApplicationSource`'s Helm parameters to reference specific versions of container images. | +| `apps[].sources[].helm.images[].repoURL` | `string` | Y | URL of the image being updated. The Freight being promoted must contain a reference to a revision of this image. | +| `apps[].sources[].helm.images[].key` | `string` | Y | The key to update within the target `ApplicationSource`'s `helm.parameters` map. See Helm documentation on the [format and limitations](https://helm.sh/docs/intro/using_helm/#the-format-and-limitations-of---set) of the notation used in this field. | +| `apps[].sources[].helm.images[].value` | `string` | Y | Specifies how the value of `key` is to be updated. Possible values for this field are limited to:
  • `ImageAndTag`: Replaces the value of `key` with a string in form `:`
  • `Tag`: Replaces the value of `key` with the image's tag
  • `ImageAndDigest`: Replaces the value of `key` with a string in form `@`
  • `Digest`: Replaces the value of `key` with the image's digest
| +| `apps[].sources[].helm.images[].fromOrigin` | `object` | N | See [specifying origins](#specifying-origins). If not specified, may inherit a value from `apps[].sources[].helm.fromOrigin` | +| `apps[].sources[].helm.fromOrigin` | `object` | N | See [specifying origins].(#specifying-origins). If not specified, may inherit a value from `apps[].sources[]`. | +| `apps[].sources[].fromOrigin` | `object` | N | See [specifying origins](#specifying-origins). If not specified, may inherit a value from `apps[].fromOrigin`. | +| `apps[].fromOrigin` | `object` | N | See [specifying origins](#specifying-origins). If not specified, may inherit a value from `fromOrigin`. | +| `fromOrigin` | `object` | N | See [specifying origins](#specifying-origins) | + +### `argocd-update` Examples + + + + + +```yaml +steps: +# Clone, render manifests, commit, push, etc... +- uses: git-commit + as: commit + config: + path: ./out + messageFromSteps: + - update-image +- uses: git-push + config: + path: ./out +- uses: argocd-update + config: + apps: + - name: my-app + sources: + - repoURL: https://github.com/example/repo.git + desiredCommitFromStep: commit +``` + + + + + +:::caution +Without making any modifications to a Git repository, this example simply +updates a "live" Argo CD `Application` resource to point its `targetRevision` +field at a specific version of a Helm chart, which Argo CD will pull directly +from the the chart repository. + +While this can be a useful technique, it should be used with caution. This is +not "real GitOps" since the state of the `Application` resource is not backed +up in a Git repository. If the `Application` resource were deleted, there would +be no remaining record of its desired state. +::: + +```yaml +steps: +- uses: argocd-update + config: + apps: + - name: my-app + sources: + - repoURL: https://example-chart-repo + chart: my-chart + updateTargetRevision: true +``` + + + + + +:::caution +Without making any modifications to a Git repository, this example simply +updates Kustomize-specific properties of a "live" Argo CD `Application` +resource. + +While this can be a useful technique, it should be used with caution. This is +not "real GitOps" since the state of the `Application` resource is not backed up +in a Git repository. If the `Application` resource were deleted, there would be +no remaining record of its desired state. +::: + +```yaml +steps: +- uses: argocd-update + config: + apps: + - name: my-app + sources: + - repoURL: https://github.com/example/repo.git + kustomize: + images: + - repoURL: my/image +``` + + + + + +:::caution +Without making any modifications to a Git repository, this example simply +updates Helm-specific properties of a "live" Argo CD `Application` resource. + +While this can be a useful technique, it should be used with caution. This is +not "real GitOps" since the state of the `Application` resource is not backed +up in a Git repository. If the `Application` resource were deleted, there would +be no remaining record of its desired state. +::: + +```yaml +steps: +- uses: argocd-update + config: + apps: + - name: my-app + sources: + - repoURL: https://github.com/example/repo.git + helm: + images: + - repoURL: my/image + key: image.tag + value: Tag +``` + + + + + +### `argocd-update` Health Checks + +The `argocd-update` step is unique among all other built-in promotion steps in +that, on successful completion, it will register health checks to be performed +upon the target Stage on an ongoing basis. This health check configuration is +_opaque_ to the rest of Kargo and is understood only by health check +functionality built into the step. This permits Kargo to factor the health and +sync state of Argo CD `Application` resources into the overall health of a Stage +without requiring Kargo to understand `Application` health directly. + +:::info +Although the `argocd-update` step is the only promotion step to currently +utilize this health check framework, we anticipate that future built-in and +third-party promotion steps will take advantage of it as well. +::: + +## Specifying Origins + +Many promotion steps, or parts of those steps, will (whether optionally or +unconditionally) attempt to learn the desired revision(s) of some artifact(s) by +consulting the revisions of those artifact(s) references by the Freight being +promoted. + +By way of example, this `kustomize-set-image` step will consult the Freight +being promoted to learn the desired revision of the `my/image` container image: + +```yaml +- uses: kustomize-set-image + config: + path: ./src/base + images: + - image: my/image +``` + +In some _advanced_ uses cases, Stages may request Freight from multiple origins +(Warehouses). In such scenarios, it is possible (although somewhat rare) that +the multiple Freight being promoted may collectively reference multiple distinct +revisions of the same artifact. In such as case, it can become ambiguous which +revision of an artifact referenced by a promotion step should be used. + +To permit disambiguation in cases such as those described above, all promotion +steps that have the potential to reference Freight from multiple origins support +a `fromOrigin` option that can be used to clarify which piece of Freight's +reference to the artifact should be used by identifying the origin (Warehouse) +from which the Freight should have originated. + +The best way to illustrate this involves a complex example wherein a Stage +requests Freight from two Warehouses. Both Warehouses subscribe to the same Git +repository, with one watching for changes to a Kustomize "base" configuration +and the other watching for changes to a Stage-specific Kustomize overlay. +Rendering the manifests intended for such a Stage will require combining the +base and overlay configurations with the help of a [`copy`](#copy) step. For +this case, a `git-clone` step may be configured similarly to the following: + +```yaml +steps: +- uses: git-clone + config: + repoURL: https://github.com/example/repo.git + checkout: + - fromFreight: true + fromOrigin: + kind: Warehouse + name: base + path: ./src + - fromFreight: true + fromOrigin: + kind: Warehouse + name: test-overlay + path: ./overlay + - branch: stage/test + create: true + path: ./out +- uses: git-clear + config: + path: ./out +- uses: copy + config: + inPath: ./overlay/stages/test/kustomization.yaml + outPath: ./src/stages/test/kustomization.yaml +- uses: kustomize-build + config: + path: ./src/stages/test + outPath: ./out +# Commit, push, etc... +``` + +Note that when checking out specific revisions of the +`https://github.com/example/repo.git` repository to different working trees, the +`git-clone` step has twice utilized `fromOrigin` to clarify which of the Freight +being promoted should be used to determine the revision to check out. + +:::info +`fromOrigin` never needs to be specified in the majority of use cases wherein +there is no inherent ambiguity. Kargo will automatically select the correct +revision of an artifact when there is only one possibility. When Kargo detects +that there may be multiple possibilities, it will fail and raise an error +indicating that the user must disambiguate by specifying `fromOrigin` in +applicable steps. +::: diff --git a/docs/docs/35-references/_category_.json b/docs/docs/35-references/_category_.json new file mode 100644 index 000000000..2ae746604 --- /dev/null +++ b/docs/docs/35-references/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Reference docs", + "link": null +}