Terraform模块输出调用失败及Terratest测试报错求助
问题分析
Terraform控制台报错原因
根模块无法直接引用子模块内部的aws_s3_bucket.tf_s3资源——Terraform模块本身是隔离的,子模块内的资源只能通过模块输出逐层向上暴露,否则根模块会判定该资源未声明。
Terratest测试报错原因
最底层s3模块的tf_s3_name输出没有传递到根模块,根模块未定义对应输出变量,导致Terratest从根模块状态中找不到该输出。
解决方案
需要逐层向上暴露模块输出,让根模块能获取到dev和stage环境的S3桶属性,再修改测试代码完成验证。
1. 修改环境模块的输出(dev/s3/main.tf、stage/s3/main.tf)
在dev/s3/main.tf中添加输出,将底层s3模块的输出暴露到当前dev模块:
module "Devs3Create" { source = "../../modules/s3" bucket_env_name = "dev" } # 暴露s3模块的输出到当前dev模块 output "dev_s3_bucket" { value = module.Devs3Create.tf_s3_name }
同理修改stage/s3/main.tf:
module "Stages3Create" { source = "../../modules/s3" bucket_env_name = "stage" } # 暴露s3模块的输出到当前stage模块 output "stage_s3_bucket" { value = module.Stages3Create.tf_s3_name }
2. 修改根模块main.tf,添加全局输出
在根模块main.tf中添加输出,将dev和stage模块的输出暴露到根层级:
module "dev" { source = "./dev/s3" } module "stage" { source = "./stage/s3" } # 输出dev环境的S3桶信息 output "dev_s3_bucket" { value = module.dev.dev_s3_bucket } # 输出stage环境的S3桶信息 output "stage_s3_bucket" { value = module.stage.stage_s3_bucket }
3. 修改Terratest测试代码(tests/s3_test.go)
修改测试代码,分别获取dev和stage的输出,验证桶名符合环境预期:
package test import ( "testing" "regexp" "github.com/gruntwork-io/terratest/modules/terraform" "github.com/stretchr/testify/assert" ) func TestS3(t *testing.T) { terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{ TerraformDir: "../", }) defer terraform.Destroy(t, terraformOptions) terraform.InitAndApply(t, terraformOptions) // 验证dev环境S3桶名包含"dev" devS3Output := terraform.Output(t, terraformOptions, "dev_s3_bucket") assert.Regexp(t, regexp.MustCompile("dev"), devS3Output) // 验证stage环境S3桶名包含"stage" stageS3Output := terraform.Output(t, terraformOptions, "stage_s3_bucket") assert.Regexp(t, regexp.MustCompile("stage"), stageS3Output) }
验证步骤
- 执行
terraform init初始化配置 - 执行
terraform apply应用配置,此时根模块会输出dev和stage的S3桶信息 - 运行测试
go test -v,验证两个环境的桶名符合预期
补充说明
如果需要获取S3桶的具体属性(如ARN、创建时间等),可修改s3模块的输出指定具体属性:
# modules/s3/main.tf output "tf_s3_arn" { value = aws_s3_bucket.tf_s3.arn } output "tf_s3_name" { value = aws_s3_bucket.tf_s3.id }
随后按同样逻辑逐层传递输出,在测试代码中获取对应属性完成验证。
内容的提问来源于stack exchange,提问作者Sri
相关产品推荐
相关产品推荐

