如何在YAML格式CloudFormation UserData中使用函数获取EC2公IP写入文本文件
问题根因
- 原配置失效的核心原因:CloudFormation的YAML短形式内置函数(如
!GetAtt、!Ref)仅能作为独立YAML节点的取值使用,不能直接嵌入!Sub处理的多行块文本内部。块文本内的所有内容都会被判定为普通字符串,不会触发CFN的函数解析逻辑。 - 原配置存在的隐性语法问题:
echo行中字符串与后续内容直接拼接无有效分隔,即使函数能正常解析,bash执行逻辑也会报错。
正确实现方式
利用!Sub的字符串替换能力,通过两种合规写法实现需求:
写法1:Sub占位符内直接嵌套函数(最简洁)
在!Sub处理的字符串中,通过${!函数}的格式声明需要替换的CFN函数值,不需要额外传参:
UserData: Fn::Base64: !Sub | #!/bin/bash -xe echo "Public IP: ${!GetAtt Bastion.PublicIp}" > /home/ec2-user/readme.txt
写法2:通过Sub参数列表传递取值
将公网IP的引用作为!Sub的第二参数传入,定义自定义替换变量,适合包含多变量的复杂脚本场景:
UserData: Fn::Base64: Fn::Sub: - | #!/bin/bash -xe echo "Public IP: ${BastionPublicIp}" > /home/ec2-user/readme.txt - BastionPublicIp: !GetAtt Bastion.PublicIp
落地注意事项
- 所有写在
!Sub块文本里的CFN取值,必须放在${}占位符结构内,不能直接裸写短形式函数。 - 需确保脚本中写入文件的对应目录存在、执行脚本的用户拥有文件写入权限,避免bash执行失败。
内容的提问来源于stack exchange,提问作者Sandeep
相关产品推荐
相关产品推荐

