How should we be using dependency lock files in CI

Hi there!

I’m interested to know how terraform suggest we should be using lock files alongside a CI solution. I understand that the idea of a dependency lock is to allow the dependency versions to be consistent when running terraform. Naturally, I would expect a lock file to be committed into the code base, so that when a CI tool then clones the repo and runs terraform, the dependencies that are selected are predictable.

The confusion comes here when we start using a CI tool for all runs of terraform. Let me explain the use-case in more detail:

We don’t want engineers download or store service account keys on their local machines to use to run plans while developing. Therefore, engineers don’t run plans locally, instead they push code to a VCS branch, and the CI tool will then run a plan and generate an output for the engineer to view. This is great because all our service accounts are kept secure, and we don’t need to grant our engineers any permissions (following concept of least privileged access).

However, this means that we never commit any changes to the lock file, because the CI doesn’t commit anything into VCS (and this would seem overly complicated to set up), and an engineers never runs terraform locally.

What is the suggested way to use lock files with CI? Are we doing something drastically wrong here? Or should we just ignore lock files completely and specifically set exact versions in our terraform code? It would be good to get some opinions / examples of how other people are using terraform locks!

Thanks in advance!

We currently exclude the lock file (via .gitignore) and set the exact versions in the required_providers block.

Hi @finlay.evans,

I would suggest thinking of the dependency lock file as part of the source code that your developers are submitting to test, rather than an artifact of the remote planning process.

Specifically, I would expect your developers to update the lock file on their local systems and submit that to the VCS branch along with whatever other changes they are intending to test.

If your concern is that the developers don’t have suitable credentials to initialize the backend, you could potentially avoid that problem by having the developers run terraform init -backend=false, so that Terraform will install all of the necessary dependencies and update the lock file but will skip trying to initialize the backend. That partial initialization should also allow them to use other commands that work only with the configuration (not the state), such as terraform validate as a way to get quick feedback on simple validation errors before pushing up the branch for speculative planning.

1 Like