CDK:可以将为 EdgeFunction 资源创建的堆栈放在另一个(跨区域)堆栈中吗?
CDK: Possible to put the stack created for EdgeFunction resource in another (cross-region) stack?
问题陈述
我在 eu-west-1
中有我的主要 CDK 堆栈,但在 us-east-1
中创建了一个 EdgeFunction
。
我注意到 EdgeFunction
有两个奇怪的地方:
- 即使在
NestedStack
中声明,它们也会在 cdk ls
中显示为 edge-lambda-stack-nnnnnnnnn
(除非给出明确的名称)。
- 删除主堆栈时,我们称之为
primary
,它不会删除 lambda 堆栈。可能是因为上面的 (1) 告诉我它不是 NestedStack
. 的一部分
我曾尝试将 EdgeFunction
明确地放在 us-east-1
中创建的单独堆栈中,然后从 primary
交叉引用它,但失败并显示“无法在交叉中使用资源” -环境时尚”(以及其他)。
问题
- 为什么
cloudfront.experimental.EdgeFunction
不遵守 NestedStack
边界?
- 我能否以某种方式构建一个存在于
us-east-1
中的 Stack
并将 lambda 交叉引用到我在 eu-west-1
中的主堆栈中?
- 我能否至少做到这样,删除
primary
堆栈也会自动删除 lambda 堆栈。
我问的原因是因为我有很多环境和很多 lambda,堆栈的组合爆炸让事情变得有点笨拙。
例子
CDK 版本 1.116
import "source-map-support/register";
import * as cdk from "@aws-cdk/core";
import * as cloudfront from "@aws-cdk/aws-cloudfront";
import * as lambda from "@aws-cdk/aws-lambda";
import * as path from "path";
class PrimaryStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
new SecondaryStack(this, "secondary-stack");
}
}
class SecondaryStack extends cdk.NestedStack {
constructor(scope: cdk.Construct, id: string) {
super(scope, id);
new cloudfront.experimental.EdgeFunction(this, "my-lambda", {
runtime: lambda.Runtime.NODEJS_14_X,
functionName: "my-lambda",
handler: "index.handler",
code: lambda.Code.fromAsset(
path.join(__dirname, "..", "lib", "my-lambda"),
),
});
}
}
const app = new cdk.App();
new PrimaryStack(app, "primary", {
env: { account: "123", region: "eu-west-1" },
});
cdk ls
输出:
edge-lambda-stack-cnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
primary
我与 AWS 高级支持人员进行了交谈,得到的答复是 CDK 似乎无法通过使用嵌套堆栈来处理此问题。
相反,在 us-east-1
中为 EdgeLambdas 创建一个单独的堆栈,然后将 lambdas 的 ARN 导出到 SSM。
在另一个堆栈中,import the ARNs from SSM and use those。
这将导致要处理的堆栈数量最少。您仍然需要分别部署这两个堆栈。
我最终使用的代码如下所示:
export function exportLambdaSsm(
func: cloudfront.experimental.EdgeFunction,
): ssm.StringParameter {
const funcName = // ...
return new ssm.StringParameter(this, `${funcName}-param`, {
// Parameter with slash must start with a slash
parameterName: `/${funcName}`,
stringValue: func.functionArn,
});
}
export function importLambdaFromSsm(stack: Stack): lambda.IVersion {
const funcName = // ...
const funcResource = new cr.AwsCustomResource(stack, `${funcName}-param`, {
policy: cr.AwsCustomResourcePolicy.fromStatements([
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ["ssm:GetParameter*"],
resources: [
stack.formatArn({
service: "ssm",
region: "us-east-1",
resource: "parameter",
resourceName: funcName,
}),
],
}),
]),
onUpdate: {
// will also be called for a CREATE event
service: "SSM",
action: "getParameter",
parameters: {
Name: `/${funcName}`,
},
region: "us-east-1",
// Update physical id to always fetch the latest version
physicalResourceId: cr.PhysicalResourceId.of(Date.now().toString()),
},
});
return lambda.Version.fromVersionArn(stack, funcName, funcResource.getResponseField("Parameter.Value"));
}
请注意,在获取和存储 SSM 值时,有很多关于斜线位置的规则。我试图保持上面的代码正确。
问题陈述
我在 eu-west-1
中有我的主要 CDK 堆栈,但在 us-east-1
中创建了一个 EdgeFunction
。
我注意到 EdgeFunction
有两个奇怪的地方:
- 即使在
NestedStack
中声明,它们也会在cdk ls
中显示为edge-lambda-stack-nnnnnnnnn
(除非给出明确的名称)。 - 删除主堆栈时,我们称之为
primary
,它不会删除 lambda 堆栈。可能是因为上面的 (1) 告诉我它不是NestedStack
. 的一部分
我曾尝试将 EdgeFunction
明确地放在 us-east-1
中创建的单独堆栈中,然后从 primary
交叉引用它,但失败并显示“无法在交叉中使用资源” -环境时尚”(以及其他)。
问题
- 为什么
cloudfront.experimental.EdgeFunction
不遵守NestedStack
边界? - 我能否以某种方式构建一个存在于
us-east-1
中的Stack
并将 lambda 交叉引用到我在eu-west-1
中的主堆栈中? - 我能否至少做到这样,删除
primary
堆栈也会自动删除 lambda 堆栈。
我问的原因是因为我有很多环境和很多 lambda,堆栈的组合爆炸让事情变得有点笨拙。
例子
CDK 版本 1.116
import "source-map-support/register";
import * as cdk from "@aws-cdk/core";
import * as cloudfront from "@aws-cdk/aws-cloudfront";
import * as lambda from "@aws-cdk/aws-lambda";
import * as path from "path";
class PrimaryStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
new SecondaryStack(this, "secondary-stack");
}
}
class SecondaryStack extends cdk.NestedStack {
constructor(scope: cdk.Construct, id: string) {
super(scope, id);
new cloudfront.experimental.EdgeFunction(this, "my-lambda", {
runtime: lambda.Runtime.NODEJS_14_X,
functionName: "my-lambda",
handler: "index.handler",
code: lambda.Code.fromAsset(
path.join(__dirname, "..", "lib", "my-lambda"),
),
});
}
}
const app = new cdk.App();
new PrimaryStack(app, "primary", {
env: { account: "123", region: "eu-west-1" },
});
cdk ls
输出:
edge-lambda-stack-cnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
primary
我与 AWS 高级支持人员进行了交谈,得到的答复是 CDK 似乎无法通过使用嵌套堆栈来处理此问题。
相反,在 us-east-1
中为 EdgeLambdas 创建一个单独的堆栈,然后将 lambdas 的 ARN 导出到 SSM。
在另一个堆栈中,import the ARNs from SSM and use those。
这将导致要处理的堆栈数量最少。您仍然需要分别部署这两个堆栈。
我最终使用的代码如下所示:
export function exportLambdaSsm(
func: cloudfront.experimental.EdgeFunction,
): ssm.StringParameter {
const funcName = // ...
return new ssm.StringParameter(this, `${funcName}-param`, {
// Parameter with slash must start with a slash
parameterName: `/${funcName}`,
stringValue: func.functionArn,
});
}
export function importLambdaFromSsm(stack: Stack): lambda.IVersion {
const funcName = // ...
const funcResource = new cr.AwsCustomResource(stack, `${funcName}-param`, {
policy: cr.AwsCustomResourcePolicy.fromStatements([
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ["ssm:GetParameter*"],
resources: [
stack.formatArn({
service: "ssm",
region: "us-east-1",
resource: "parameter",
resourceName: funcName,
}),
],
}),
]),
onUpdate: {
// will also be called for a CREATE event
service: "SSM",
action: "getParameter",
parameters: {
Name: `/${funcName}`,
},
region: "us-east-1",
// Update physical id to always fetch the latest version
physicalResourceId: cr.PhysicalResourceId.of(Date.now().toString()),
},
});
return lambda.Version.fromVersionArn(stack, funcName, funcResource.getResponseField("Parameter.Value"));
}
请注意,在获取和存储 SSM 值时,有很多关于斜线位置的规则。我试图保持上面的代码正确。