如何让Terraform templatefile忽略Bash默认变量?
问题说明
将Bash脚本作为Terraform的user data使用时,需要仅让Terraform替换指定的${redis_ip}和${app_lb_dns}变量,但templatefile函数会解析脚本内所有${}格式的内容,包括Bash自身的颜色变量(如${G}、${R}),导致报错提示缺少对应变量键。尝试\${}和$${}转义未生效,需解决该冲突。
原Bash脚本
#!/bin/bash #Colors for terminal #RED R="\e[31m" #GREEN G="\e[32m" #YELLOW Y="\e[33m" #NORMAL N="\e[0m" validation(){ if [ $1 -eq 0 ]; then echo -e "${G}$2 is successful${N}" else echo -e "${R}$2 has Failed${N}" exit 1; fi } echo -e "${Y}Configuring Cart Service${N}" cart_config="/etc/systemd/system/cart.service" cat << EOF >$cart_config Environment=REDIS_HOST="${redis_ip}" #I want TF to only substitute these Environment=CATALOGUE_HOST="${app_lb_dns}" Environment=CATALOGUE_PORT=8082 EOF validation $? "Configuring Cart Service"
错误信息
20: user_data = base64encode(templatefile("../userdata/cart.sh", { redis_ip = data.aws_ssm_parameter.redis_ip.value, app_lb_dns = data.aws_ssm_parameter.app_lb_dns.value }))
while calling templatefile(path, vars)
Invalid value for "vars" parameter: vars map does not contain key "G", referenced at ../userdata/cart.sh:16,21-22.
翻译:调用templatefile(path, vars)函数时出错:"vars"参数无效,变量映射中不存在键"G",该引用位于../userdata/cart.sh第16行21-22位置。
原Terraform代码
user_data = base64encode(templatefile("../userdata/cart.sh", { redis_ip = data.aws_ssm_parameter.redis_ip.value, app_lb_dns = data.aws_ssm_parameter.app_lb_dns.value }))
解决方案
方法1:转义脚本中Bash自有变量(推荐)
将脚本中所有不需要Terraform解析的${xxx}替换为$${xxx},Terraform会将$${xxx}解析为${xxx}输出给Bash,仅保留指定变量让Terraform替换。
修改后的Bash脚本:
#!/bin/bash #Colors for terminal #RED R="\e[31m" #GREEN G="\e[32m" #YELLOW Y="\e[33m" #NORMAL N="\e[0m" validation(){ if [ $1 -eq 0 ]; then echo -e "$${G}$2 is successful$${N}" else echo -e "$${R}$2 has Failed$${N}" exit 1; fi } echo -e "$${Y}Configuring Cart Service$${N}" cart_config="/etc/systemd/system/cart.service" cat << EOF >$cart_config Environment=REDIS_HOST="${redis_ip}" #I want TF to only substitute these Environment=CATALOGUE_HOST="${app_lb_dns}" Environment=CATALOGUE_PORT=8082 EOF validation $? "Configuring Cart Service"
方法2:手动替换指定变量
不使用templatefile,改用file读取脚本原始内容,再通过replace函数手动替换目标变量,避免Terraform解析所有${}:
user_data = base64encode( replace( file("../userdata/cart.sh"), [ "/\\${redis_ip}/", data.aws_ssm_parameter.redis_ip.value, "/\\${app_lb_dns}/", data.aws_ssm_parameter.app_lb_dns.value ] ) )
内容的提问来源于stack exchange,提问作者N-CODER

