Dependabot: Automatically Update Your Terraform (Eps: 1)
Let Dependabot update your hardcoded dependency file version
When managing software and repositories, we often deal with the version of third-party tools, dependencies, or libraries we use. The library's latest version guarantees improved security and more features provided. Even though updating the library seems like an easy task, cause all you have to do is just edit the hardcoded version file (for example, in Terraform, all you have to do is just edit the required_version
block value). But the problem is when we have a bunch of files with hardcoded versions that we need to manage, it will take a lot of time to edit those files, and believe me, it's so frustrating (even though I haven’t done it yet, cause see the files enough to make me feel dizzy 😵).
So, to handle this problem, I guess there are many approaches we can take. Still, in this article, I will give you the approach I take to handle this kind of problem by using automation tools, specifically GitLab Dependabot. There is plenty of other automation tools for updating dependency versions like Renovate and Depfu, but for now, let’s dive in with GitLab Dependabot first. And one thing, we will implement this using Terraform as our dependency that we want to upgrade and GitLab as our repository and for setup the CI pipeline. So our goals will be:
- Configure dependabot to update Terraform version
- Configure the CI pipeline to run the dependabot
Dependabot 🤖
I’m not going to talk too much about Dependabot because many articles are already discussing this tool. One thing to note is that Dependabot initially only ran in GitHub, but thankfully now there is the GitLab implementation, which is what we will be using.
Prerequisites
- A file called
dependabot.yml
placed inside a folder called.gitlab
- A CI/CD file called
.gitlab-ci.yml
to help us run the Dependabot automatically
- A GitLab runner (or you can use shared Runner)
- A Terraform file with version configuration inside it (both Terraform version and provider version)
[1] Configure Our Files
Let’s start our journey by setting up our files. The first is the Terraform version.tf
file, placed inside a folder /src
. This file's purpose is only to become our “Guinea pig”. My terraform file looks like
If you look closely at this, the google, helm, and Kubernetes providers' versions are already outdated. The latest google version is version 4.29.0, the helm is 2.6.0, and Kubernetes is 2.12.1. And for required_version
which is the Terraform version is already outdated, too. The latest version is 1.2.5
Next, we have our dependabot.yml
file placed inside a folder .gitlab
The Dependabot file must have 2 parts which are the version and updates. Here is the explanation about that file, or you can see the full list of the options here in the documentation:
- version tells what dependabot version we currently use
- updates part contains the configuration rules for updating the dependency.
- package-ecosystem tells what package (dependency) version we want to update. Here we specify that we want to update the terraform dependency.
- directory is the place where hardcoded dependency version files live. Because we placed our
version.tf
file inside the/src
folder, so we set the directory option to point to our/src
folder. - interval, as its name tell, specify the interval to run the version update check
- time and timezone used to set up the time when the dependabot run.
- open-pull-request-limit, is to restrict the number of pull requests that dependabot can make. If there is a new version of the dependency we define, the dependabot will create a new pull request. Let’s say we have 3 providers in our Terraform, and those 3 providers are already outdated, so dependabot will open 3 separate pull requests for each provider.
So, in short, this file in one sentence can be interpreted as:
“I want to update my Terraform version, that I have defined inside /src folder every day at 23:00 with Asia/Jakarta timezone and in every update scanning I will limit dependabot only to open maximum 3 pull request”
And the last file that we need to configure is the .gitlab-ci.yml
which is intended to run our CI pipeline, and inside the CI pipeline, we will run the dependabot update checking as our job. This is the configuration.
Nothing special there. It’s just a simple pipeline configuration taken from the dependabot-gitlab page.
[2] Prepare The GitLab Runner
I’m not going to give you a tutorial on setting up a GitLab runner here, but I want to ensure that you have a runner in your repo. (Maybe in the future, I will make a tutorial on how to do this)
[3] Set GitLab CI Variables
Go to GitLab CI/CD setting page and set these variables:
- BRANCH
- PROJECT_PATH
- PACKAGE_MANAGER_SET
- SETTINGS__GITHUB_ACCESS_TOKEN
- SETTINGS__GITLAB_ACCESS_TOKEN
[4] Wait For The Sweet Pull Requests!
Now, all you have to do is push your changes and wait for the runner to run the dependabot pipeline. After successfully running the pipeline, dependabot will automatically create a new Pull Request to update the Terraform version.
However, something bad still happens. The dependabot successfully made pull requests to update the providers' version, but it failed for the Terraform version (the one required_version
in the last line of ourversion.tf
file). I don’t know why this happened, but I guess it's related to how dependabot works. Dependabot works by scanning the .lock
file of a dependency, and if you take a look at the .terraform.lock.hcl
file, there are provider versions like we define in the version.tf
file, but there is norequired_version
there. I’m not sure if that is the cause, but I have good news for you. We can solve this problem by using another auto dependency update tool I have told you about, Renovate. I will explain the steps in the next article soon.
Thank you for reading this article about dependabot, and have a nice day 😁