amazon-web-services - CDK:可以将为 EdgeFunction 资源创建的堆栈放在另一个(跨区域)堆栈中吗?
问题描述
问题陈述
我有我的主 CDK 堆栈eu-west-1
,但EdgeFunction
在us-east-1
.
我注意到两个奇怪的事情EdgeFunction
:
- 即使在 a 中声明,
NestedStack
它们也会显示cdk ls
为edge-lambda-stack-nnnnnnnnn
(除非给出明确的名称)。 - 删除主堆栈时,我们称之为
primary
,它不会删除 lambda 堆栈。可能是因为上面的 (1) 告诉我它不是NestedStack
.
我曾尝试将其放入显式EdgeFunction
创建的单独堆栈中us-east-1
,然后从中交叉引用它,primary
但由于“无法以跨环境方式使用资源”(以及其他方式)而失败。
问题
- 为什么不
cloudfront.experimental.EdgeFunction
尊重NestedStack
边界? - 我可以以某种方式构建一个
Stack
存在于us-east-1
的 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 似乎无法通过使用嵌套堆栈来处理这个问题。
相反,为其中的 EdgeLambdas 创建一个单独的堆栈,us-east-1
然后将 lambdas 的 ARN 导出到 SSM。
在另一个堆栈中,从 SSM 导入 ARN 并使用那些.
这将导致要处理的堆栈数量最少。您仍然需要分别部署这两个堆栈。
我最终使用的代码如下所示:
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 值时,关于斜线的位置有很多规则。我试图保持上面的代码正确。
推荐阅读
- java - 完成对 Web 服务的多次调用时使用的设计模式
- javascript - 将 Csv 转换为 Json 时发生 JavaScript 错误
- c - 如何在 C 中以特定速率运行循环(在仿真中)
- javascript - 谷歌 oauth2.0 显示无效客户端错误
- google-api - Google oAuth API:如何为未经身份验证的用户显示谷歌登录层?
- php - 使用 codeigniter 的 dompdf 库不起作用 html 和 css
- java - 如何在java中捕获没有数据的堆转储
- java - 如何解压缩包含多个文件的 .gz 文件
- java - 获取数据集并将其打印到二维数组中
- python - 如何将所有单词与正则表达式匹配,除了 urls 或类似的?