Подписаться на глобальный поток таблиц dynamodb в региональных лямбда-выражениях aws?

Вот моя региональная конфигурация лямбда-SDK.

Кажется, проблема в tableStreamArn:

   const globalTableTableName = "my-org-glb-table1"

    const regionalTable = Table.fromTableAttributes(this, `Table-${Stack.of(this).region}`, {
        tableName: globalTableTableName,
        tableStreamArn: `arn:aws:dynamodb:${Stack.of(this).region}:${this.account}:table/${globalTableTableName}/stream/latest` // here !
    });

    const eventSource = new DynamoEventSource(regionalTable, {
        startingPosition: StartingPosition.TRIM_HORIZON,
        batchSize: 5,
        bisectBatchOnError: true,
        retryAttempts: 2
    });
    lambda1.addEventSource(eventSource);

Я не могу знать, какой поток будет у таблицы, поэтому мой лямбда-стек не может быть развернут.

Наличие stream/latest - не сработает:

❌ Не удалось развернуть: Ошибка: стек с именем app-my-org-lambda-stack не удалось создать, возможно, его придется удалить вручную из консоли AWS: ROLLBACK_COMPLETE: обработчик ресурса вернул сообщение: «Неверный запрос». предоставлено: Поток не найден: arn:aws:dynamodb:us-east-1:123456789012:table/app-my-org-glb-table1/stream/latest (Сервис: Lambda, код состояния: 400, идентификатор запроса: e165f9e7-f808-4528-b383-4992861e5aa0)" (RequestToken: d98d6f65-21d1-80b0-4ab3-7a3fc9430268, HandlerErrorCode: Неверный запрос)

Если я не делаю это неправильно, я проверил то и это:

Звучит хорошо, но как заставить это работать?

P.S. Я использовал конструкцию L1 для создания глобальной таблицы и проверил, что ее можно развернуть и там есть поток (с некоторым ARN).

if (stackRegion == PRIMARY_REGION) {

            const globalTable = new CfnGlobalTable(this, 'my-org-glb-table1', {
                tableName: "my-org-glb-table1",
                ...

57
1

Ответ:

Решено

Хорошо. идея возникла из этого ответа.

То, как я сделал это с CKD, выглядит следующим образом (и, кстати, GPT не справился с этим):

const globalTableTableName = "my-org-glb-table1"

    // getting the stream arn for the table
    const streamArnProvider = this.getStreamArnProviderService(props.lambdaStreamArnProviderArn, ecrRepo);
    const streamArnResource = new CustomResource(this, 'StreamArnResource', {
        serviceToken: streamArnProvider.serviceToken,
        properties: {
            TableName: globalTableTableName // this is where we pass table name to the lambda
        }
    });
    const streamArn = streamArnResource.getAtt('StreamArn').toString();
 const regionalTable = Table.fromTableAttributes(this, `${globalTableTableName}-${Stack.of(this).region}`, {
        tableName: globalTableTableName,
        tableStreamArn: streamArn
    });

где:

 private getStreamArnProviderService(streamArnProviderLambdaArn: string, ecrRepo: IRepository): Provider {

    const streamArnProviderLambda = lambda.Function.fromFunctionAttributes(this, 'ImportedLambda', {
        functionArn: streamArnProviderLambdaArn,
        // true, since the Lambda function is in the same environment and we want CDK to manage permissions
        sameEnvironment: true
    });

    return new Provider(this, 'StreamArnProviderService', {
        onEventHandler: streamArnProviderLambda,
    });
}

По сути, путем введения +1 лямбды, которая получала ARN из ARN таблицы для каждого региона.

А потокstreamArnProviderLambdaArn поступает из другого стека, который создает этот потокstreamArnProviderLambda.