Terragrunt无法读取父级生成的provider.tf,AWS凭证获取失败
Terragrunt无法识别父级生成的provider配置问题分析与解决
目录结构
Project root ├── terraform │ └── non_live │ ├── base │ │ └── terragrunt.hcl │ ├── global.hcl │ └── terragrunt.hcl
父级terragrunt.hcl内容
terragrunt_version_constraint = "< v0.52.0" terraform_version_constraint = ">= 1.5.5, < 1.6.0" remote_state { backend = "s3" generate = { path = "backend.tf" if_exists = "overwrite" } config = { bucket = "my-bucket" key = "${path_relative_to_include()}/terraform.tfstate" region = "us-west-1" encrypt = true dynamodb_table = "my-lock-table" } } generate "provider" { path = "provider.tf" if_exists = "overwrite_terragrunt" contents = <<EOF provider "aws" { region = "us-west-1" profile = "my-profile" } EOF } generate "version" { path = "terraform.tf" if_exists = "overwrite_terragrunt" contents = <<EOF terraform { required_version = "1.5.5" } EOF }
non_live/base/terragrunt.hcl内容
include "root" { path = find_in_parent_folders() } include "global" { path = "${get_terragrunt_dir()}/../global.hcl" expose = true } terraform { source = "tfr:///terraform-aws-modules/s3-bucket/aws//.?version=3.15.1" } inputs = { bucket = "terragrunt-test-bucket" attach_deny_insecure_transport_policy = true s3_bucket_region = "${include.global.locals.region}" }
问题现象
在non_live/base目录执行terragrunt init时,发现provider.tf被生成在.terragrunt-cache目录而非当前目录,同时Terragrunt报错无法找到AWS凭证:
ERRO[0007] Error finding AWS credentials (did you set the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables?): NoCredentialProviders: no valid providers in chain. Deprecated. For verbose messaging see aws.Config.CredentialsChainVerboseErrors ERRO[0007] Unable to determine underlying exit code, so Terragrunt will exit with error code 1
手动设置环境变量export AWS_PROFILE=my-profile后,问题可解决。
原因分析
- 生成文件位置问题:当Terragrunt通过
terraform.source引用远程模块时,所有generate块创建的配置文件都会被写入到.terragrunt-cache下的模块副本中——这是Terragrunt的默认行为,目的是将生成的配置和远程模块代码合并后再交给Terraform执行,所以不会出现在当前工作目录。 - 凭证读取时机问题:Terragrunt初始化远程状态(
remote_state)的操作,会在Terraform加载provider.tf之前执行。此时.terragrunt-cache里的provider.tf还没生效,Terragrunt无法读取其中配置的profile参数,只能依赖环境变量或AWS默认凭证链,因此会出现找不到凭证的报错。
解决方法
方法1:给远程状态配置添加profile
在父级terragrunt.hcl的remote_state.config中添加profile参数,让Terragrunt处理远程状态时直接使用指定的profile:
remote_state { backend = "s3" generate = { path = "backend.tf" if_exists = "overwrite" } config = { bucket = "my-bucket" key = "${path_relative_to_include()}/terraform.tfstate" region = "us-west-1" encrypt = true dynamodb_table = "my-lock-table" profile = "my-profile" # 新增这一行 } }
这样Terragrunt在初始化远程状态时就会用指定的profile,无需依赖环境变量。
方法2:用extra_arguments传递profile参数
在父级或子级terragrunt.hcl中添加extra_arguments块,给Terraform命令传递profile参数:
extra_arguments "aws_profile" { commands = ["init", "plan", "apply", "destroy"] arguments = ["-var", "aws_profile=my-profile"] }
注意需要确保引用的远程模块支持aws_profile变量,或者在生成的provider块中引用该变量(比如把profile = "my-profile"改成profile = var.aws_profile)。
方法3:使用本地模块(不推荐)
如果一定要让provider.tf生成在当前目录,可以放弃远程模块的source配置,把模块代码放在本地目录。但这种方式会失去远程模块版本管理的优势,不适合生产环境。
内容的提问来源于stack exchange,提问作者zaman sakib
相关产品推荐
相关产品推荐

