Validate failing to upgrade lock file locally on version change
DavOpz opened this issue · 3 comments
Describe the bug
Version (Local) - v1.91.0
Docker Image (GitHub Workflow) - ghcr.io/antonbabenko/pre-commit-terraform:v1.91.0
Running the following pre-commit hook steps
- terraform_validate
- terraform_providers_lock
Locally - The "terraform_validate" hook shows no issues and passes with Success, however it will then fail on "terraform_providers_lock" because - correctly - my .terraform.lock.hcl
refers to an old version of registry.terraform.io/hashicorp/azurerm
.
GitHub Workflow - When I run this same process via Github workflow, "terraform_validate" correctly flags the need to make changes and fails on the file diff.
Expected behaviour is parity between local and github workflow as they are using the same version, main expected behaviour is that locally the results seen in github would occur.
My main guess on what is happening is because my .terraform
dir is stored locally that the validate is working because the providers are present, however when running in github the files are not as they are in the .gitignore
, so it will then run terraform init
and this would have fixed the terraform.lock.hcl
file as well if it were able to write.
Request an option to force terraform init -upgrade
on hook terraform_validate
, this will make it possible to replicate the CICD environment by ensuring the init is performed the same as if there were no .terraform
files locally.
How can we reproduce it?
See section Files
for a copy of the files used, then perform the following steps
- Run
terraform init
to generate lockfile - Run
pre-commit run -a --color=always
and view the two hooks displayingPassed
- Update the
versions.tf
file from initial to the other file specified, changing the version of thehashicorp/azurerm
provider from3.103.1
to3.108.0
- Run
pre-commit run -a --color=always
and the validate will showPassed
however terraform lock will displayFailed
, there is no attempt to resolve and adding the--tf-init-args=-upgrade
arg to validate does not ensure the lock file will be updated prior to the next step failing.- Local Output
Terraform validate.......................................................Passed Lock terraform provider versions.........................................Failed - hook id: terraform_providers_lock - exit code: 1 - Fetching hashicorp/null 3.2.2 for darwin_arm64... - Retrieved hashicorp/null 3.2.2 for darwin_arm64 (signed by HashiCorp) ╷ │ Error: Could not retrieve providers for locking │ │ Terraform failed to fetch the requested providers for darwin_arm64 in order to calculate their checksums: some providers could not be installed: │ - registry.terraform.io/hashicorp/azurerm: locked provider registry.terraform.io/hashicorp/azurerm 3.103.1 does not match configured version constraint 3.108.0; must use terraform init -upgrade to allow selection of new versions.
- Comment out the
terraform_providers_lock
hook in.pre-commit-config.yaml
or you will be unable to commit to test the disparity in GitHub. - Push to a repository in GitHub to trigger the CICD, here the validate step will attempt to fix the file, as would be expected locally prior to getting to a PR run.
- CICD Output
Run pre-commit run -a --color=always pre-commit run -a --color=always shell: bash --noprofile --norc -e -o pipefail {0} [INFO] Initializing environment for https://github.com/antonbabenko/pre-commit-terraform. Terraform validate.......................................................Failed - hook id: terraform_validate - files were modified by this hook Command 'terraform init' successfully done: . Error: Process completed with exit code 1.
You can see that when ran locally terraform_validate
reports success because of the existence of the .terraform
, however running via CICD fails because when running the terraform init
it would be required to update the .terraform.lock.hcl
file, which it isn't doing on the local pre-commit hook.
Environment information
-
OS: MacOS Sonoma 14.3 M3 Pro
-
uname -a
and/orsysteminfo | Select-String "^OS"
output:
Darwin MacPro-F6WMC6WQG9 23.3.0 Darwin Kernel Version 23.3.0: Wed Dec 20 21:30:59 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T6030 arm64
- Tools availability and versions:
GNU bash, version 3.2.57(1)-release (arm64-apple-darwin23)
pre-commit 3.7.1
bash: line 3: tofu: command not found
Terraform v1.8.5
python SKIPPED
Python 3.12.3
checkov SKIPPED
Infracost v0.10.37
terraform-docs version v0.18.0 228c7a7 darwin/arm64
terragrunt version 0.59.3
terrascan version: v1.19.1
TFLint version 0.51.1
+ ruleset.terraform (0.7.0-bundled)
tfsec SKIPPED
trivy Version: 0.52.1
Check Bundle:
Digest: sha256:cfb65621a1f55d9d099c4c28931b252716fcda8bba5081eb43f1001668e79d85
DownloadedAt: 2024-06-14 08:38:10.74048 +0000 UTC
tfupdate 0.8.2
hcledit 0.2.11
Files
.pre-commit-config.yaml
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.91.0
hooks:
- id: terraform_validate
args:
- --hook-config=--retry-once-with-cleanup=true
- --tf-init-args=-upgrade
- id: terraform_providers_lock
args:
- --hook-config=--mode=always-regenerate-lockfile
.github/workflows/pre-commit.yml
name: pre-commit-terraform
on:
pull_request:
jobs:
pre-commit:
runs-on: ubuntu-latest
container:
image: ghcr.io/antonbabenko/pre-commit-terraform:v1.91.0
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- run: |
git config --global --add safe.directory $GITHUB_WORKSPACE
git fetch --no-tags --prune --depth=1 origin +refs/heads/*:refs/remotes/origin/*
- name: fix tar dependency in alpine container image
run: |
apk --no-cache add tar
# check python modules installed versions
python -m pip freeze --local
- name: Cache pre-commit since we use pre-commit from container
uses: actions/cache@v4
with:
path: ~/.cache/pre-commit
key: pre-commit-3|${{ hashFiles('.pre-commit-config.yaml') }}
- name: Execute pre-commit on all files
run: |
pre-commit run -a --color=always
.gitignore
# Local .terraform directories
**/.terraform/*
# .tfstate files
*.tfstate
*.tfstate.*
# Crash log files
crash.log
crash.*.log
# Exclude all .tfvars files, which are likely to contain sensitive data, such as
# password, private keys, and other secrets. These should not be part of version
# control as they are data points which are potentially sensitive and subject
# to change depending on the environment.
*.tfvars
*.tfvars.json
# Ignore override files as they are usually used to override resources locally and so
# are not checked in
override.tf
override.tf.json
*_override.tf
*_override.tf.json
# Include override files you do wish to add to version control using negated pattern
# !example_override.tf
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
# example: *tfplan*
# Ignore CLI configuration files
.terraformrc
terraform.rc
main.tf
resource "null_resource" "foo" {
triggers = {
example = var.project_name
}
}
variables.tf
variable "project_name" {
default = "default value"
type = string
description = "Example variable."
}
versions.tf (Initial File)
terraform {
required_version = "1.8.5"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "3.103.1"
}
null = {
source = "hashicorp/null"
version = "3.2.2"
}
}
}
versions.tf (Change to file after running commands specified)
terraform {
required_version = "1.8.5"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "3.108.0"
}
null = {
source = "hashicorp/null"
version = "3.2.2"
}
}
}
To add to this, I've just tried running terraform init -upgrade
locally to resolve this (and added back the other tests) and it all worked fine locally
Terraform fmt............................................................Passed
Terraform validate.......................................................Passed
Lock terraform provider versions.........................................Passed
Terraform validate with tflint...........................................Passed
Terraform validate with trivy............................................Passed
terrascan................................................................Passed
tfupdate.................................................................Passed
Terraform docs...........................................................Passed
However pushing to CICD shows the following
[INFO] Initializing environment for https://github.com/antonbabenko/pre-commit-terraform.
Terraform fmt............................................................Passed
Terraform validate.......................................................Failed
- hook id: terraform_validate
- files were modified by this hook
Command 'terraform init' successfully done: .
Lock terraform provider versions.........................................Passed
Terraform validate with tflint...........................................Passed
Terraform validate with trivy............................................Passed
terrascan................................................................Passed
tfupdate.................................................................Passed
Terraform docs...........................................................Passed
pre-commit hook(s) made changes.
If you are seeing this message in CI, reproduce locally with: `pre-commit run --all-files`.
To run `pre-commit` as part of git workflow, use `pre-commit install`.
All changes made by hooks:
diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl
index 1d61275..38a779c 100644
--- a/.terraform.lock.hcl
+++ b/.terraform.lock.hcl
@@ -6,6 +6,7 @@ provider "registry.terraform.io/hashicorp/azurerm" {
constraints = "3.108.0"
hashes = [
"h1:36WHCMjguUKG15iS3WNqmk2/FQH2AwFL0mJl0VWCfps=",
+ "h1:RIFBFTXz4X48JDHjbQHX4y400ax1/uEzMVFZgX3/z3w=",
"zh:2afecf948fd702bc08c87d9114595809d011f99a70a12dbf6bc67a12d0bee5fc",
"zh:395b6d1384a579867064e62d49b0b91e15919c33b03ea8b5031c2779bfa16b3d",
"zh:3e5594c59b6b02bc6e0f4c3de71aa2ab992494c53725fb3c64d36745f3814ef3",
@@ -26,6 +27,7 @@ provider "registry.terraform.io/hashicorp/null" {
constraints = "3.2.2"
hashes = [
"h1:IMVAUHKoydFrlPrl9OzasDnw/8ntZFerCC9iXw1rXQY=",
+ "h1:zT1ZbegaAYHwQa+QwIFugArWikRJI9dqohj8xb0GY88=",
"zh:3248aae6a2198f3ec8394218d05bd5e42be59f43a3a7c0b71c66ec0df08b69e7",
"zh:32b1aaa1c3013d33c245493f4a65465eab9436b454d250102729321a44c8ab9a",
"zh:38eff7e470acb48f66380a73a5c7cdd76cc9b9c9ba9a7249c7991488abe22fe3",
Error: Process completed with exit code 1.
I'm now thinking this is due to me creating the lockfile locally on a macbook and then running the tests in the linux container. Will try to confirm and close if so.
Yeah, apologies, worked it out, will close issue
Adding the following to .pre-commit-config.yaml
fixed the issue
- id: terraform_providers_lock
args:
- --hook-config=--mode=always-regenerate-lockfile
- --args=-platform=linux_amd64
- --args=-platform=darwin_arm64
I'm now thinking this is due to me creating the lockfile locally on a macbook and then running the tests in the linux container.
Yep, it is.