Ubuntu环境中cfn-signal失效导致CloudFormation栈超时问题排查
我来帮你排查并修复这个cfn-signal失效的问题,先从你的配置和脚本里的几个关键问题入手:
核心问题分析与修复步骤
1. Python版本适配错误(Ubuntu 20.04默认用Python3)
你使用的AMI ami-02a599eb01e3b3c5b 是Ubuntu 20.04版本,这个系统已经默认弃用Python2,但你的脚本里用apt install -y python-pip安装的是Python2的包管理器,后续用它安装aws-cfn-bootstrap会导致环境不兼容,直接引发cfn-signal无法正常运行。
修复方案: 改用Python3的包管理器:
apt install -y python3-pip
2. 推荐用系统包管理器安装aws-cfn-bootstrap
AWS现在更推荐通过apt而非pip安装aws-cfn-bootstrap,这样能更好适配系统环境,避免依赖冲突。而且pip安装的版本路径和系统包安装的路径不一致,这也是你调用cfn-signal失败的原因之一。
修复方案: 替换pip安装步骤为:
apt install -y aws-cfn-bootstrap
安装完成后,cfn-signal的路径是/usr/bin/cfn-signal(旧版本的/opt/aws/bin/cfn-signal不再适用)。
3. 修正cfn-signal调用逻辑与错误处理
原脚本里的$?仅捕获最后一步命令的退出码,无法全面反映整个初始化流程的状态;同时路径错误会直接导致命令执行失败。建议调整为确保所有步骤成功后再发送成功信号,否则传递错误码。
修复后的完整UserData脚本:
UserData: Fn::Base64: | #!/bin/bash -x # 更新系统包索引 apt update -y # 安装依赖工具 apt install -y python3-pip aws-cfn-bootstrap # 根据初始化结果发送信号 if [ $? -eq 0 ]; then /usr/bin/cfn-signal -e 0 --stack teststack --resource TestInstance --region ap-southeast-2 else /usr/bin/cfn-signal -e $? --stack teststack --resource TestInstance --region ap-southeast-2 fi
4. 检查EC2实例的IAM权限
EC2实例必须拥有cloudformation:SignalResource权限才能向CloudFormation发送信号,否则即使脚本正确,也会因权限不足导致信号无法送达。
修复方案: 给实例关联的IAM角色添加以下权限策略:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "cloudformation:SignalResource", "Resource": "arn:aws:cloudformation:ap-southeast-2:YOUR_ACCOUNT_ID:stack/teststack/*" } ] }
替换YOUR_ACCOUNT_ID为你的AWS账号ID,生产环境不建议用*替代具体资源ARN。
5. 验证网络连通性
确保EC2实例能访问CloudFormation服务端点:
- 实例所在安全组需允许出站HTTPS(443端口)到
cloudformation.ap-southeast-2.amazonaws.com - 如果实例在私有子网,需配置NAT网关或CloudFormation的VPC端点
验证方法
登录EC2实例后,查看云初始化日志确认脚本执行状态:
cat /var/log/cloud-init-output.log
如果日志里出现cfn-signal的成功输出,说明问题已解决。
内容的提问来源于stack exchange,提问作者Anastázie

