Terraform部署EC2时Bash变量无法写入Caddyfile的问题排查
问题根源与解决方案
你的问题主要由两个原因导致:
- Terraform对
$符号的提前解析:你使用的<<-EOF是不转义的 heredoc 格式,Terraform会把脚本中的$public_ip当成自身的变量处理,而你没有定义这个Terraform变量,所以最终传递给EC2的脚本里该变量被替换为空。 - EIP绑定时机滞后:如果是Terraform自动关联EIP到EC2实例,user-data执行时EIP可能还未完成绑定,
sleep 20的等待时间可能不足,导致curl获取的是实例的临时公网IP而非EIP(甚至获取失败)。
解决方法1:转义脚本中的$符号,避免Terraform解析
将脚本里所有的$前加上反斜杠\,让Terraform把$原封不动传递给EC2实例的shell执行,同时适当延长等待时间确保EIP绑定完成:
user_data = <<-EOF sudo su cd ~ sleep 30 public_ip=\$(curl -s http://checkip.amazonaws.com) sudo mkdir -p /var/log/caddy sudo touch /var/log/caddy/caddy_access.log echo -en "\$public_ip.nip.io { \nlog { \noutput file /var/log/caddy/caddy_access.log \n} \nreverse_proxy / localhost:3000 localhost:3001 { \nlb_policy round_robin \n}\n}" > Caddyfile sudo caddy start EOF
注意:
- 给
echo的内容添加双引号,确保shell能正确解析$public_ip变量 - 用
curl -s减少冗余输出,避免干扰变量赋值 - 新增
mkdir -p确保日志目录存在,防止touch命令失败
解决方法2:直接通过Terraform传递EIP变量(更可靠)
如果是用Terraform创建并关联EIP,直接将EIP的公网地址注入到user-data中,完全避免等待和curl获取的问题:
假设你的EIP资源定义如下:
resource "aws_eip" "instance_eip" { instance = aws_instance.your_instance.id vpc = true }
修改user-data为:
user_data = <<-EOF sudo su cd ~ sudo mkdir -p /var/log/caddy sudo touch /var/log/caddy/caddy_access.log echo -en "${aws_eip.instance_eip.public_ip}.nip.io { \nlog { \noutput file /var/log/caddy/caddy_access.log \n} \nreverse_proxy / localhost:3000 localhost:3001 { \nlb_policy round_robin \n}\n}" > Caddyfile sudo caddy start EOF
这种方式下,Terraform会在EIP绑定完成后,将其公网IP值替换到user-data中,脚本执行时直接使用正确的EIP地址,无需等待。
额外优化建议
- 无需先
sudo su再重复使用sudo,可以直接用sudo执行所有命令,或者切换用户后去掉sudo:user_data = <<-EOF # 直接用sudo执行所有操作,避免切换用户的冗余步骤 sleep 30 public_ip=\$(curl -s http://checkip.amazonaws.com) sudo mkdir -p /var/log/caddy sudo touch /var/log/caddy/caddy_access.log sudo bash -c 'echo -en "$public_ip.nip.io { \nlog { \noutput file /var/log/caddy/caddy_access.log \n} \nreverse_proxy / localhost:3000 localhost:3001 { \nlb_policy round_robin \n}\n}" > /etc/caddy/Caddyfile' sudo caddy start EOF - 如果Caddy未预装在AMI中,建议在user-data开头添加Caddy的安装步骤,确保脚本执行完整。
内容的提问来源于stack exchange,提问作者Ahmed Rauf Khan
相关产品推荐
相关产品推荐

