terragrunt icon indicating copy to clipboard operation
terragrunt copied to clipboard

`providers lock` are broken with multiple platforms

Open dmattia opened this issue 4 years ago • 9 comments

In a directory that does not yet have a lock file, I am running terragrunt providers lock -platform=darwin_amd64 -platform=linux_amd64 and am noticing the error:

- Fetching hashicorp/aws 3.26.0 for darwin_amd64...
- Obtained hashicorp/aws checksums for darwin_amd64 (signed by HashiCorp)
- Fetching hashicorp/aws 3.26.0 for linux_amd64...

Error: Could not retrieve providers for locking

Terraform failed to fetch the requested providers for linux_amd64 in order to
calculate their checksums: some providers could not be installed:
- registry.terraform.io/hashicorp/aws: the current package for
registry.terraform.io/hashicorp/aws 3.26.0 doesn't match any of the checksums
previously recorded in the dependency lock file.

ERRO[0015] Hit multiple errors:
Hit multiple errors:
exit status 1

I believe that this is caused because terragrunt init is run first via auto-init, which creates a lock file, which then prevents the providers lock command from working because it tries to download providers for a platform different than the one that gets put into the lockfile during auto-init.

The only solution I can see here is to:

  • terragrunt init to create a .terragrunt-cache folder to run terraform commands in
  • rm .terraform.lock.hcl to remove the lock file
  • terragrunt providers lock -platform=darwin_amd64 -platform=linux_amd64 to create a lockfile with both platforms present

Ideally, I think that providers lock commands should work with auto-init turned off, as init is not required in terraform to run the providers lock commands. And on that topic, there never seems to be reason that providers lock commands should use auto-init, so if there's a way to not use auto-init for these commands that would be great

dmattia avatar Feb 04 '21 07:02 dmattia

Tracking a list of commands that should never run auto-init seems reasonable. We're buried with other initiatives, but if anyone wants to try to implement this that would be much appreciated.

That said, as a current workaround, does https://terragrunt.gruntwork.io/docs/reference/cli-options/#terragrunt-no-auto-init work?

yorinasub17 avatar Feb 05 '21 14:02 yorinasub17

@dmattia actually terraform provider lock command cannot run before init if you're referencing other modules, see https://github.com/hashicorp/terraform/issues/27161#issuecomment-741636560

the only current workaround is the one you stated. I automated it using terragrunt hooks and it works well with init, providers and run-all commands:

  # used for `terragrunt providers`
  before_hook "providers_remove_.terraform.lock.hcl" {
    commands     = ["providers"]
    execute      = ["rm", ".terraform.lock.hcl"]
    run_on_error = false
  }

  # used for `terragrunt init`
  after_hook "init_remove_.terraform.lock.hcl" {
    commands     = ["init"]
    execute      = ["rm", ".terraform.lock.hcl"]
    run_on_error = false
  }

  after_hook "init_lock_providers" {
    commands     = ["init"]
    execute      = ["terraform", "providers", "lock", "-platform=linux_amd64", "-platform=darwin_amd64"]
    run_on_error = false
  }

chrismazanec avatar Feb 13 '21 01:02 chrismazanec

Imho your workaround is bypassing the idea behind the .terraform.lock.hcl? terraform will always install latest versions of the provider matching the version constraints defined.

We bypassed this issue a bit different:

after_hook "init_lock_providers" {
  commands     = ["init"]
  execute      = ["terraform", "providers", "lock", "-platform=linux_amd64", "-platform=darwin_amd64"]
  run_on_error = false
}

after_hook "init_copy_back_lockfile" {
  commands     = ["init"]
  execute      = ["cp", ".terraform.lock.hcl", "${get_terragrunt_dir()}"]
  run_on_error = false
}

It's still not ideal as this results in a duplicate copy, one done by the .terraform.lock.hcl handling in terragrunt and one by the hook.

cschroer avatar Mar 30 '21 09:03 cschroer

This seems to be an issue from terraform, not terragrunt. You can test it by going to the terragrunt-cache dir and run terraform directly. Also we see this error only with the AWS provider.

https://github.com/hashicorp/terraform/issues/27810

stevie- avatar Jun 11 '21 09:06 stevie-

Here's my workaround for this terraform issues

two issues:

  1. when plugin cache is enabled terraform init doesn't add signatures, which breaks terraform providers lock for other platforms
  2. if there is a hash but no signatures in terraform.lock.hcl validation will fail for other platforms not matching this hash

Workaround

terraform {

  # https://github.com/hashicorp/terraform/issues/27769
  extra_arguments "ignore_cache_on_init" {
    commands = contains(get_terraform_cli_args(), "-upgrade") ? ["init"] : []
    env_vars = {
      TF_PLUGIN_CACHE_DIR = ""
    }
  }

  # make sure CI platform is added to hashes
  extra_arguments "add_signatures_for_other_platforms" {
    commands = contains(get_terraform_cli_args(), "lock") ? ["providers"] : []
    # use env_vars since "provider locks" argument order fails
    env_vars = {
      TF_CLI_ARGS_providers_lock = "-platform=darwin_amd64 -platform=linux_amd64"
      TF_PLUGIN_CACHE_DIR = "" # disable cache for auto init
    }
}

This workaround doesn't work for "normal" terragrunt init with cache enabled issue, but for the usecase of updating providers. Once the terraform.lock.hcl is correct (hash + signatures) providers lock will work as expected.

BTW: It is sufficient to remove the hashes list from terraform.lock.hcl to make it work. so you could keep the version constraints.

stevie- avatar Jun 11 '21 10:06 stevie-

I am having this issue and sometimes I can get it to go but not today. I ended up copying the lock from another module. Any chance this will be resolved? Its wasting my time just to get a lock file properly generated. Thanks!

FriedCircuits avatar Nov 18 '21 01:11 FriedCircuits

I've run into this issue as well with latest Terragrunt and Terraform:

terraform 1.1.7
terragrunt 0.36.3

codewest avatar Mar 09 '22 16:03 codewest

I am having this issue and sometimes I can get it to go but not today. I ended up copying the lock from another module. Any chance this will be resolved? Its wasting my time just to get a lock file properly generated. Thanks!

Same here, the behaviour is quite random, requires a couple of re-runs and it will mostly work. Causing quite some pain this week.

Locally things work fine when not using a TF_PLUGIN_CACHE_DIR ( mostly) , in a CI system where TF_PLUGIN_CACHE_DIR the behaviour is more erratic.

fwiw, I am running terraform version 1.1.5 and terragrunt 0.36.3 ( issue was present on 0.36.1) as well.

Clearing the .terragrunt-cache , doing a terragrunt plan and then manually generating the lock files for linux_amd64 (CI system) and linux_arm64 ( local) makes it work with a few attempts.

itsavvy-ankur avatar Mar 09 '22 16:03 itsavvy-ankur

I fixed this in a totally different way as I was getting really inconsistent behaviour with the above solutions:

rm -fr .terragrunt-cache
rm -f .terraform.lock.hcl
export TERRAGRUNT_AUTO_INIT=false
terragrunt providers lock -platform darwin_arm64 -platform linux_amd64
unset TERRAGRUNT_AUTO_INIT
terragrunt apply

Then once the lock file is valid, can just run terragrunt apply in the future and commit the lock file as normal.

NOTE: This doesn't seem to work when your source module references other modules. I generally need to comment those out to get it going (as long as they don't use different providers, commenting it out temporarily will work)

rcousens avatar Jun 14 '22 00:06 rcousens

Hello. This seems to be working for me:

cat ~/.terraformrc
plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"
git clone repo
cd repo/subfolder
TF_CLI_CONFIG_FILE="/dev/null" terragrunt providers lock -platform=windows_amd64 -platform=darwin_amd64 -platform=darwin_arm64 -platform=linux_amd64
cat .terraform.lock.hcl 
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.

provider "registry.terraform.io/hashicorp/aws" {
  version     = "3.75.2"
  constraints = "< 4.0.0"
  hashes = [
    "h1:Yi/V8LtJKyGZhKJmgsqKpVqBZKNECctHOn4fV3LFvOw=",
    "h1:lcSLAmkNM1FvNhqAEbh2oTZRqF37HKRh1Di8LvssYBY=",
    "h1:x0gluX9ZKEmz+JJW3Ut5GgWDFOq/lhs2vkqJ+xt57zs=",
    "h1:xXeHg5KDyH3rn2mrFh+iuvO2d9CEx8ryvOWRUMC3aWg=",
    "zh:0e75fb14ec42d69bc46461dd54016bb2487d38da324222cec20863918b8954c4",
    "zh:30831a1fe29f005d8b809250b43d09522288db45d474c9d238b26f40bdca2388",
    "zh:36163d625ab2999c9cd31ef2475d978f9f033a8dfa0d585f1665f2d6492fac4b",
    "zh:48ec39685541e4ddd8ddd196e2cfb72516b87f471d86ac3892bc11f83c573199",
    "zh:707b9c8775efd6962b6226d914ab25f308013bba1f68953daa77adca99ff6807",
    "zh:72bd9f4609a827afa366c6f119c7dec7d73a35d712dad1457c0497d87bf8d160",
    "zh:930e3ae3d0cb152e17ee5a8aee5cb47f7613d6421bc7c22e7f50c19da484a100",
    "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425",
    "zh:a19bf49b80101a0f0272b994153eeff8f8c206ecc592707bfbce7563355b6882",
    "zh:a34b5d2bbaf52285b0c9a8df6258f4789f4d927ff777e126bdc77e7887abbeaa",
    "zh:caad6fd5e79eae33e6d74e38c3b15c28a5482f2a1a8ca46cc1ee70089de61adb",
    "zh:f2eae988635030de9a088f8058fbcd91e2014a8312a48b16bfd09a9d69d9d6f7",
  ]
}

kbcz1989 avatar Nov 08 '22 12:11 kbcz1989