Можно ли развернуть стеки AWS CDK изнутри лямбды? - PullRequest
0 голосов
/ 09 ноября 2019

Я хочу развернуть стеки AWS CDK с помощью функции Lambda. Сценарий использования должен поддерживать функциональность, аналогичную описанной в Безсерверный конвейер CI / CD Trek10 , где соответствующий код здесь .

В двух словах, AWS CodePipelinesподдерживает только прослушивание изменений внутри одной ветки Git. Я хочу слушать события GitHub, связанные с созданием репозиториев и веток, и создавать экземпляры CodePipeline в ответ на эти события, чтобы для каждой ветви каждого репозитория Git был конвейер. Я хочу, чтобы Lambda прослушивала события GitHub и создавала стеки CDK. Пример Trek10 использует Python и напрямую вызывает CloudFormation. Я бы хотел, чтобы лямбды были намного проще и вместо них использовали бы CDK.

Вот простая лямбда, использующая Typescript, которая взята из этой AWS CDK :

// 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, так как это выглядит оченьгрязное решение, поэтому я ищу другое решение.

Какой самый простой рабочий пример вызова CDK из функции Lambda?

...