AWS CloudFormation自定义资源持续处于CREATE_IN_PROGRESS状态问题求助
嗨,我来帮你排查下这个问题,从你的代码和描述来看,有几个关键点可能导致自定义资源一直卡在创建中:
1. 变量名拼写错误
看你Lambda循环里的这段代码:
const ec2C = new AWS.EC2({ region }); const vpcs = await ec2Client.describeVpcs().promise();
你创建的EC2客户端实例是ec2C,但调用的时候写成了ec2Client——这个未定义的变量会抛出错误。虽然你在内部catch里捕获了这个错误并把信息加入了results,但这个错误可能会干扰后续代码的执行逻辑,甚至导致响应没有正确发送到CloudFormation。
2. 重复发送CloudFormation响应
在你的外层catch块里,你已经调用了response.send(event, context, response.FAILED);,但之后代码依然会执行到最后一行的response.send(event, context, response.SUCCESS, ...)。这会导致你的Lambda向CloudFormation发送两次响应,CloudFormation无法处理重复的回调,从而卡住资源创建流程。
你需要确保在任何代码路径下只发送一次响应,比如在外层catch里发送FAILED后,加上return;来终止后续代码执行:
} catch (error) { results.push('Error fetching active regions: ' + error.message); response.send(event, context, response.FAILED); return; // 终止后续代码,避免重复发送SUCCESS响应 }
3. 异步函数中使用cfn-response的注意事项
因为你的Lambda handler是async函数,而cfn-response.send是基于回调的方法,可能会存在Lambda执行环境没有及时终止的问题。建议你加上context.callbackWaitsForEmptyEventLoop = false;,确保发送响应后Lambda能立即结束,让CloudFormation及时收到回调:
exports.handler = async (event, context) => { context.callbackWaitsForEmptyEventLoop = false; // 加入这一行 const results = []; // 后续代码... };
修复后的代码示例
我把这些问题修复后的代码整理了一下,你可以参考:
const AWS = require('aws-sdk'); const ec2 = new AWS.EC2(); const response = require('cfn-response'); exports.handler = async (event, context) => { context.callbackWaitsForEmptyEventLoop = false; const results = []; try { const data = await ec2.describeRegions().promise(); const allRegions = data.Regions.map(region => region.RegionName); for (const reg of allRegions) { try { const ec2Client = new AWS.EC2({ region: reg }); // 修正变量名,统一为ec2Client const vpcs = await ec2Client.describeVpcs().promise(); const defaultVpc = vpcs.Vpcs.find(vpc => vpc.IsDefault); if (defaultVpc) { results.push(`Default VPC in ${reg}: ${defaultVpc.VpcId}`); } else { results.push(`No default VPC found in ${reg}`); } } catch (error) { results.push(`Error in ${reg}: ${error.message}`); } } // 只有在没有外层错误时才发送SUCCESS response.send(event, context, response.SUCCESS, { results }); } catch (error) { results.push(`Error fetching active regions: ${error.message}`); response.send(event, context, response.FAILED, { results }); } };
另外,你可以再检查下Lambda的IAM权限,确保它有调用CloudFormation回调URL的权限(不过通常自定义资源的Lambda会自动获得这个权限,但如果是手动配置的角色,可能需要确认)。
备注:内容来源于stack exchange,提问作者BearGrillz

