如何使用sam来运行一个使用codepipeline部署的cdk应用?

How do you use sam to run a cdk application that uses codepipeline to deploy?

我正在使用使用 CodePipeline 的 AWS CDK 构建应用程序。所以基本上有两个堆栈,一个设置代码管道,另一个设置应用程序(由管道触发)。

我正在研究 https://cdkworkshop.com/ 中的内置内容,所以在我的项目中我有一个文件 cdk.json,其中有一个条目 app 指向特定的 TypeScript 文件(example4 -be 是应用程序名称):

{
  "app": "npx ts-node --prefer-ts-exts bin/example4-be.ts",

此文件构建 CodePipeline 堆栈:

#!/usr/bin/env node
import * as cdk from "aws-cdk-lib"
import {PipelineStack} from "../lib/pipeline-stack"

const app = new cdk.App()
new PipelineStack(app, "Example4BePipeline")

所以当我尝试在本地使用 sam 运行 应用程序时,它失败了,说没有 Lambda 函数。我相信这是因为它正在构建 CodePipeline 堆栈而不是应用程序堆栈。如果我将 exampe4-be.ts 更改为:

#!/usr/bin/env node
import * as cdk from "aws-cdk-lib"
import {Example4BeStack} from "../lib/example4-be-stack";

const app = new cdk.App()
new Example4BeStack(app, "Example4BePipeline")

有效。 Example4BeStack 是应用程序堆栈。但很明显,如果我这样做,CodePipeline 将停止工作。

我怎样才能让这两个东西同时工作?

我运行 sam 运行 本地应用程序的命令是:~

cdk synth --no-staging | out-file template.yaml -encoding utf8
sam local start-api

在您的代码库中创建两个 cdk.App 链,一个用于管道,一个用于独立 development/testing 和 sam localcdk deploy。您的“应用程序”堆栈将成为两个链的一部分。这是我使用的模式的一个简化示例:

管道部署 (app-pipeline.ts)ApiStackDatabaseStackcdk.Stage 的子代,[=[=] 的孙代=22=],以及 cdk.App.

的曾孙

开发部署 (app.ts)ApiStackDatabaseStackcdk.App 的子代。与 sam localcdk deploy 一起用于开发和测试。

bin/
  app.ts              # calls makeAppStacks to add the stacks; runs frequently during development
  app-pipeline.ts     # adds the PipelineStack to an App

lib/
  ApiStack.ts
  DatabaseStack.ts
  PipelineStack.ts    # adds DeployStage to the pipeline
  DeployStage.ts      # subclasses cdk.Stage; calls makeAppStacks.ts to add the stacks
  makeAppStacks.ts    # adds the Api and Db stacks to either an App or a Stage

makeAppStacks 包装函数实例化了实际的堆栈。

// makeAppStacks.ts
export const makeAppStacks = (scope: cdk.App | DeployStage, appName: string, account: string, region: string): void => {
  const {table} = new DatabaseStack(scope, 'MyDb', ...)
  new ApiStack(scope, 'MyApi', {table, ...})
};

makeAppStacks 在两个地方被调用。 DeployStage.tsapp.ts 是通用的,很少更改:

// DeployStage.ts
export class DeployStage extends cdk.Stage {
  constructor(scope: Construct, id: string, props: DeployStageProps) {
    super(scope, id, props);
    makeAppStacks(this, props.appName, props.env.account, props.env.region);
  }
}
// app.ts
const app = new cdk.App();
const account = process.env.AWS_ACCOUNT;
makeAppStacks(app, 'MyApp', account, 'us-east-1');

为方便起见添加一些脚本:

"scripts": {
  "---- app (sandbox env) ----": "",
  "deploy-sandbox:cdk": "AWS_ACCOUNT=<Sandbox Acct> npx cdk deploy '*' --app 'ts-node ./bin/app.ts' --profile sandbox --outputs-file cdk.outputs.json",
  "deploy-sandbox": "build && test && deploy-sandbox:cdk",
  "destroy-sandbox": ...,
  "synth-sandbox": ...,
  "---- app-pipeline (pipeline env) ----": "",
  "deploy-pipeline:cdk": "npx cdk deploy '*' --app 'ts-node ./bin/app-pipeline.ts' --profile pipeline",
  "deploy-pipeline": "build && deploy-pipeline:cdk",
}