"release-manifests.yaml" workflow which targets releasing tags that are
labeled as a release, or commits that are pushed on the release branch.
add more detail in jsonnet example section
more text
There might be some overlap with the SOPS/Azure KMS example that Leigh
provided
re-align with #1064
fixup text
substantial rework in introduction
more text that hasn't been in a commit yet
more organization
more commentary
This is an example implementation of "build-time" manifest generation on GitHub Actions.
This example implements "build-time" manifest generation on GitHub Actions.
We first use third-party tools to prepare and update YAML manifests in a CI job. Then changes are committed to a deploy branch from CI and finally pushed, where `kustomize-controller` can apply them to a cluster.
Third-party tools are used to generate YAML manifests in a CI job. The updated YAML are committed and pushed to Git, where `kustomize-controller` finally applies them.
A complementary feature in Flux v2 is [post-build variable substition](https://toolkit.fluxcd.io/components/kustomize/kustomization/#variable-substitution), but its use is limited by some constraints such as lacking support for [run-time access to Git repository metadata](https://github.com/fluxcd/flux2/discussions/1054) about the commit that is deployed.
### Background
We recommend to solve this from within CI, and many then asked, "how do I do that" – so this guide was written. To show an implementation of Manifest Generation that can be used with [any old app](https://github.com/kingdonb/any_old_app) on GitHub. (The linked example is a basic Rails app which has been used to develop this guide.)
A complementary idea to manifest generation in Flux v2 is [post-build variable substition](https://toolkit.fluxcd.io/components/kustomize/kustomization/#variable-substitution). Unfortunately, for at least one popular use case, it is still too limited. Currently there is no support in `Kustomization` for [fetching Git repository metadata](https://github.com/fluxcd/flux2/discussions/1054) from the commit that is being deployed.
From end-to-end, with a recommended architecture... 🆗 👍 🥇
It is not possible to reference a commit's own Git SHA, or commit ID, as `kustomize build` runs from that commit. This is a common request from Flux users, especially those working with Mono-repos, as Flux v1 certainly had this capability.
## Primary Uses of Flux
Flux v1 allowed users to provide their own binaries to `kustomize build` by leveraging an `initContainer`, enabling users to `shell_exec` from within `.flux.yaml`, permitting arbitrary commands to be run by manifest generation, with practically no limitations on access to the commit and/or repository data.
This was able to be used productively [with `kustomize edit set image` in a generator](https://github.com/fluxcd/flux2/discussions/1002), for example, to reference tags built from the current commit, even without scanning any image repository (and perhaps before images have even finished building.)
While many productive uses were possible, this capability was a curse to supporting Flux, for site reliability as well as security reasons.
#### What's Not Possible Anymore
Clearly this arrangement offers too much freedom. Manifest generation runtimes always increases as a repository grows, which can be a source of reconciliation timeouts. From a security perspective also there can be no way to permit any of this to behave as described in a multi-tenancy environment.
Still, it is not an unreasonable ask to simply deploy the latest image, and also a reasonably common use case that Flux v1 could already fulfill handily (with no qualifiers!) Flux adopters leveraging this capability have fostered and grown many projects.
Flux is not prescriptive about how updates should happen. Sorting with Number or SemVer policies should not be considered to be exhaustive of the many possible approaches. The `image-automation-controller` is one possible implementation; it is also still in alpha releases as of the time of this writing, and can likely still be further improved, even in ways we maybe haven't thought of yet.
#### What Flux Does
Flux will deploy whatever is in the latest commit, on whatever branch you point it at. It is by design that Flux doesn't care how a commit is generated.
#### What Flux Don't
Since ["select latest by build time" image automation](https://github.com/fluxcd/flux2/discussions/802) is deprecated, and since [`.flux.yaml` is also deprecated](https://github.com/fluxcd/flux2/issues/543), some staple workflows are no longer possible without new accommodations from infrastructure.
Flux still provides image automation which remains separate from CI, but for `ImageAutomationPolicy` now there are some additional requirements on the image tagging plan for auto updating. While this is new, it still remains true that CI things are generally considered to be outside of the scope of FluxCD.
#### What Should We Do?
We first recommend users [adjust their tagging strategies](/guides/sortable-image-tags/), which is made clear elsewhere in the docs. This is usually a straightforward adjustment, and enables the use of [Image Update Policies](/guides/image-update/); however this may not be feasible or desired in some cases.
Parallel deployments of Flux v1 and v2 may be undertaken for change management reasons, and due to the order of implementation, changes to image tag strategies can't be undertaken before Flux v1 is finally taken down.
So as interim or alternative solutions may be needed, we recommended manifest generation to resolve this. Many asked, "how do I do *that* on **my CI**?"
As it turned out, this is neither straightforward nor obvious, so (even though it is not in Flux), this guide was conceived for Flux users.
(Possibly the first in a series,) supporting manifest generation strategies spanning different YAML tools and different CI providers with Flux:
## Use Manifest Generation
Introducing, Manifest Generation with Jsonnet, for [any old app](https://github.com/kingdonb/any_old_app) on GitHub!
Using a separate repo than your `fleet-infra` may be indicated at times through the examples. The `any_old_app` repo linked above is a skeleton app, which was used to develop this guide. (**`FIXME Editor: TODO`** You can also clone and inspect the branches there to find the code from these examples.)
OK, here with a recommended architecture... 🆗 👍 🥇
**SNIP**
Editor: Potentially cut everything between ^SNIP above and >SNIP below
except for perhaps the Security Consideration. (Covered well enough by new "Background" text above?)
### Primary Uses of Flux
Flux's primary use case for `kustomize-controller` is to apply YAML manifests from the latest `Revision` of an `Artifact`.
For a `GitRepository`, this is the latest commit in a branch or tag ref. The use cases in this tutorial for manifest generation assume that the CI is given write access to one or more Git repos **in order to affect changes to** what deploys on the cluster.
For a `GitRepository`, this is the latest commit in a branch or tag ref. The use cases in this tutorial for manifest generation assume that the **CI is given write access** to one or more Git repos **in order to affect changes to** what deploys on the cluster.
For so many CI providers, this can be complicated to set up. Secure authentication and authorization is hard. In GitHub Actions though, within a single repo, this is simply provided for without additional configuration, whenever Actions are enabled!
@ -38,13 +86,13 @@ Flux's behavior of deploying `GIT_SHA` image tags as they are pushed [is being d
!!! warning "Migrate to use `ImagePolicy`, the `fluxcd.io/automated` behavior is deprecated"
Qualified feature parity is provided through `ImagePolicies`. Those who use Flux's automation cannot automate `GIT_SHA` as the tag for automated workloads anymore in Flux v2.
For especially users who manage a lot of workloads that manage both Flux v1 and v2 in parallel, and who want to safely move just one piece at a time in order to limit the blast radius of upgrading, can follow these examples in order to reproduce the specific behavior of `fluxcd.io/automated` from CI, without anything else.
In case users need to run some workloads from both Flux v1 and v2 in parallel, for example a large migration moving one app at a time a-la [Strangler Fig Pattern](https://martinfowler.com/bliki/StranglerFigApplication.html), in order to maintain continuity of the specific behavior of `fluxcd.io/automated` this compatibility shim can be used.
Readers should become familiar with Flux v2's [image scanning configuration](/guides/image-update/#configure-image-scanning) to avoid falling into the trap of [doing CI-ops](https://www.weave.works/blog/kubernetes-anti-patterns-let-s-do-gitops-not-ciops), where releases are driven by CI rather than coming from Git.
Readers should become familiar with Flux v2's [image scanning configuration](/guides/image-update/#configure-image-scanning) to avoid [doing CI-ops](https://www.weave.works/blog/kubernetes-anti-patterns-let-s-do-gitops-not-ciops), where releases are driven thru CI rather than promoting tested artifacts from one environment to the next.
This compatibility shim does not perform image scanning in any way, it just approximates the behavior in a way that is mostly compatible for Dev environments. We drive the deployment of new images directly from CI. There is no reconciliation watching image repos for new images, (this is not a replacement for Flux automation.)
This compatibility shim does not perform image scanning in any way, it just approximates the behavior in a way that is mostly compatible for Dev environments. We drive the deployment of new images directly from CI. This is not a replacement for Flux automation. Flux does not recommend keeping this behavior in your CI, migrate to ImagePolicy based functionality of Flux v2 instead. Since this is a breaking change, a compatibility shim is being provided.
Recognizing also that not all Flux users are the ones publishing their own images, it is considered that making [this update](/guides/sortable-image-tags/) to CI build processes is not always practical for end-users.
Recognizing also that not all Flux users are the ones publishing their own images, it is considered that making [this update](/guides/sortable-image-tags/) to CI build and image tagging processes is not always practical for end-users, who may even be completely dependant on inflexible upstreams.
#### Deprecated Features
@ -52,13 +100,16 @@ So we address some deprecated features for users of Flux migrating their develop
We recognize that for those migrating from Flux v1, many or most will have only followed guidance that we've recommended them in the past, so might be feeling betrayed now. Some of our guides and docs certainly have gone so far as to recommend using `GIT_SHA` as the whole image tag. (Even [Flux's own CI jobs](https://github.com/fluxcd/kustomize-controller/blob/main/.github/workflows/release.yml#L20) still write image tags like this.)
The Flux development team recognizes that this feature having changed may unfortunately cause pain for some of our users and for downstream technology adopters, who might rightly blame Flux for causing them this pain.
The Flux development team recognizes that this feature having changed may unfortunately cause pain for some of our users and for downstream technology adopters, who might rightly blame Flux for causing them this pain. We hope that making the update to sortable image tags will not be too painful.
If your build process doesn't already meet Flux's new requirements for image automation, and you can not fix it now; this should not block upgrading to Flux v2. We can solve it adding only a few new CI build processes.
If your build process doesn't already meet Flux's new requirements for image automation, and you can not fix it now; this pain should not block upgrading to Flux v2. We can still upgrade preserving same behavior, only adding a few new CI build processes. Then disable `fluxcd.io/automated` annotations, finally turn off Flux v1, completing the migration! We can address any image tagging process changes needed after the upgrade is already completed.
So, these two ideas are fundamentally separate, but this guide covers both ideas in tandem, with the same thread: how to do manifest generation, and how to use it to drive deploys from CI.
So, these two ideas are fundamentally separate, but this guide covers both ideas in tandem, with the same thread: how to do manifest generation, and how to use it to drive deploys from CI in a way that is GitOps-friendly and reminiscent of Flux v1.
In a way that is GitOps-friendly and reminiscent of Flux v1, (even though it is also technically CI-ops!) we show how to reproduce the approximate behavior of a deprecated feature (`fluxcd.io/automated`), without imposing any new constraints or requirements on image tagging policy.
Some may say this is technically CI-ops in GitOps clothing, and this is true too. CI-ops in this case makes it possible to reproduce closely the same behavior of the old deprecated feature (`fluxcd.io/automated`), without imposing any new constraints or additional requirements for image tagging policy.
Editor: Potentially cut everything between ^SNIP above and >SNIP below
**SNIP**
It is intended, finally, to show through this use case, three fundamental ideas for use in CI to accompany Flux automation:
@ -68,15 +119,15 @@ It is intended, finally, to show through this use case, three fundamental ideas
Readers can interpret this document with adaptations for use with other CI providers, or Git source hosts.
#### The Choice of GitHub Actions
### The Choice of GitHub Actions
There are authentication concerns with every CI provider and they differ by Git provider.
Being that GitHub Actions is hosted on GitHub, this guide can be uniquely simple in some ways, as we can skip talking about authentication almost altogether. It is handled by the CI platform, we get write access to git.
Being that GitHub Actions is hosted on GitHub, this guide can be uniquely simple in some ways, as we can mostly skip configuring authentication. The cross-cutting concern is handled by the CI platform; we write access to Git as we are already a Git user, (and one with write access.)
(Other providers will need more attention for authn and authz configuration in order to ensure that connections between CI provider and Source provider's git host are all handled safely and securely.)
### Use Cases of Manifest Generation
## Use Cases of Manifest Generation
There are several use cases presented. Shown below are a few different ways to add commits and push updates to Git, through GitHub Actions.
@ -97,7 +148,7 @@ The examples below assume no prior familiarity with GitHub Actions. Together the
This is the example we've been waiting for, the answer to `.flux.yaml` in Flux v2! 🎉🎁
#### String Substitution with `sed -i`
### String Substitution with `sed -i`
The entry point for these examples starts at `.github/workflows/` in a source repository. Add this directory if needed in your repositories. The first use case is to build a manifest with the commit hash of the latest commit, to deploy an image built from that commit. This example triggers from any commit on any branch.
@ -253,7 +304,7 @@ If CI fails to build, your branch may contain a new copy of the source code whil
This can leave the Kustomization in an error state which can be hard to detect, and may need to be manually remediated. This is not a strategy for Production. (Instead, use SemVer tags with `ImagePolicy`.)
#### Docker Build and Tag with Version
### Docker Build and Tag with Version
This is how to build an image and push a tag from the latest commit on the branch.
@ -321,9 +372,9 @@ Little above differs from the linked examples, provided from Docker via the GitH
In our example when a commit is pushed on a branch, `VERSION` is set from `GIT_SHA`, but if it is a tag that is pushed then the image tag is written and pushed instead.
* TODO: Add caching examples if needed to make sure that the merge commit does not reflect a different Image when it is rebuilt without any changes. That way, the image that has already been tested can be promoted, rather than building a new image assuming it hasn't changed, and pushing out an untested image.
We should note, this example does not implement caching. This means that even when subsequent commits represent a no-op, totally new images will be built instead of reusing existing layers. This is wasteful, but for us it is out of scope. [Docker Buildx Caching in GitHub Actions](https://evilmartians.com/chronicles/build-images-on-github-actions-with-docker-layer-caching#the-cache-dance-off) is a great topic and a totally other guide.
* TODO: This type of error (an untested image is promoted into production) should always be prevented as early as possible through merge checks in staging and production, and using safe promotion strategies. (The todo is to document this strategy from end to end.)
* TODO: Document strategies to prevent untested commits from being promoted into staging or production environments, through the use of release staging and validation with merge checks, for safe promotion. (The todo is to document such a strategy from end to end –which is again probably out of scope for this guide.)
```bash
# excerpted from above - set VERSION for tag refs
@ -349,12 +400,25 @@ with:
The image tag `VERSION` comes from the branch or Git tag that triggered the build. Whether that version is a `GIT_SHA` or a semantic version tag, the same workflow can be used to build the image as shown here!
#### Jsonnet for YAML Document Rehydration
### Jsonnet for YAML Document Rehydration
As mentioned before, Flux only monitors one branch or tag per Kustomization, so it is advisable to protect the release branch with eg. branch policies, as it directly represents the production deployment.
The CI user for this example should be allowed to push directly to the `deploy` branch; it also represents the production environment here and must be protected from normal users in a similar fashion. Only CI (and/or the cluster admin user) should be allowed to write to the `deploy` branch.
!!! note "`GitRepository` source only targets one branch"
Since Flux uses one branch or tag per Kustomization, for CI to trigger an update to the cluster it must write into a `deploy` branch. Even when a new build can come from any branch (as is frequently the case for Dev environments) the YAML manifests to deploy are written to just one branch.
Since Flux uses one branch per Kustomization, to trigger an update we must write to a `deploy` branch or tag. Even when new app images can come from any branch (eg. for Dev environments where any latest commit is to be deployed) the YAML manifests to deploy will be sourced from just one branch.
#### Jsonnet Render Action
Below we build from any tag with the `release/*` format, or any latest commit pushed to the `release` branch. (Users, we expect, may choose either `on.push` strategy, probably not using both `tags` and `branches` as the example below, to avoid confusion.)
The outputted YAML manifests, on successful completion of the jsonnet render step, are staged on the `deploy` branch, then committed and pushed.
The latest commit on the `deploy` branch is reconciled into the cluster by a `Kustomization`.
```yaml
# ./.github/workflows/release-manifests.yaml
name: Build jsonnet
on:
push:
@ -398,8 +462,20 @@ jobs:
signoff: true
```
While it is straightforward to see which commit is the latest pushed on a branch, (especially when policy would prohibit force-pushes,) it is not always easy to see which tag was the latest pushed. It is possible for `1.3.4` to be pushed after `1.3.5`, for example, and since CI builds execute in the order that they are received, an earlier numbered release could win. This is not image policy, it is strictly deploying manifests from the latest commit pushed.
We add two new steps in this example:
```
# excerpted from above - workflow steps 3 and 4
- id: jsonnet-render
- name: Prepare target branch
```
The `jsonnet-render` step is borrowed from another source, again find it on [GitHub Actions Marketplace](https://github.com/marketplace/actions/jsonnet-render) for more information.
!!! note "The `EndBug/add-and-commit` action is used again"
This time, with the help of `rake.sh`, our change is staged into a different target branch. This is the same `deploy` branch, regardless of where the build comes from; any push event can trigger this deploy.
This time, with the help of `rake.sh`, our change is staged into a different target branch. This is the same `deploy` branch, regardless of where the build comes from; any configured push event can trigger this deploy.
```bash
#!/bin/bash
@ -437,32 +513,102 @@ Tailor this workflow to your needs. We render from a file `manifests/example.jso
signoff: true
```
This is [Add & Commit](https://github.com/marketplace/actions/add-commit) with a `branch` option, to set the target branch. We've added a `signoff` option as well, to demonstrate another feature of this GitHub Action. There are many ways to use this workflow, (we will not be covering them exhaustively.)
This is [Add & Commit](https://github.com/marketplace/actions/add-commit) with a `branch` option, to set the target branch. We've added a `signoff` option as well here, to demonstrate another feature of this GitHub Action. There are many ways to use this workflow step. The link provides more information.
#### Looping
This example writes the same `secretRef` into many `HelmReleases`, to provide for the cluster to be able to use the same `imagePullSecret` across several `Deployments` in a namespace. It is a common problem that `jsonnet` can solve quite handily, without repeating the `Secret` name over and over as a string.
```yaml
TODO: Add some jsonnet here to demonstrate how one does ^that
TODO: Add a jsonnet example here that demonstrates simple string interpolation and a looping construct
```
We could solve this in `Kustomization`'s `postBuild`, via `envsubst`, or handle it in CI as in this example. Un-templated manifests can now be read in directly by `Kustomize`, or reviewed by a person (before or after deployment) at any time.
(Say something about jsonnet example above.)
#### `ConfigMap` with `envsubst`
The next example "enforces," or copies, a `configMap` with a SHA value in it from one namespace into many namespaces, so that Kustomizations in each namespace can maintain the same config data in their reconciliations and stay DRY, without building configurations that reach across namespace boundaries.
ConfigMap values are not treated as secret data, so there is no confusing encryption to contend with, making for a good first example. This simple example shows how to centralize the reference to these plain-text tag or version values. (Later, we will repeat this process with a SOPS encrypted secret.)
```yaml
TODO: Add example that builds a configmap and clones it into several namespaces,
making multiple references into the ConfigMap from neighboring HelmReleases
```
(Say something about the configmap example above.)
#### Handling `Secret`s
Because a `secret` is not safe to store in Git unencrypted, Flux recommends using SOPS to encrypt it.
SOPS will produce a [different data key](https://github.com/mozilla/sops/issues/315) for each fresh invocation of `sops -e`, producing different cipher data even for the same input data. This is true even when the secret content has not changed. This means, unfortunately, it is not practical for a Manifest Generation routine to implement secret transparency without granting the capability to read secrets to the CI infrastructure.
SOPS stores the metadata required to decrypt each secret in the metadata of the secret, which must be stored unencrypted to allow encrypted secrets to be read by the private key owners.
Secret transparency means that it should be possible for an observer to know when a stored secret has been updated or rotated. Transparency can be achieved in SOPS by running using `sops [encrypted.yaml]` as an editor, which decrypts and re-encrypts the secret, only changing the cipher text when secret data also changes.
Depending on your access model, this suggestion could be either a complete non-starter, or a helpful add-on.
As an example, Secrets could be read from GitHub Secrets during a CI job, then written encrypted into a secret that is pushed to the deploy branch. This implementation provides a basic solution for simple centralized secrets rotation. But as this would go way beyond simple manifest generation, we consider this beyond the scope of the tutorial, and it is mentioned only as an example of a more complex usage scenario for users to consider.
#### Replicate `Secrets` Across Namespaces
When the data of a `secret` is stored in the git repository, it can be encrypted to store and transmit safely. SOPS in Kustomize supports encryption of only `(stringData|data)` fields, not secret `metadata` including `namespace`. This means that secrets within the same repo can be copied freely and decrypted somewhere else, just as long as the `Kustomization` still has access to the SOPS private key.
Because of these properties though, copying a SOPS-encrypted secret from one namespace to another within one single Flux tenant is as easy as cloning the YAML manifest and updating the `namespace` field. Compared to SealedSecrets controller, which does not permit this type of copying; SOPS, on the other hand, does not currently prevent this without some attention being paid to RBAC.
Remember to protect your secrets with RBAC! This is not optional, when handling secrets as in this example.
#### Protecting `Secrets` from Unauthorized Access
The logical boundary of a secret is any cluster or tenant where the private key is available for decrypting.
This means that any SOPS secret, once encrypted, can be copied anywhere or used as a base for other Kustomizations in the cluster, so long as the Kustomization itself has access to the decryption keys.
It is important to understand that the `sops-gpg` key that is generated in the Flux SOPS guide can be used by any `Kustomization` in the `flux-system` namespace.
It cannot be over-emphasized; if users want secrets to remain secret, the `flux-system` namespace (and indeed the entire cluster itself) must be hardened and protected, managed by qualified cluster admins. It is recommended that changes which could access encrypted secrets are tightly controlled as much as deemed appropriate.
#### More Advanced Secrets Usage
The use of KMS as opposed to in-cluster GPG keys with SOPS is left as an exercise for the reader. The basics of KMS with various cloud providers is covered in more depth by the [Mozilla SOPS](/guides/mozilla-sops/#using-various-cloud-providers) guide.
Another scenario we considered, but rejected for these examples, requires to decrypt and then re-encrypt SOPS secrets, for use with the `secretGenerator` feature of Kustomize. This workflow is not supported here for reasons already explained.
Flux suggests maintaining the only active copy of the decryption key for a cluster inside of that cluster (though there may be a provision for backups, or some alternate keys permitted to decrypt.) This arrangement makes such use cases significantly more complicated to explain, beyond the scope of this guide.
For those uses though, additional Workflow Actions are provided:
The [Decrypt SOPS Secrets](https://github.com/marketplace/actions/decrypt-sops-secrets) action may be useful and it is mentioned here, (but no example uses are provided.)
The [Sops Binary Installer](https://github.com/marketplace/actions/sops-binary-installer) action enables more advanced use cases, like encrypting or re-encrypting secrets.
#### Jsonnet Recap
While much of this type of manipulation could be handled in `Kustomization`'s `postBuild`, via `envsubst`, some configurations are more complicated this way. They can be better handled in CI, where access to additional tools can be provided.
By writing YAML manifests into a git commit, this Jsonnet usage pattern enables inspection of manifests as they are read directly by `Kustomize` before being applied, for review at any time; before or after deployment.
When the YAML that is applied in the cluster comes directly from Git commits, that's GitOps!
### Commit Across Repositories Workflow
This is the same actual YAML that is applied. (Now that's GitOps!)
Flux will not deploy from pushes on just any branch; GitRepository sources target just one specific branch. Merging to a `staging` branch, for example, can be used to trigger a deployment to a Staging environment.
Most use cases for deployments will not take just any push, preferring to target instead one specific branch. Merging in our application's Git repository to a `staging` branch can trigger staging a deployment to some Test environment, for example.
Manifest generation can be used to solve, broadly, very many problems, such that even with many examples, this guide would never be totally exhaustive.
Manifest generation can be used to solve, broadly, very many problems. Even with many examples, this guide would never be totally exhaustive.
This is the final example in this guide.
#### Commit Across Repositories Workflow
Here we show 🥁 ... how to replicate the original behavior of Flux v1's image automation! 🤯 🎉
This is the final example in this guide. It shows how to replicate the behavior of Flux v1's image automation totally.
To replicate the nearest approximation of Flux's "deploy latest image" feature of yesteryore, we use push events to do the job, as we hinted was possible in an earlier example. Without Flux v1's redundant and expensive image pull behavior, used to get access to image build information required to order image tags for deployment.
To replicate the best nearest approximation of Flux's "deploy latest image" feature of yesteryore, we use push events to do the job without invoking Flux v1's expensive and redundant image pull requirements to get access to image build metadata.
This is racy and doesn't always guarantee the latest commit will be the one that is deployed, since this behavior depends on the time that each commit is pushed, and even precisely how long the build takes to complete; the difference is fine for Dev environments, but this is not a strategy for Production use cases.
This is racy and doesn't guarantee the latest commit will be the one deployed, since it depends on the time that each commit is pushed and even how long the build takes to complete; fine for Dev environments, not for Production strategy.
App CI can commit and push a subfolder full of YAML manifests into a separate deploy branch for `Kustomization` to apply, which can be any branch on any separate repository to which the CI is granted write access.
This is done by leverage of CI to commit and push a subfolder from an application repository into a separate deploy branch of plain YAML manifests for `Kustomization` to apply, that can be pushed to any branch on any separate repository to which CI is granted write access.
While there are some issues, this is actually perfect for some deployments, eg. in a staging environment!
```yaml
name: Update Fleet-Infra
@ -506,11 +652,11 @@ jobs:
commit-message: "[ci skip] deploy from ${{ steps.prep.outputs.VERSION }}"
```
This is [Push directory to another repository](https://github.com/marketplace/actions/push-directory-to-another-repository). Flux v2 is made to work with more than one GitRepository.
This is [Push directory to another repository](https://github.com/marketplace/actions/push-directory-to-another-repository). This is especially useful because Flux v2 is made to work with more than one GitRepository.
If you use a mono-repo, consider adding a deploy branch to it! There is no need for branches in the same repo to always share a parent and intersect again at a merge point.
If you must use a mono-repo, consider adding a deploy branch to it! There is no need for branches in the same repo to always share a parent and intersect again at a merge point.
This is counter-productive for performance and will create bottlenecks for Flux, as large commits will take longer to clone, and therefore to reconcile; ignoring with `.sourceignore` or `spec.ignore` will unfortunately not help much. There are some limitations that can only be surpassed by changing the data structure.
A mono-repo can be counter-productive for performance and will create bottlenecks for Flux, as large commits will take longer to clone, and therefore to reconcile. Ignoring with `.sourceignore` or `spec.ignore` will unfortunately not help much with this. Some limitations can only be overcome by changing the data structure.
The `flux-system` is in the `main` branch of `kingdonb/fleet-infra`, as is the default. We prepared in advance, an empty commit with no parent in the same repository, on the `deploy` branch, so that this checkout would begin with an empty workspace that `ci/rake.sh` could copy the `output/` of jsonnet into.
The most generous characterization of this example as a whole that I can give, is that it is not regressive compared to the behavior of Flux v1's `fluxcd.io/automated`, that it would perform actually much better at scale, and at much lower cost in terms of control-plane and network overhead.
This is not technically regressive when compared to the behavior of Flux v1's `fluxcd.io/automated`, actually avoiding image pull depending on push instead to write the latest git tag, externally and functionally identical to how Flux v1 did automation. Little else is good that we can say about it.
It is a compatibility shim, to bridge the gap for Flux v1 users. If possible, users are encouraged to migrate to using timestamps, build numbers, or semantic version tags, all supported by [Flux v2 image automation](/guides/image-update/) features that are still in alpha at the time of this writing.
It is a compatibility shim, to bridge the gap for Flux v1 users. If possible, users are encouraged to migrate to using timestamps, build numbers, or semver tags, that are all supported by some [Flux v2 image automation](/guides/image-update/) features that are still in alpha at the time of this writing.
Flux's new [Image Automation Controllers](/components/image/controller/) are the new solution for Production use!