How to Keep Everything Up to Date
Problem DRAFT
Your infrastructure is composed of dozens, if not hundreds, of components and applications. Their configurations span multiple tools (docker
, helm
, packages
) and configuration file formats (e.g. Dockerfile
, stacks/catalog/cert-manager.yaml
and default.auto.tfvars
). Industry best practice is to use strict version pinning in order to maintain stable infrastructure. However, this shifts the burden of keeping everything current onto the developer. So, we need some way to automate the update process, in order to reduce the developer’s burden and, as a result, reduce long-term tech debt by staying current.
Solution
Use Renovatebot to automatically open Pull Requests when new versions of dependencies are available. Rennovatebot is a free and fully hosted solution that is much more powerful than https://github.com/dependabot by GitHub.
First, install the renovate.json
config file into your repo:
https://github.com/cloudposse/renovatebot-testing-2/blob/review-branch/.github/renovate.json
Second, add # renovate
annotations to your code as detailed below in the Examples
section. Although annotations may not be necessary for some dependencies (our renovate.json
file does try to identify common dependency patterns, even in the absence of an annotation), we do recommend that you annotate where possible.
For conventions on keeping packages from specific data sources (e.g., Helm releases, or Docker images) updated, please see the Data Sources
section below.
For details on pinning package versions to a pre-specified range, see the Version Pinning
section below.
Examples
Dockerfile
Automatically update base images in Dockerfiles.
# renovate: datasource=docker depName=cloudposse/geodesic registryUrl=public.ecr.aws versioning=docker
ARG GEODESIC_VERSION=0.146.5
ARG OS=debian
FROM public.ecr.aws/cloudposse/geodesic:$GEODESIC_VERSION-$OS
Automatically update ARG
and ENV
statements for package pinning in Dockerfiles.
# renovate: datasource=github-releases depName=cloudposse/atmos versioning="regex:(?<major>0)\\.(?<minor>21)\\.(?<patch>\\d+)"
ARG ATMOS_VERSION=1.51.0
# renovate: datasource=github-releases depName=cloudposse/atmos
ARG TERRAFORM_VERSION=1.0.4
# renovate: datasource=docker depName=cloudposse/awesome-image versioning=docker registryUrl=docker.io/images
ENV DOCKER_VERSION=19.03.1
# renovate: datasource=helm depName=echo-server registryUrl=https://helm.sh/charts
ENV ECHO_SERVER_VERSION=1.19.1
Automatically update packages based on cargo
versioning scheme.
https://docs.renovatebot.com/modules/versioning/#cargo-versioning
# Install terraform
# Install specific versions of Terraform. Must match versions in Spacelift terraform_version_map
# in components/terraform/spacelift/default.auto.tfvars
# renovate: datasource=github-releases depName=hashicorp/terraform versioning="regex:v?(?<major>0)\\.(?<minor>12)\\.(?<patch>\\d+)"
ARG TF_12_VERSION=0.12.30
# renovate: datasource=github-releases depName=hashicorp/terraform cargo=">=0.13.0 <0.14.0"
ARG TF_13_VERSION=0.13.6
# renovate: datasource=github-releases depName=hashicorp/terraform cargo=">=0.14.0 <0.15.0"
ARG TF_14_VERSION=0.14.7
# renovate: datasource=github-releases depName=hashicorp/terraform cargo=">=0.15.0 <0.16.0"
ARG TF_15_VERSION=0.15.4
# renovate: datasource=github-releases depName=hashicorp/terraform cargo=">=1.0.0 <1.1.0"
ARG TF_1_0_VERSION=1.0.2
RUN apt-get update && apt-get install -y -u --allow-downgrades \
terraform-0.12="${TF_12_VERSION}-*" terraform-0.13="${TF_13_VERSION}-*" \
terraform-0.14="${TF_14_VERSION}-*" terraform-0.15="${TF_15_VERSION}-*" \
terraform-1="${TF_1_0_VERSION}-*"
Terraform .tfvars
Automatically update helm charts in terraform var files.
enabled = true
name = "datadog"
description = "Datadog Kubernetes Agent"
kubernetes_namespace = "monitoring"
create_namespace = true
repository = "https://helm.datadoghq.com"
chart = "datadog"
# renovate: datasource=helm depName=datadog registryUrl=https://helm.datadoghq.com
chart_version = "2.22.10"
timeout = 180
wait = true
atomic = true
cleanup_on_fail = true
Stack Configurations
Automatically update docker images.
components:
terraform:
metrics-server:
settings:
spacelift:
workspace_enabled: true
vars:
enabled: true
values:
image:
repository: "k8s.gcr.io/metrics-server/metrics-server"
# renovate: datasource=docker depName=metrics-server/metrics-server versioning=docker registryUrl=k8s.gcr.io
tag: "v0.3.7"
pullPolicy: IfNotPresent
Automatically update the cluster_kubernetes_version
components:
terraform:
eks:
settings:
spacelift:
workspace_enabled: true
vars:
# renovate: datasource=github-releases depName=kubernetes/kubernetes
cluster_kubernetes_version: "1.20"
node_groups:
main:
# values of `null` will be replaced with default values
# availability_zones = null will create 1 auto scaling group in each availability zone of region
availability_zones: null
desired_group_size: 3 # number of instances to start
Data Sources
Supported conventions:
GitHub Releases
# renovate: datasource=github-releases depName=cloudposse/atmos cargo=">=1.2.3 <2.0.0"
Helm Releases
# renovate: datasource=github-releases depName=cloudposse/atmos cargo=">=1.2.3 <2.0.0"
Docker Tags
# renovate: datasource=github-releases depName=cloudposse/atmos cargo=">=1.2.3 <2.0.0"
Terraform Modules
(terraform modules are handled automatically without our rules)
Terraform Components
Terraform components cannot be updated at this time using this strategy; however, the terraform modules referenced in your components will be automatically updated.
GitHub Actions
https://docs.renovatebot.com/modules/manager/github-actions/
Version Pinning
To pin a package to a given version range, simply add a field of the form version="regex:v?(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)"
to that package’s renovate annotation, specifying the desired major/minor versions. For example, to pin a package to the 1.x.x
release range, you would use version="regex:v?(?<major>1)\\.(?<minor>\\d+)\\.(?<patch>\\d+)"
; similarly, to pin a package to the 2.1
release range, you would use version="regex:v?(?<major>2)\\.(?<minor>1)\\.(?<patch>\\d+)"
.