Вот моя региональная конфигурация лямбда-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",
...
Хорошо. идея возникла из этого ответа.
То, как я сделал это с 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.