gpt4 book ai didi

amazon-web-services - 在 CloudFormation 模板中从辅助区域引用全局 dynamodb 表

转载 作者:行者123 更新时间:2023-12-03 07:12:17 25 4
gpt4 key购买 nike

我们正在使用 CloudFormation 来定义我们的基础设施。使用在一个区域(主区域)中定义和创建的全局 dynamodb 表,但在另一区域中具有副本。如何在另一个区域的模板中引用同一个表?具体来说,我需要获取辅助区域中堆栈的全局表名称和流 ARN。原因?来自次要区域的此堆栈的一个 lambda 使用此名称和流 ARN 来为此表创建新记录。我以为任何使用全局表的人都会遇到这个问题,但我在网上搜索并没有找到任何简单的解决方案。

现在它在模板中的定义方式如下:

 Table1:
Type: AWS::DynamoDB::GlobalTable
Condition: CreateGlobalTable
Properties:
TableName: !Sub "Table1-${StageName}"
AttributeDefinitions:
- AttributeName: store_id
AttributeType: S
- AttributeName: client_name
AttributeType: S
BillingMode: PAY_PER_REQUEST
KeySchema:
- AttributeName: store_id
KeyType: HASH
- AttributeName: client_name
KeyType: RANGE
StreamSpecification:
StreamViewType: NEW_IMAGE
Replicas:
- Region: us-east-1
- Region: us-west-2
TimeToLiveSpecification:
AttributeName: time_to_live
Enabled: true

最佳答案

我遇到了完全相同的问题。借助这个blog entry ,我使用自定义资源提出了以下解决方案。

简而言之,我将堆栈分为 2 个:在一个堆栈中,我部署 DynamoDB::GlobalTable 以及一个 Serverless::Function,它将负责为我们获取流 ARN。另一方面,我有其余的组件。

第一个堆栈的模板如下所示:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Parameters:
DynamoTableName:
Type: "String"
Default: TableNameExample
MainRegion:
Type: "String"
Default: "eu-west-1"


Conditions:
IsMainRegionCondition: !Equals [ !Ref AWS::Region, !Ref MainRegion ]


Resources:
DynamoTable:
Condition: IsMainRegionCondition # Note: Deployed only in one region, replicated in others
Type: AWS::DynamoDB::GlobalTable
Properties:
TableName: !Ref DynamoTableName
BillingMode: PAY_PER_REQUEST
KeySchema:
- AttributeName: entity_id
KeyType: HASH
- AttributeName: language
KeyType: RANGE
AttributeDefinitions:
- AttributeName: entity_id
AttributeType: S
- AttributeName: language
AttributeType: S
StreamSpecification:
StreamViewType: NEW_AND_OLD_IMAGES
Replicas:
- Region: eu-west-1
PointInTimeRecoverySpecification:
PointInTimeRecoveryEnabled: true
- Region: us-east-1
PointInTimeRecoverySpecification:
PointInTimeRecoveryEnabled: true

GetGlobalTableStreamFunction:
Type: AWS::Serverless::Function
Properties:
Environment:
Variables:
TABLE_NAME: !Ref DynamoTableName
MemorySize: 256
CodeUri: functions/dynamo_db_stream/
Handler: app.lambda_handler
Runtime: python3.7
Policies:
- Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- dynamodb:DescribeTable
Resource: '*'

Outputs:
GetGlobalTableStreamFunctionArn:
Value: !GetAtt GetGlobalTableStreamFunction.Arn
Export:
Name: "get-global-table-stream-function-arn"

Lambda 的代码如下(请注意,您需要将 crhelper 依赖项与 Lambda 一起打包)。

import logging
import os

import boto3
from crhelper import CfnResource

TABLE_NAME = os.environ["TABLE_NAME"]

logger = logging.getLogger(__name__)

helper = CfnResource(
json_logging=False,
log_level='DEBUG',
boto_level='CRITICAL'
)

dynamo_db_client = boto3.client("dynamodb")


def lambda_handler(event, context):
helper(event, context)


def get_table_stream_arn():
logger.info(f"Getting stream ARN for table '{TABLE_NAME}'...")
response = dynamo_db_client.describe_table(
TableName=TABLE_NAME
)

logger.debug(f"Describe table response: {response}")
stream_arn = response["Table"]["LatestStreamArn"]
logger.info(f"ARN for table {TABLE_NAME}: {stream_arn}")
return stream_arn


@helper.create
def create(event, context):
logger.info("Received a 'Create' event")

stream_arn = get_table_stream_arn()
# This will make the stream ARN accessible via Cfn
# `!GetAtt DynamoTableStreamArnGetter.StreamArn`
helper.Data.update({"StreamArn": stream_arn})
return stream_arn


@helper.update
def update(event, context):
logger.info("Received an 'Update' event, doing nothing")


@helper.delete
def delete(event, context):
logger.info("Received a 'Delete' event, doing nothing")

然后,在第二个堆栈中,我们需要创建自定义资源。

Resources:

[...]

DynamoTableStreamArnGetter:
Type: 'Custom::DynamoTableStreamArnFunction'
Version: '1.0'
Properties:
ServiceToken: !ImportValue "get-global-table-stream-function-arn"

最后,您可以通过以下方式获取/引用副本区域(在第二个堆栈模板中)中的流 ARN:

!GetAtt DynamoTableStreamArnGetter.StreamArn

有关此解决方案的一些说明:

  1. 我不确定对于这种特殊情况,我们是否需要在 Lambda 的 create(...) 函数中返回stream_arn
  2. 在第一个模板中,我不喜欢授予描述所有表的权限(资源:'*')。但是,您无法引用 DynamoTable 资源,因为它不会存在于副本区域中。如果有人知道更好的方法将其限制在该表中,请告诉我。

关于amazon-web-services - 在 CloudFormation 模板中从辅助区域引用全局 dynamodb 表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72891607/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com