Terraform matti/resource/shell模块向.sh脚本传变量不生效问题
Terraform 通过 matti/resource/shell 模块传参失效问题排查与正确实现
问题核心根因
- 模块传参通道缺失:matti/resource/shell 模块不会自动把 Terraform 侧定义的变量注入到 shell 执行进程的环境中,原配置没有显式指定要传递的环境变量,shell 脚本根本读不到 Terraform 定义的各类参数
- Shell 脚本引号逻辑错误:bash 在单引号作用范围内不会做任何变量解析,原脚本中 curl 命令的请求体完全被单引号包裹,就算环境变量成功注入,
$ACCOUNT_NAME这类占位符也只会被当字面量字符串传递,不会替换为实际值 - 变量定义不完整:当前 variables.tf 仅声明了 API_KEY 变量,脚本依赖的账号名、邮箱、密码等参数没有对应的 Terraform 变量定义,传参链路天然不通
正确实现步骤
1. 补全 Terraform 变量定义
在 variables.tf 中声明所有脚本依赖的参数,敏感类参数开启 sensitive 标记避免日志泄露:
variable "API_KEY" { description = "接口调用密钥" type = string default = "" # 生产环境建议从环境变量/密钥服务注入,不要硬编码明文 } variable "ACCOUNT_NAME" { description = "待创建的账号名称" type = string } variable "EMAIL" { description = "账号绑定的用户邮箱" type = string } variable "PASSWORD" { description = "账号初始密码" type = string sensitive = true } variable "FIRST_NAME" { description = "用户名" type = string } variable "LAST_NAME" { description = "用户姓" type = string }
2. 修改模块调用配置,打通传参通道
在 matti/resource/shell 模块调用中通过 environment 参数,把 Terraform 变量映射为 shell 进程可读取的环境变量,同时配置 triggers 逻辑让资源状态和参数变更绑定,避免无意义的重复执行:
module "account_create" { source = "matti/resource/shell" command = "/bin/bash ${path.module}/create_account.sh" # 显式映射需要传递给shell的环境变量 environment = { API_KEY = var.API_KEY ACCOUNT_NAME = var.ACCOUNT_NAME EMAIL = var.EMAIL PASSWORD = var.PASSWORD FIRST_NAME = var.FIRST_NAME LAST_NAME = var.LAST_NAME } # 参数变更时自动触发脚本重新执行 triggers = { account_name = var.ACCOUNT_NAME email = var.EMAIL } }
3. 修正 shell 脚本的引号与请求逻辑
去掉单引号包裹的固定字符串写法,清理原脚本中冗余的引号拼接逻辑,用 heredoc 方式构造 JSON 请求体,避免多层引号嵌套导致的变量解析失效问题,修正后的 create_account.sh 内容为:
#!/bin/bash # 用heredoc构造可正常解析变量的JSON请求体 REQUEST_BODY=$(cat <<EOF { "account": { "name": "$ACCOUNT_NAME" }, "users": [ { "email": "$EMAIL", "password": "$PASSWORD", "first_name": "$FIRST_NAME", "last_name": "$LAST_NAME", "role": "readonly", "owner": "true" } ] } EOF ) curl -X POST \ -H "api-key: $API_KEY" \ -H "Content-Type:application/json" \ -d "$REQUEST_BODY" \ "https://your-target-domain/accounts" > /tmp/return.json
关键注意事项
- matti/resource/shell 模块默认的 shell 执行环境是隔离的,必须通过
environment块显式传递参数,不能依赖 Terraform 变量的自动注入 - 构造 JSON 类请求体时,优先用 heredoc 方式拼接,不要用多层引号嵌套字符串,否则极易出现变量不解析、格式错误的问题
- 密钥、密码类敏感值不要硬编码在脚本或者 Terraform 默认值中,配合 sensitive 标记和外部密钥源注入可以降低泄露风险
内容的提问来源于stack exchange,提问作者Tuan Nguyen
相关产品推荐
相关产品推荐

