AWS上PrivateWorkForce无法删除及依赖缺失问题求助
问题解决:CloudFormation自定义资源Lambda的Node.js运行时及AWS SDK依赖错误
核心问题分析
- Node.js运行时过时:原模板使用已废弃的nodejs10.x运行时,升级到nodejs20.x后,Lambda不再默认包含AWS SDK v2(
aws-sdk模块)。 - SDK版本不匹配:代码中仍使用v2 SDK的
require('aws-sdk')导入,但package.json仅引入了v3版本的SageMaker客户端,缺少Cognito等其他服务的v3客户端,导致模块找不到。 - 堆栈删除阻塞:自定义资源Lambda执行失败,导致CloudFormation堆栈无法正常删除。
分步解决方案
1. 迁移代码到AWS SDK v3
将privateWorkforce.js中的v2 SDK用法替换为v3版本的客户端:
修改导入部分
const FS = require('fs'); const PATH = require('path'); // 替换旧的AWS SDK导入为v3客户端 const { CognitoIdentityProviderClient, CreateUserPoolDomainCommand, UpdateUserPoolClientCommand, DescribeUserPoolDomainCommand, DeleteUserPoolDomainCommand, CreateGroupCommand, DeleteGroupCommand, UpdateUserPoolCommand } = require('@aws-sdk/client-cognito-identity-provider'); const { SageMakerClient, ListWorkteamsCommand, CreateWorkteamCommand, DescribeWorkteamCommand, DeleteWorkteamCommand } = require('@aws-sdk/client-sagemaker'); const mxBaseResponse = require('../shared/mxBaseResponse');
修改客户端初始化
class PrivateWorkforce extends mxBaseResponse(class {}) { constructor(event, context) { super(event, context); /* sanity check */ const data = event.ResourceProperties.Data; this.sanityCheck(data); this.$data = data; // 初始化v3客户端 this.$cognito = new CognitoIdentityProviderClient({ apiVersion: '2016-04-18', }); this.$sagemaker = new SageMakerClient({ apiVersion: '2017-07-24', }); }
修改API调用方式(v3使用send()方法)
例如,修改preconfigure方法:
async preconfigure() { await this.cognito.send(new CreateUserPoolDomainCommand({ Domain: this.userPoolDomain, UserPoolId: this.userPool, })); await this.cognito.send(new UpdateUserPoolClientCommand({ ClientId: this.clientId, UserPoolId: this.userPool, AllowedOAuthFlows: [ 'code', 'implicit', ], AllowedOAuthFlowsUserPoolClient: true, AllowedOAuthScopes: [ 'email', 'openid', 'profile', ], ExplicitAuthFlows: [ 'USER_PASSWORD_AUTH', ], CallbackURLs: [ 'https://127.0.0.1', ], LogoutURLs: [ 'https://127.0.0.1', ], SupportedIdentityProviders: [ 'COGNITO', ], })); }
所有原promise()调用都需要替换为send(new Command(...))的形式,比如queryCurrentTeam、cognitoCreateGroup等方法需对应修改。
2. 更新package.json依赖
添加Cognito的v3客户端到依赖列表:
{ "$schema": "http://json.schemastore.org/package", "name": "custom-resources", "version": "1.0.0", "description": "(Custom Brand Detection) AWS CloudFormation Custom Resource Lambda function", "main": "index.js", "private": true, "scripts": { "pretest": "npm install", "test": "mocha *.spec.js", "build:clean": "rm -rf dist && mkdir -p dist", "build:copy": "cp -rv index.js package.json lib dist/", "build:install": "cd dist && npm install --production", "build": "npm-run-all -s build:clean build:copy build:install", "zip": "cd dist && zip -rq custom-resources.zip ." }, "author": "aws-specialist-sa-emea", "license": "MIT-0", "dependencies": { "adm-zip": "^0.4.14", "mime": "^2.4.5", "@aws-sdk/client-sagemaker": "^3.500.0", "@aws-sdk/client-cognito-identity-provider": "^3.500.0" }, "devDependencies": { "core-lib": "file:../layers/core-lib" } }
3. 重新构建并部署Lambda
运行构建脚本生成新的部署包:
npm run build npm run zip
将生成的dist/custom-resources.zip上传到Lambda函数,或更新CloudFormation模板中的Lambda代码包位置。
4. 解决堆栈删除阻塞问题
如果堆栈仍无法删除,可通过以下方式强制清理:
- 方法1:跳过自定义资源删除
使用AWS CLI执行删除命令,跳过失败的自定义资源类型:aws cloudformation delete-stack --stack-name YOUR_STACK_NAME --skip-resource-types Custom::PrivateWorkforceConfiguration - 方法2:手动清理资源
- 先删除对应的Lambda函数;
- 手动删除Cognito用户池域名、SageMaker工作团队等相关资源;
- 再次尝试删除CloudFormation堆栈。
内容的提问来源于stack exchange,提问作者Nicholas Ortiz
相关产品推荐
相关产品推荐

