【发布时间】:2020-03-05 23:41:35
【问题描述】:
我想使用 Lambda 函数部署 AWS CDK 堆栈。用例是支持与Trek10's Serverless CI/CD pipeline中描述的功能相似的功能,其中相关代码为here。
简而言之,AWS CodePipelines 仅支持监听单个 Git 分支中的更改。我想收听与创建存储库和分支相关的 GitHub 事件,并创建 CodePipeline 实例以响应这些事件,以便每个 Git 存储库的每个分支都有一个管道。我想要一个 Lambda 来监听 GitHub 事件并创建 CDK 堆栈。 Trek10 示例使用 Python 并直接调用 CloudFormation。我希望 Lambda 更简单,并改用 CDK。
这是一个使用 Typescript 的简单 Lambda,它源自 AWS CDK issue:
// index.ts
import {ScheduledEvent} from 'aws-lambda';
import {CloudFormationDeploymentTarget, DEFAULT_TOOLKIT_STACK_NAME} from 'aws-cdk/lib/api/deployment-target';
import {CdkToolkit} from 'aws-cdk/lib/cdk-toolkit';
import {AppStacks} from 'aws-cdk/lib/api/cxapp/stacks';
import {Configuration} from 'aws-cdk/lib/settings';
import {execProgram} from "aws-cdk/lib/api/cxapp/exec";
import * as yargs from 'yargs';
import {SDK} from 'aws-cdk/lib/api/util/sdk';
export const handleCloudWatchEvent = async (event: ScheduledEvent): Promise<void> => {
try {
const aws = new SDK();
const argv = await yargs.parse(['deploy', '--app', 'bin/pipeline.js', '--staging', '/tmp', '--verbose', '--require-approval', 'never']);
const configuration = new Configuration(argv);
await configuration.load();
const appStacks = new AppStacks({
configuration,
aws,
synthesizer: execProgram,
});
const provisioner = new CloudFormationDeploymentTarget({ aws });
const cli = new CdkToolkit({ appStacks, provisioner });
const toolkitStackName = configuration.settings.get(['toolkitStackName']) || DEFAULT_TOOLKIT_STACK_NAME;
await cli.deploy({
stackNames: [],
exclusively: argv.exclusively as boolean,
toolkitStackName,
roleArn: argv.roleArn as string,
requireApproval: configuration.settings.get(['requireApproval']),
ci: true,
reuseAssets: argv['build-exclude'] as string[],
sdk: aws
});
return;
} catch (e) {
console.error(e);
return;
}
};
但是,我收到上述问题中所述的错误:
ERROR { Error: Cannot find module '../package.json'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15)
at Function.Module._load (internal/modules/cjs/loader.js:562:25)
at Module.require (internal/modules/cjs/loader.js:692:17)
at new SDK (/var/task/node_modules/aws-cdk/lib/api/util/sdk.ts:92:39)
at Runtime.exports.handleCloudWatchEvent [as handler] (/resources/index.ts:204:21)
at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)
at process._tickCallback (internal/process/next_tick.js:68:7) code: 'MODULE_NOT_FOUND' }
我不想修补sdk.ts:https://github.com/aws/aws-cdk/blob/master/packages/aws-cdk/lib/api/util/sdk.ts#L92,因为这似乎是一个非常肮脏的解决方案,所以我正在寻找另一个解决方案。
从 Lambda 函数中调用 CDK 的最简单的工作示例是什么?
【问题讨论】:
-
@AliHabibzadeh 请问一个简单的例子是什么样的? lambda 是否将管道文件复制到某种形式的 npm 项目结构中,运行
aws sts assume-role以获取凭据,然后针对该结构执行npm run build && cdk synth && cdk deploy并将这些凭据用作该子进程的环境变量? -
在下面查看我的答案以获取解决方案以及最近的 GitHub 示例。
标签: amazon-web-services aws-lambda aws-codepipeline aws-cdk