Using a local Renovate bot to manage Ansible collection dependencies
We wanted to use renovate bot to automatically update collection dependencies for one of our Ansible playbook repositories. This blog post describes the basics of renovate, how we configured it and how we actually run renovate locally.
Understanding renovate
As this was our first try of using renovate for dependency updates, we struggled to understand how renovate works and how it is configured.
Renovate is a bot that is able to scan multiple repositories for dependencies and create pull/merge requests with updated dependencies.
Configuration is split between a configuration for the bot and a local one for each repository.
So you basically have
One or more global configuration files that configure the bot (config.js) written in JavaScript or TypeScript
One configuration file per repository (renovate.json) written in JSON that contains local configuration options just for this repository.
Renovate is very flexible on how to structure the configuration. For more information see config-overview in the docs.
Renovate also supports multiple platforms, like GitHub, GitLab or Forgejo. For a complete list see renovate platforms.
The idea is that you run the bot once, it scans all configured repositories and creates pull requests in every repository with dependency updates.
If your projects are hosted on GitHub and you would like to use GitHub Actions for running renovate the straight forward solution is to follow Mend Renovate on GitHub Marketplace.
But we wanted more control and tried to
run renovate on a local machine. This should be migrated to a Job Template or Kubernetes CronJob later (might be worth another post)
use a private Automation Hub for hosting dependencies. So renovate should query collections on our Private Automation Hub for dependency updates
credentials should be made available via environment variables to the bot
Configuring and running renovate
As a first test we created a local bot configuration file config.js in our home directory. The GIT repository we used for testing is https://github.com/tosmi-ansible/aap-setup.
The first thing to be aware of is that the renovate bot by default always searches the repository configuration file (renovate.json) in the upstream repository. Changes to local files are ignored.
One way to avoid this is using --platform=local. This actually uses the local renovate.json file, but has the caveat that not all renovate functionality is available.
But in our case this was good enough as we just wanted to test AAP Hub authentication.
It is also helpful to run renovate with debugging enabled, this dumps the configuration currently used to STDOUT.
For example we had the following renovate.json config for testing:
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:best-practices"
],
"timezone": "Europe/London",
"schedule": [
"at any time"
],
"packageRules": [
{
"matchDatasources": ["galaxy-collection"]
},
{
"matchDatasources": ["github-tags"],
"enabled": "false"
}
],
"hostRules": [
{
"matchHost": "aap.apps.hub.aws.tntinfra.net",
"token": "Token <the token>",
"authType": "Token-Only"
}
]
}But running renovate with LOG_LEVEL=debug set in the environment revealed the following settings:
DEBUG: Repository config (repository=tosmi-ansible/aap-setup)
"fileName": "renovate.json",
"config": {
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:recommended"]
}The configuration above is the configuration available in the remote GIT repository and not our local configuration.
| Renovate does not use a local renovate.json repository config by default. It always pulls the configuration from the remote repository except when you use _—platform=local. |
Furthermore renovate heavily relies on local caching. We wanted to test if renovate is using our hub token for connecting to the Hub, but we could not see any log entry in the AAP Hub container.
Renovate creates its cache files in a directory called baseDir. You can specify the location (and later wipe the cache) with the --base-dir option.
As we are using a self signed certificate in our AAP Hub test installation we had to specify NODE_TLS_REJECT_UNAUTHORIZED=0 to disable TLS verification.
To summarize our test configuration:
We used the following config.js global renovate configuration file:
module.exports = {
token: '<github token>',
platform: 'github',
onboardingConfig: {
extends: ['config:recommended'],
},
//repositories: ['tosmi-ansible/aap-setup'], (1)
};| 1 | Repository listing is not allowed when using --platform=local |
In the repository where we want to test automatic dependency updates we used the following renovate.json configuration:
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:best-practices"
],
"timezone": "Europe/London",
"schedule": [
"at any time"
],
"packageRules": [
{
"matchDatasources": ["galaxy-collection"]
},
{
"matchDatasources": ["github-tags"],
"enabled": "false" (1)
}
],
"hostRules": [
{
"matchHost": "aap.apps.hub.aws.tntinfra.net",
"token": "Token <the token>",
"authType": "Token-Only"
}
]
}| 1 | We disabled GitHub tag lookup explicitly as renovate would find some of our dependencies on GitHub |
This is our collections/requirements.yaml file with a test dependency:
roles:
collections:
- name: kubernetes.core
version: 6.3.0
source: https://aap.apps.hub.aws.tntinfra.net/api/galaxy/content/rh-certified/On our AAP Private Automation Hub we had kubernetes.core version 6.4.0 available.
So to run and test renovate locally we used the following command line:
NODE_TLS_REJECT_UNAUTHORIZED=0 LOG_LEVEL=debug RENOVATE_CONFIG_FILE=~/config.js renovate --platform=github --repository-cache=disabled --base-dir=/tmp/cacheSecret management and configuration cleanup
The next step is to remove the hard-coded tokens from our configuration. We wanted to use environment variables, as this allows us to run renovate as:
A Kubernetes CronJob with a Pod. We could inject the token via a Secret
As a job template within AAP with tokens stored as AAP credentials or
A normal Unix cron job with environment variables set
As the global renovate configuration config.js is written in JavaScript we could leverage process.env to retrieve required tokens from environment variables.
Here is our modified config.js:
module.exports = {
platform: 'github',
onboardingConfig: {
extends: ['config:recommended'],
},
// repositories: ['tosmi-ansible/aap-setup'], (1)
secrets: {
AAP_HUB_TOKEN: process.env.AAP_HUB_TOKEN, (2)
},
hostRules: [
{
matchHost: "aap.apps.hub.aws.tntinfra.net",
token: "{{ secrets.AAP_HUB_TOKEN }}", (3)
authType: "Token" (4)
},
],
};| 1 | We disable repository listing for --platform=local. Otherwise renovate will raise an error. |
| 2 | We define a new secret AAP_HUB_TOKEN and read the value from the environment variable AAP_HUB_TOKEN |
| 3 | We use the secret as our token for authenticating to AAP Hub |
| 4 | The authType setting is a little bit special, see the following section |
A few words about the authType setting. AAP Hub requires the following authorization header in the HTTP request for authentication:
Authorization: Token <the token>With renovate we have two options to achieve this:
Either set authType to "Token-Only" and specify the token as "Token <the token>". So with token-only renovate takes the token string verbatim
Or set the authType to the string we would like to prepend to the token as we did
We had to dig into the source code of renovate to understand how it functions.
And here is the renovate.json repository configuration that we used:
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:best-practices"
],
"timezone": "Europe/London",
"schedule": [
"at any time"
],
"packageRules": [
{
"matchDatasources": ["galaxy-collection"]
},
{
"matchDatasources": ["github-tags"],
"enabled": "false"
}
]
}You could also move the hostRules to the repository local renovate.json file and still use secrets.AAP_HUB_TOKEN, but as this is going to be our global configuration for Ansible code base covering multiple repositories our current idea is to store the authentication in the global configuration.
Integration with GitHub
So the last step is to store everything (the global and local configuration) on GitHub.
For the global repository we created the tosmi-ansible/renovate-config repository.
Here is our final config.js global configuration file in this repository:
module.exports = {
platform: 'github',
gitAuthor: "Renovate Bot <renovate-bot@stderr.at>",
dryRun: null,
onboardingConfig: {
extends: ['config:recommended'],
},
repositories: ['tosmi-ansible/aap-setup'], (1)
secrets: {
AAP_HUB_TOKEN: process.env.AAP_HUB_TOKEN,
},
hostRules: [
{
matchHost: "aap.apps.hub.aws.tntinfra.net",
token: "{{ secrets.AAP_HUB_TOKEN }}",
authType: "Token"
},
],
};| 1 | This time we tell renovate which repositories it should scan. |
The default configuration default.json, also stored in the global repository:
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:best-practices"
],
"timezone": "Europe/London",
"schedule": [
"at any time"
],
"enabledManagers": ["ansible", "ansible-galaxy"], (1)
"packageRules": [
{
"matchDatasources": ["galaxy-collection"]
},
{
"matchDatasources": ["github-tags"],
"enabled": "false"
}
]
}| 1 | We only enable ansible and ansible-galaxy managers. Otherwise renovate would search for various other sources for dependencies. |
tosmi-ansible/aap-setup contains our local configuration:
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"tosmi-ansible/renovate-config",
"config:best-practices"
]
}This only contains a reference to our global configuration and we would like to use the best-practices preset.
We can now run renovate from the renovate-config repository and it will scan the configured repository and create a pull request with updated dependencies if required.
$ git clone git@github.com:tosmi-ansible/renovate-config.git
$ cd renovate-config
$ NODE_TLS_REJECT_UNAUTHORIZED=0 renovate --platform=github --base-dir=/tmp/renovate-cache (1)| 1 | We still need to set NODE_TLS_REJECT_UNAUTHORIZED to 0, because our AAP Hub instance uses a private certificate |
One minor issue that we discovered is that if a pull request for an update already existed (even a closed one) Renovate would not open a new one. If you run renovate with LOG_LEVEL=debug you will see the following message:
DEBUG: Closed PR #19 already exists. Skipping branch. (repository=tosmi-ansible/aap-setup, branch=renovate/kubernetes.core-6.x)
"prTitle": "Update dependency kubernetes.core to v6.4.0"To convince Renovate to create a new pull request just rename the closed pull request on GitHub. We just added the prefix "RENAMED". After renaming the pull request, renovate will happily create a new one.
Copyright © 2020 - 2026 Toni Schmidbauer & Thomas Jungbauer


Discussion
Comments are powered by GitHub Discussions. To participate, you'll need a GitHub account.
By loading comments, you agree to GitHub's Privacy Policy. Your data is processed by GitHub, not by this website.