能否修改.terraform/modules下子模块?Terraform plan报错如何解决
Terraform模块修改问题解答
核心结论
绝对不要直接修改.terraform/modules目录下的文件,该目录是Terraform执行terraform init时自动生成的远程模块缓存目录,每次执行初始化操作、或者在新环境(比如CI/UI执行环境)运行时,都会重新从模块源地址拉取原始版本文件,你本地的临时修改不会被持久化,也不会同步到其他运行环境,这就是你执行init --upgrade后修改被重置、UI触发执行仍然报错的原因。
你遇到的所有报错根因为你使用的ec2-datapipeline模块是适配Terraform 0.11及更早版本的代码,和你当前使用的0.12+版本Terraform语法不兼容。
彻底解决方案
你可以根据自己的使用场景选择以下任意一种方案:
- 方案1:私有托管修改后的模块
将该模块的原始仓库Fork到你自己的私有代码仓库,把你本地调整好的兼容性修改提交到Fork后的仓库,然后修改你项目根目录下引用该模块的source参数为你私有仓库的地址,示例:# 调整前的模块引用 module "ec2-datapipeline" { source = "原发布方/ec2-datapipeline/aws" version = "x.x.x" // 其他参数 } # 调整后的模块引用 module "ec2-datapipeline" { source = "git::https://你的私有仓库地址/terraform-aws-ec2-datapipeline.git" ref = "v1.0.0-compat-fix" # 可指定commit、tag固定版本 // 其他参数 } - 方案2:本地引入模块代码
如果模块体积很小,直接把模块的原始代码拷贝到你项目的本地目录(比如新建./modules/ec2-datapipeline目录),把你修改后的main.tf、variables.tf放到该目录下,然后修改模块引用的source为本地路径即可:
该方案下模块代码会和你的项目代码一起提交,不会再被Terraform自动覆盖重置。module "ec2-datapipeline" { source = "./modules/ec2-datapipeline" // 其他参数 } - 方案3:升级官方兼容版本
到该模块的官方发布页查找是否已经发布了适配高版本Terraform的更新版本,直接升级模块到兼容版本即可,无需自行修改代码。
兼容性修改参考
你之前做的调整可以参考以下标准语法修改,避免遗漏问题:
- 缺失变量声明:在模块的
variables.tf中添加variable "count" {}声明即可 - 安全组类型错误:
var.vpc_security_group_ids本身已经是字符串列表,不需要额外套方括号,修改为vpc_security_group_ids = var.vpc_security_group_ids - 块参数错误:
root_block_device、ebs_block_device、ephemeral_block_device属于资源块,不能直接赋值变量,需要用dynamic块动态生成,示例:dynamic "root_block_device" { for_each = var.root_block_device != null ? [var.root_block_device] : [] content { volume_size = root_block_device.value.volume_size volume_type = root_block_device.value.volume_type # 按需补充其他属性 } } - 废弃函数替换:旧版
map函数已经被移除,修改为tomap({Name = format("%s-%d", var.name, count.index+1)})即可。
内容的提问来源于stack exchange,提问作者Koppula R
相关产品推荐
相关产品推荐

