RMK uses Helmfile for the release management.
RMK uses a reduced set of the Helmfile
commands without changing their behavior.
The full list of commands can be found in the release category.
Additionally, flags are provided for the commands, which allow extending capabilities and help during the command execution debug.
For example:
rmk release build --selector app=name
rmk release sync --helmfile-log-level=debug --selector app=name
rmk release destroy
In a project repository, all the release values files are stored in the etc/<scope>/<env>/values/
directories.
For example:
etc/deps/develop/values/
etc/kodjin/staging/values/
The release values are inherited by the projects, e.g., the upstream project's values are included into the downstream project's values.
All releases.yaml
files controlling which releases are enabled/disabled are stored in the etc/<scope>/<env>/
directories.
For example:
etc/deps/develop/releases.yaml
The
releases.yaml
files are not inherited by the projects in contrast to the values. Each project should have itsreleases.yaml
files for all deployed scopes and envs. Running any of the commands in the release category will trigger the dependency resolution mechanism, as well as the check for the Kubernetes context for the current environment to prevent releases from being synchronized outside the environment context.
The release installation order is declared in helmfile.yaml.gotmpl
file.
rmk release list
rmk release template --selector app=traefik
rmk release sync --selector scope=deps
rmk release sync --selector app=redis --helmfile-args="--set='values.name=foo'"
rmk release destroy
Among the Helmfile
selectors, the following predefined keys
are provided out of the box:
- Release name.
- Release namespace.
- Chart name. For example:
rmk release sync --selector namespace=kube-system
It is possible to override any release value for the inherited project repository. You can override any element separately in its YAML file.
For example, you have the following file in the upstream project by the .PROJECT/dependencies/deps.bootstrap.infra-<version>/etc/deps/develop/values/metrics-server.yaml
path:
apiService:
create: true
extraArgs:
- --metric-resolution=10s
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --cert-dir=/tmp
resources:
requests:
cpu: 100m
memory: 200Mi
containerSecurityContext:
readOnlyRootFilesystem: true
extraVolumes:
- name: tmpdir
emptyDir: {}
extraVolumeMounts:
- name: tmpdir
mountPath: /tmp
Then you want to change the resources.requests.cpu
value of the develop
environment in your downstream project.
In this case, you don't need to copy the whole file but only change the concrete value by repeating the YAML path to it.
So, your file with the override will look like this:
resources:
requests:
cpu: 100m
You cannot override a part of an element if it is an array. If you want to override the name of the extraVolumeMounts field of the example file above, you cannot use the following content:
extraVolumeMounts: - name: tmpThe correct way to override is to provide the whole item of the array:
extraVolumeMounts: - name: tmp mountPath: /tmp
To check the final result, run the rmk release template
command and see the final YAML.
The rmk release update
command automates the process of updating and delivering releases
according to the version changes of artifacts (container images) following the GitOps methodology.
Since RMK is a binary file that can be downloaded and installed on any Unix-based CI/CD system, it can be integrated with almost any CI/CD system: GitHub Actions, GitLab, Drone CI, Jenkins, etc.
Prerequisites:
- The project repository has already been generated and prepared using RMK.
Create the following workflow in your project repository at .github/workflows/release-update.yaml
.
An example content of the GitHub Actions' workflow:
name: Release update
on:
workflow_dispatch:
inputs:
image_repository_full_name:
description: Image repository full name of application.
required: true
version:
description: Current application version.
required: true
jobs:
release-update:
runs-on: ubuntu-22.04
steps:
- name: Checkout main repository
uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
fetch-depth: 0
- name: Release update
env:
AWS_REGION: us-east-1
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
RMK_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN_REPO }}
RMK_SLACK_WEBHOOK: ${{ secrets.RMK_SLACK_WEBHOOK }}
RMK_SLACK_CHANNEL: project-cd-notifications
RMK_RELEASE_UPDATE_REPOSITORY: ${{ github.event.inputs.image_repository_full_name }}
RMK_RELEASE_UPDATE_TAG: ${{ github.event.inputs.version }}
run: |
curl -sL "https://edenlabllc-rmk-tools-infra.s3.eu-north-1.amazonaws.com/rmk/s3-installer" | bash
rmk config init --progress-bar=false --slack-notifications
rmk release update --skip-ci --deploy
In this example, we have prepared a GitHub Action
that expects two input parameters:
image_repository_full_name
version
As soon as a request with these parameters is sent to this action,
RMK will be executed, first analyzing all the releases.yaml
files to match the image_repository_full_name
and will replace the tag field
with the corresponding version if the versions differ.
After that, it will automatically commit the changes to the current branch in the releases.yaml
files where changes have been found.
Then, it will synchronize the releases where the version changes were found.
An example of the releases.yaml
file:
# ...
foo:
enabled: true
image:
repository: 123456789.dkr.ecr.us-east-1.amazonaws.com/app.foo
tag: v0.11.1
bar:
enabled: true
image:
repository: 123456789.dkr.ecr.us-east-1.amazonaws.com/app.bar
tag: v0.16.0
# ...
To make the code delivery process fully automatic on the CI pipeline's side, after building and pushing the container image to the image repository, add a step that triggers the deployment action and passes the container image repository's full name and its final tag. This can be done via an API call using cURL or through GitHub CLI. This way, we achieve automatic code delivery to the infrastructure environment.