要部署到 us-east-1 的 Lambda@Edge 限制阻止我将 S3 存储桶部署到欧洲
Lambda@Edge limitation to be deployed to us-east-1 prevents me from deploying S3 bucket to Europe
更新:
问题的简短版本,我想交叉引用不同区域不同堆栈中的某些值,但文档太混乱了,让我觉得不可能这样做,但这是可能的,只是我不得不这样做将这些值输出为该堆栈中的导出值,然后使用:
${cf.us-east-1:another-stack.theNeededArn}
在另一个堆栈中。
长版如果你感兴趣:
我正在使用无服务器框架维护基础架构代码。我有连接到托管在欧洲的 S3 存储桶的 CloudFront。我收到一个客户端请求,要求通过 CloudFront 限制对这个存储桶的访问,仅限于经过身份验证的用户(自定义身份验证)。 Lambda@Edge 是最好的解决方案,我已经以这种方式实现了它,但是因为 Lambda@Edge 必须部署到 us-east-1,所以我最终将 S3 和 Cloudfront 移动到同一区域 us-east-1(那是因为 Cloofront 依赖于 lambda edge 而 S3 依赖于 CloudFront 所以我必须将它们保持在同一个堆栈或至少同一个区域中)。但我不想为了合法的东西把我的桶搬到美国,我想把数据保存在欧洲,而且我的 S3 有一个 lambda 触发器功能,可以监听它并将一些数据写入欧洲托管的 DynamoDb。
所以问题是:
我在欧洲有 S3,我想将它保留在欧洲,但由于使用了 lambda 边缘,并且由于云形成或无服务器不支持跨区域堆栈引用,我最终将这个 S3 移到了美国,但事实并非如此要求!
- 我认为即使我们使用云端,但我们所有的客户都在欧洲并将 S3 存储桶放在美国会增加延迟。
- 对于合法的东西,我想将欧洲用户的数据保留在欧洲内部,而不是将其移到外部。
在这个问题的答案中,我指定了我的方法和完整的代码示例,以防您感兴趣:
有什么建议吗?
更新(显示确切问题的步骤):
- 在我的 serverless.yml 中,我创建了包含此 lambda 的堆栈
边缘:
我不想使用无服务器框架配置 lambda 边缘,而是使用云形成来配置云前端和所有内容。
- 在cloud formation resources文件中,我添加了cloud front
来源并通过其行为配置私有来源以使用
lambda边(请注意图中高亮部分):
请注意,现在我在我的 Cloudfront 中使用 lambda edge ARN,因此它们需要位于同一区域,并且因为 lambda@edge 应该位于 us-east-1 中,所以我决定将 CloudFront 移动到同一区域并且确实如此并不重要,因为它在设计上具有边缘行为。
- 此外,如果您对这里感兴趣,我定义了所有需要的角色
步骤 1 中预定义的 lambda 边(包括
发布正确的策略以及 lambda edge 版本作为
在 lambda edge 中,你必须引用版本,而不是函数
并在这一步中完成所有设置,为了完整起见,我只是将其放在这里。):
- 现在我有云前端配置,lambda边缘配置,
在云端,我们引用了 lambda edge ARN,它
引导我将它们放在同一区域,但现在我将定义我的 S3
存储桶并将其设为私有,因此没有人可以访问它,只有
云端 CloudFrontOriginAccessIdentity 可以做到这一点:
正如您在角色中看到的那样,我刚刚授予对 CloudFront 的访问权限以获取并授予对(lambda edge to get and put 但不确定这是否正确)的访问权限,但无论如何,即使我们只需要 CloudFrontOriginAccessIdentity连接到我的存储桶,所以现在存储桶与我的 CloudFront 链接,它也链接到 lambda 边缘,所以我不能将它们分开以仅将 S3 放在欧洲??
即使我有一个 S3 触发器 lambda 函数,所以我应该把这个函数放在美国,即使这个函数在欧洲做一些与 DynamoDb 相关的事情?那么有什么意义呢?此外,即使 Cloudfront 是边缘的但存储桶是区域性的,所以如果我真的需要处理一些与之相关的数据,这意味着通过将它放入我们我会增加延迟?这就是我的完整详细问题。
更新2:
我想 post 代码作为屏幕截图,这样我可以突出显示一些行并使其更容易但是对于那些有兴趣检查代码本身的人,我已经 post 在我对此的回答中编辑了它的完整版本问题在这里:
解决方案不是将所有内容都移至 us-east-1
,而是只维护两个堆栈,即主堆栈和 lambda 边缘堆栈。主堆栈位于 EU,lambda 边缘堆栈位于 us-east-1
。您可以使用 ${cf.us-east-1:another-stack.lambdaEdgeArn}
.
引用 us-east-1
中的 lambda 边缘函数
无法引用 Fn:ImportValue
从其他区域部署到 us-east-1
的 Lambda@Edge。在 CloudFormation 模板中,有一个解决方法,即动态查找特定于版本的 ARN 并将其作为模板参数传递给任务文件中的 CloudFront 模板。
- name: Get Lambda Version-ARN
shell:
cmd: "
aws lambda list-versions-by-function \
--function-name '{{ lambda_func_name }}' \
--region '{{ lambda_region }}' \
--query \"max_by(Versions, &to_number(to_number(Version) || '0'))\" \
| jq -r '.FunctionArn'
"
register: lambda_output
- set_fact:
lambda_arn: "{{ lambda_output.stdout }}"
- name: CloudFront
cloudformation:
stack_name: "{{ stack_name }}"
state: "{{ state }}"
region: "{{ region }}"
template: "roles/{{ role_name }}/templates/cloudfront-template.yml"
template_parameters:
LambdaARN: "{{ lambda_arn }}"
...
更新:
问题的简短版本,我想交叉引用不同区域不同堆栈中的某些值,但文档太混乱了,让我觉得不可能这样做,但这是可能的,只是我不得不这样做将这些值输出为该堆栈中的导出值,然后使用:
${cf.us-east-1:another-stack.theNeededArn}
在另一个堆栈中。
长版如果你感兴趣:
我正在使用无服务器框架维护基础架构代码。我有连接到托管在欧洲的 S3 存储桶的 CloudFront。我收到一个客户端请求,要求通过 CloudFront 限制对这个存储桶的访问,仅限于经过身份验证的用户(自定义身份验证)。 Lambda@Edge 是最好的解决方案,我已经以这种方式实现了它,但是因为 Lambda@Edge 必须部署到 us-east-1,所以我最终将 S3 和 Cloudfront 移动到同一区域 us-east-1(那是因为 Cloofront 依赖于 lambda edge 而 S3 依赖于 CloudFront 所以我必须将它们保持在同一个堆栈或至少同一个区域中)。但我不想为了合法的东西把我的桶搬到美国,我想把数据保存在欧洲,而且我的 S3 有一个 lambda 触发器功能,可以监听它并将一些数据写入欧洲托管的 DynamoDb。
所以问题是: 我在欧洲有 S3,我想将它保留在欧洲,但由于使用了 lambda 边缘,并且由于云形成或无服务器不支持跨区域堆栈引用,我最终将这个 S3 移到了美国,但事实并非如此要求!
- 我认为即使我们使用云端,但我们所有的客户都在欧洲并将 S3 存储桶放在美国会增加延迟。
- 对于合法的东西,我想将欧洲用户的数据保留在欧洲内部,而不是将其移到外部。
在这个问题的答案中,我指定了我的方法和完整的代码示例,以防您感兴趣:
有什么建议吗?
更新(显示确切问题的步骤):
- 在我的 serverless.yml 中,我创建了包含此 lambda 的堆栈 边缘:
我不想使用无服务器框架配置 lambda 边缘,而是使用云形成来配置云前端和所有内容。
- 在cloud formation resources文件中,我添加了cloud front 来源并通过其行为配置私有来源以使用 lambda边(请注意图中高亮部分):
- 此外,如果您对这里感兴趣,我定义了所有需要的角色 步骤 1 中预定义的 lambda 边(包括 发布正确的策略以及 lambda edge 版本作为 在 lambda edge 中,你必须引用版本,而不是函数 并在这一步中完成所有设置,为了完整起见,我只是将其放在这里。):
- 现在我有云前端配置,lambda边缘配置, 在云端,我们引用了 lambda edge ARN,它 引导我将它们放在同一区域,但现在我将定义我的 S3 存储桶并将其设为私有,因此没有人可以访问它,只有 云端 CloudFrontOriginAccessIdentity 可以做到这一点:
正如您在角色中看到的那样,我刚刚授予对 CloudFront 的访问权限以获取并授予对(lambda edge to get and put 但不确定这是否正确)的访问权限,但无论如何,即使我们只需要 CloudFrontOriginAccessIdentity连接到我的存储桶,所以现在存储桶与我的 CloudFront 链接,它也链接到 lambda 边缘,所以我不能将它们分开以仅将 S3 放在欧洲??
即使我有一个 S3 触发器 lambda 函数,所以我应该把这个函数放在美国,即使这个函数在欧洲做一些与 DynamoDb 相关的事情?那么有什么意义呢?此外,即使 Cloudfront 是边缘的但存储桶是区域性的,所以如果我真的需要处理一些与之相关的数据,这意味着通过将它放入我们我会增加延迟?这就是我的完整详细问题。
更新2:
我想 post 代码作为屏幕截图,这样我可以突出显示一些行并使其更容易但是对于那些有兴趣检查代码本身的人,我已经 post 在我对此的回答中编辑了它的完整版本问题在这里:
解决方案不是将所有内容都移至 us-east-1
,而是只维护两个堆栈,即主堆栈和 lambda 边缘堆栈。主堆栈位于 EU,lambda 边缘堆栈位于 us-east-1
。您可以使用 ${cf.us-east-1:another-stack.lambdaEdgeArn}
.
us-east-1
中的 lambda 边缘函数
无法引用 Fn:ImportValue
从其他区域部署到 us-east-1
的 Lambda@Edge。在 CloudFormation 模板中,有一个解决方法,即动态查找特定于版本的 ARN 并将其作为模板参数传递给任务文件中的 CloudFront 模板。
- name: Get Lambda Version-ARN
shell:
cmd: "
aws lambda list-versions-by-function \
--function-name '{{ lambda_func_name }}' \
--region '{{ lambda_region }}' \
--query \"max_by(Versions, &to_number(to_number(Version) || '0'))\" \
| jq -r '.FunctionArn'
"
register: lambda_output
- set_fact:
lambda_arn: "{{ lambda_output.stdout }}"
- name: CloudFront
cloudformation:
stack_name: "{{ stack_name }}"
state: "{{ state }}"
region: "{{ region }}"
template: "roles/{{ role_name }}/templates/cloudfront-template.yml"
template_parameters:
LambdaARN: "{{ lambda_arn }}"
...