Alors que nous entreprenons tous ensemble le voyage vers l'alignement sur les principes de GitOps, je suis sûr que nous pouvons tous nous souvenir du moment où nous avons initialement utilisé ArgoCD pour déployer notre première application sur un cluster Kubernetes via GitOps. Chez Virtru, nous avons adoré la facilité avec laquelle GitOps a rendu la gestion des applications et la rapidité avec laquelle il nous a permis de bouger tout en gardant tous nos environnements continuellement synchronisés.
Nous savons tous qu'après le premier déploiement, il y a cette hâte et ce besoin d'agir rapidement. Avant que vous ne le réalisiez, vous avez de nombreux composants déployés sur vos clusters, par exemple
Il semble que chaque semaine, un nouvel outil vienne combler une lacune. Avoir toutes ces options est formidable, mais l'introduction de chacune d'entre elles ajoute à la liste croissante des composants à gérer.
La sécurité est au cœur de Virtru, et lorsque vous travaillez dans une entreprise où c'est le cas, vous devez vous assurer que tous les composants que vous utilisez sont mis à jour en temps voulu. Cependant, nous ne voulons pas non plus introduire de problèmes dans l'environnement.
Prenons un peu de recul et réfléchissons à ce qu'il faut faire pour gérer chaque composant. Pour chaque composant, vous devez:
Cela devient rapidement une responsabilité à plein temps pour un membre de l'équipe. Nous avions besoin de réduire une partie du labeur inutile de notre équipe chez Virtru.
Typiquement, pour gérer les dépendances, vous pouvez vous tourner vers quelque chose comme Dependabot. Dans notre cas, nous avions besoin de quelque chose qui puisse gérer plus que les versions des paquets npm ou go typiques. Nous avions besoin de gérer les versions de nos cartes de barre définies dans une application ArgoCD ainsi que nos fournisseurs et modules Terraform.
C'est pourquoi nous avons commencé à chercher dans la communauté pour voir s'il existait une technologie existante que nous pourrions exploiter ou décider si nous devions construire quelque chose par nous-mêmes.
Et voilà, nous n'étions pas les seuls à penser à ce problème !
Renovate est un outil permettant de gérer les mises à jour automatisées des dépendances. Il est open-source et s'intègre à divers systèmes de contrôle de version, dont GitHub et GitLab. Il y a deux façons d'installer Renovate : via l'application GitHub ou en auto-hébergement.
Nous voulions avoir plus de contrôle sur la façon dont nous exécutons Renovate, et quelle version est déployée. Cela nous a limité à l'application auto-hébergée. Nous voulions l'exécuter dans Kubernetes. Renovate est disponible en tant que conteneur à partir de DockerHub ou vous pouvez aussi facilement construire votre propre image de conteneur en installant l'application à partir de NPM, qui est la route que nous avons choisie pour avoir le plus de contrôle sur la configuration de Renovate.
Renovate est déployé dans les clusters Virtru comme un CronJob. Notre configuration est similaire aux exemples de la documentation officielle :
apiVersion: v1
kind: ConfigMap
metadata:
name: renovate-config
namespace: renovate-test
data:
config.json: |-
{
"repositories": ["<your-org>/<your-repo-1>, <your-org>/<your-repo-2>"]
}
---
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: renovate-bot
namespace: renovate-test
spec:
schedule: "@hourly"
concurrencyPolicy: Forbid
jobTemplate:
spec:
template:
spec:
containers:
- image: renovate/renovate:31.14.0
name: renovate-bot
env:
- name: RENOVATE_PLATFORM
value: "github"
- name: RENOVATE_AUTODISCOVER
value: "false"
- name: RENOVATE_BASE_DIR
value: "/tmp/renovate/"
- name: RENOVATE_CONFIG_FILE
value: "/opt/renovate/config.json"
- name: LOG_LEVEL
value: debug
- name: RENOVATE_TOKEN
valueFrom:
secretKeyRef:
key: github-token
name: renovate-secrets
volumeMounts:
- name: config-volume
mountPath: /opt/renovate/
- name: work-volume
mountPath: /tmp/renovate/
restartPolicy: Never
volumes:
- name: config-volume
configMap:
name: renovate-config
- name: work-volume
emptyDir: {}
Ce manifeste suppose que l'espace de noms Renovate contient un secret Kubernetes appelé renovate-secrets, avec la clé github-token et la valeur d'un jeton API GitHub valide. Les permissions du token doivent être repo read/write. Vous pouvez créer le secret comme suit :
❯ kubectl create -n renovate secret generic renovate-secrets
--from-literal=github-token=<token>
Aussi flexible qu'il soit, Renovate est facile à prendre en main. Il offre la découverte automatique des dépôts. Cependant, une plus grande organisation voudrait l'omettre, puisque cette fonctionnalité fait que Renovate s'exécute sur chaque dépôt auquel la clé API GitHub a accès. Une alternative à la découverte automatique est la directive repository list dans le fichier de configuration de Renovate. L'embarquement pour chaque dépôt est également automatisé. Renovate soumet des demandes de pull avec un fichier de configuration par défaut pour ce dépôt.
La configuration la plus simple pour un dépôt GitHub privé ressemble à ceci :
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json"
}
Ceci indique à Renovate d'utiliser la configuration par défaut, qui est un bon endroit pour commencer.
Vous pouvez également ajouter des étiquettes pour filtrer facilement les RP créés par Renovate :
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"labels": ["renovate"]
}
Ainsi, tous les PR seront étiquetés comme "rénovés".
Ignorer certains chemins peut également être utile lorsqu'un projet comporte des parties qui ne sont pas prêtes à accepter des mises à jour. Par exemple, voici comment ignorer tout ce qui se trouve dans le dossier "/argocd/sandbox" :
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"ignorePaths": [
"argocd/sandbox/**"
]
}
Spécifier des règles de paquetage personnalisées est crucial pour tout référentiel de taille décente. Ces règles indiquent à Renovate comment appliquer un élément de configuration à un certain nombre de fichiers/paquets sélectionnés. La cible peut être choisie en fonction d'un ensemble de sélecteurs, y compris le chemin et le gestionnaire.
Parlons plus en détail des "managers", qui sont l'abréviation de "gestionnaires de paquets". Il s'agit notamment des gestionnaires de paquets traditionnels comme npm, Gradle et Bundle, ainsi que des formats de fichiers moins traditionnels, comme les Dockerfiles ou les manifestes ArgoCD. Les gestionnaires sont utilisés pour détecter et maintenir les fichiers dans un référentiel.
En fait, la configuration minimale du projet ArgoCD nécessite l'utilisation des règles de paquetage personnalisées, car par défaut, le gestionnaire ArgoCD ne définit aucun modèle de correspondance de fichiers, et ne correspondra donc à aucun fichier tant que le modèle n'aura pas été configuré.
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"packageRules": [
{
"matchManagers": [
"argocd"
],
"matchPaths": [
"argocd/production/**",
"argocd/development/**",
"argocd/staging/**"
],
}
]
}
La configuration ci-dessus permettra de gérer les manifestes ArgoCD dans le projet avec la structure suivante :
└── argocd
├── development
├── production
└── staging
Les règles personnalisées dans la liste des règles de paquetage ont une priorité plus élevée que les règles globales. De cette façon, vous pouvez redéfinir la configuration globale dans les règles personnalisées. Par exemple, vous pouvez écraser l'étiquette globale "green" pour tous les fichiers ArgoCD dans le chemin "argocd/production" :
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"labels": ["green"],
"packageRules": [
{
"matchManagers": [
"argocd"
],
"matchPaths": [
"argocd/production/**"
],
"labels": ["red"]
},
{
"matchManagers": [
"argocd"
],
"matchPaths": [
"argocd/staging/**",
"argocd/development/**"
]
}
]
}
L'exemple précédent illustre également la façon dont vous pouvez établir une correspondance sur la base de plusieurs facteurs. Dans ce cas, il s'agissait de managers et de chemins.
Il est parfois utile de regrouper certains des objets qui ont été mis en correspondance. Cela peut être réalisé à l'aide de la directive groupName. Toutes les mises à jour correspondantes partageant le nom du groupe seront placées dans la même branche et le même PR. Le regroupement de toutes les mises à jour de versions non majeures peut se faire comme suit :
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"packageRules": [
{
"matchManagers": ["argocd"],
"matchUpdateTypes": ["minor", "patch", "pin", "digest", "lockFileMaintenance", "rollback", "bump"],
"groupName": "argocd non-major updates"
},
{
"matchManagers": ["argocd"],
"matchUpdateTypes": ["major"]
}
]
}
Enfin, vous pouvez définir une planification personnalisée pour un référentiel. Ce paramètre était essentiel pour nous, et nous avons fini par l'activer pour chaque référentiel géré par renovate. Une planification basée sur le référentiel nous a permis de lancer renovate toutes les 15 minutes, sans nous soucier de faire tourner une quantité excessive de tâches CI/CD ou de créer d'autres activités indésirables déclenchées par des événements GitHub.
Les syntaxes Cron et Later peuvent être utilisées pour configurer la planification. Certains préréglages sont également pris en charge. Quand une planification est utilisée, Renovate ne créera plus de nouveaux PRs. Cependant, vous devez désactiver la valeur updateNotScheduled afin d'activer les PRs existants.
Voici un exemple de planning mensuel sans mise à jour des PRs existants :
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"schedule": [
"before 3am on the first day of the month"
],
"updateNotScheduled": false
}
Comme vous pouvez le voir, Renovate apporte une pléthore d'options de configuration et fournit la flexibilité dont toute équipe pourrait avoir besoin.
Renovate a aidé à résoudre cette première étape dans le processus de gestion du cycle de vie qui consiste à vérifier s'il y a une nouvelle version. En couplant étroitement les notes de version aux demandes de retrait, il est plus facile pour l'équipe de vérifier ce qui a changé.
Pour l'instant, tout ce qui suit Rénovation est encore manuel, mais nous prévoyons de franchir quelques étapes supplémentaires :
Gardez l'œil ouvert pour d'autres articles de la série Virtru Technical Series de l'équipe d'ingénierie de la plateforme Virtru, car nous continuons à explorer et à mettre en œuvre ces étapes supplémentaires.
Contact us to learn more about our partnership opportunities.