Managing dependencies is critical to the software development lifecycle (SDLC), ensuring that your project stays up-to-date with the latest features and security fixes.
Dependabot is a popular tool for automating dependency updates, and OpenTofu, is an open-source tool for managing IaC and can be integrated with it to keep your infrastructure configurations current.
This blog post will explore how to set up and use OpenTofu with Dependabot.
Repository structure
You can find the code here.
├── .devcontainer
│ ├── Dockerfile
│ └── devcontainer.json
├── .github
│ ├── dependabot.yaml
│ └── workflows
│ ├── jekyll-gh-pages.yml
│ └── module_version.yaml
├── README.md
├── environments
│ ├── dev
│ │ └── main.tf
│ ├── prod
│ │ └── main.tf
│ └── stage
│ └── main.tf
└── modules
└── network
├── main.tf
├── provider.tf
└── variables.tf
Lately, I’ve become a big fan of codespaces, so I always have my .devcontainer
folder with my custom configuration for my codespace.
In the .github
directory, we have the workflows that run for this repository:
dependabot.yaml — Here we configure dependabot’s behavior
jekyll-gh-pages.yml — GitHub pages for this repository (not required by this automation, but still, a more beutiful way to go through the documentation)
module_version.yaml — Module tagging workflow
In the environments
directory, we have OpenTofu configurations for three environments: dev
, stage
and prod
.
In the modules
folder we will keep all of our OpenTofu modules. In this example, we only have one network module.
How it works
The network module has only one job right, and that job is creating VPCs:
resource "aws_vpc" "this" {
for_each = var.vpcs
cidr_block = each.value.cidr_block
tags = merge({
Name = each.key
}, each.value.tags)
}
This module is called in each environment with a specific version tag:
provider "aws" {
region = "eu-west-1"
}
module "network" {
source = "git::ssh://git@github.com/flavius-dinu/tofu_dependabot.git//modules/network?ref=network-v0.0.7"
vpcs = {
vpc1 = {
cidr_block = "10.0.0.0/16"
}
}
}
Whenever there is a change to the module, a new tag will be created by this GitHub Actions workflow.
Tags will be in the following format network-version
:
For GitHub Actions to be able to push these new tags, I have provided my Personal Access Token (PAT) as a secret to my repository:
In the dependabot configuration, we’ve specified the tool we are using, the directory in which dependabot should look for dependencies and the running interval.
version: 2
updates:
- package-ecosystem: "terraform"
directory: "/environments/dev"
schedule:
interval: "daily"
allow:
- dependency-type: "all"
- package-ecosystem: "terraform"
directory: "/environments/stage"
schedule:
interval: "weekly"
allow:
- dependency-type: "all"
- package-ecosystem: "terraform"
directory: "/environments/prod"
schedule:
interval: "weekly"
allow:
- dependency-type: "all"
Dependabot can only run on a schedule, so if a new tag is created, dependabot will not automatically pick it up and make changes for you until the schedule is met.
Example run
I will first make a change to the network module to have a new tag created. As soon as I push my changes, the GitHub Actions workflow that automatically creates a tag, will be triggered:
After a couple of seconds, this finishes, and the new tag gets created:
Now, we could either wait for Dependabot to pick up the change based on the schedule, or we could easily trigger a run ourselves.
To do that, we can easily go to the Insights tab, select Dependency graph, and then choose Dependabot.
By clicking on any of the jobs on the Recent update jobs
, we can easily trigger Dependabot to check for updates:
As soon as we do that for the dev workflow, a GitHub actions workflow will be triggered that will automatically trigger a PR to update the dev environment’s module version:
As soon as this job finishes, the PR will be created:
Let’s check what is will this PR modify:
As you can see, the only change it makes is modifying the module version.
I am ok with this change so I can easily merge the PR:
You could potentially create a GitHub Actions workflow that runs on a cron that will trigger dependabot to identify any changes made to your modules, but having a daily trigger for the lower environments and a daily/weekly one for superior ones makes more sense.
If you want to see it in action, check out this video:
Key Points
Integrating OpenTofu with Dependabot streamlines the process of keeping your infrastructure as code up-to-date, ensuring you always have the latest features and security fixes.
With the setup described in this post, you can automate the process, saving time and reducing manual effort. Happy coding!