Amazon web services 无法使用CloudFormation将GSI添加到DynamoDB表
我有一个现有的DynamoDB表,它被定义为CloudFormation堆栈的一部分。根据定义,GlobalSecondaryIndex属性不需要替换。它甚至详细说明了以下注意事项 您可以不间断地删除或添加一个全局辅助索引 以及以下内容 如果更新表以包含新的全局二级索引,则AWS CloudFormation启动索引创建,然后继续 堆栈更新。AWS CloudFormation不会等待索引恢复 完成创建,因为回填阶段可能需要很长时间, 取决于桌子的大小 但是,实际上,当我尝试执行更新时,会收到以下错误消息:Amazon web services 无法使用CloudFormation将GSI添加到DynamoDB表,amazon-web-services,amazon-dynamodb,amazon-cloudformation,Amazon Web Services,Amazon Dynamodb,Amazon Cloudformation,我有一个现有的DynamoDB表,它被定义为CloudFormation堆栈的一部分。根据定义,GlobalSecondaryIndex属性不需要替换。它甚至详细说明了以下注意事项 您可以不间断地删除或添加一个全局辅助索引 以及以下内容 如果更新表以包含新的全局二级索引,则AWS CloudFormation启动索引创建,然后继续 堆栈更新。AWS CloudFormation不会等待索引恢复 完成创建,因为回填阶段可能需要很长时间, 取决于桌子的大小 但是,实际上,当我尝试执行更新时,会收到以
CloudFormation cannot update a stack when a custom-named resource requires replacing. Rename mytablename and update the stack again.
由于我添加了一个使用新属性的GSI,我不得不修改AttributeDefinitions,这表示它确实需要替换。然而,即使我尝试添加一个GSI,其中只有AttributeDefinitions中定义的现有属性,我仍然会收到相同的错误消息
以下是我的表的原始CFN定义的片段:
{
"myTable": {
"Type": "AWS::DynamoDB::Table",
"Properties": {
"TableName": "mytablename",
"AttributeDefinitions": [
{
"AttributeName": "entryId",
"AttributeType": "S"
},
{
"AttributeName": "entryName",
"AttributeType": "S"
},
{
"AttributeName": "appId",
"AttributeType": "S"
}
],
"KeySchema": [
{
"KeyType": "HASH",
"AttributeName": "entryId"
},
{
"KeyType": "RANGE",
"AttributeName": "entryName"
}
],
"ProvisionedThroughput": {
"ReadCapacityUnits": {
"Ref": "readThroughput"
},
"WriteCapacityUnits": {
"Ref": "writeThroughput"
}
},
"GlobalSecondaryIndexes": [
{
"IndexName": "appId-index",
"KeySchema": [
{
"KeyType": "HASH",
"AttributeName": "appId"
}
],
"Projection": {
"ProjectionType": "KEYS_ONLY"
},
"ProvisionedThroughput": {
"ReadCapacityUnits": {
"Ref": "readThroughput"
},
"WriteCapacityUnits": {
"Ref": "writeThroughput"
}
}
}
]
}
}
}
以下是我想要更新的内容:
{
"myTable": {
"Type": "AWS::DynamoDB::Table",
"Properties": {
"TableName": "mytablename",
"AttributeDefinitions": [
{
"AttributeName": "entryId",
"AttributeType": "S"
},
{
"AttributeName": "entryName",
"AttributeType": "S"
},
{
"AttributeName": "appId",
"AttributeType": "S"
},
{
"AttributeName": "userId",
"AttributeType": "S"
}
],
"KeySchema": [
{
"KeyType": "HASH",
"AttributeName": "entryId"
},
{
"KeyType": "RANGE",
"AttributeName": "entryName"
}
],
"ProvisionedThroughput": {
"ReadCapacityUnits": {
"Ref": "readThroughput"
},
"WriteCapacityUnits": {
"Ref": "writeThroughput"
}
},
"GlobalSecondaryIndexes": [
{
"IndexName": "appId-index",
"KeySchema": [
{
"KeyType": "HASH",
"AttributeName": "appId"
}
],
"Projection": {
"ProjectionType": "KEYS_ONLY"
},
"ProvisionedThroughput": {
"ReadCapacityUnits": {
"Ref": "readThroughput"
},
"WriteCapacityUnits": {
"Ref": "writeThroughput"
}
}
},
{
"IndexName": "userId-index",
"KeySchema": [
{
"KeyType": "HASH",
"AttributeName": "userId"
}
],
"Projection": {
"ProjectionType": "KEYS_ONLY"
},
"ProvisionedThroughput": {
"ReadCapacityUnits": {
"Ref": "readThroughput"
},
"WriteCapacityUnits": {
"Ref": "writeThroughput"
}
}
}
]
}
}
}
但是,正如我前面提到的,即使我没有在AttributeDefinitions中定义userId,并且在新的GSI定义中使用现有属性,它也不会工作,并且会失败,并显示相同的错误消息。我今天也遇到了相同的错误,并从Amazon技术支持部门得到了答案。问题是您提供了一个TableName字段。CloudFormation希望负责为您的表命名。显然,当您为它们提供自己的名称时,这就是您在替换表的更新中遇到的错误(不确定为什么需要替换,但文档是这么说的)
对我来说,这使得CloudFormation对于维护我的DynamoDB表毫无用处。我必须内置配置,以便我的代码能够动态地告诉我CloudFormation为我生成的随机表名。AWS支持部门对我的回应FWIW: 解决问题
- 注意,这会丢失所有当前条目,因此一定要先备份到s3李>
同样,这是一个众所周知的问题,支持正在推动服务团队前进,因为我们知道这是一个非常常见的用例和难点。在进行生产测试之前,请在测试环境中尝试解决方法。备份DynamoDB中的所有数据,然后,如果您使用的是无服务器,请执行以下任一命令: 个人删除:
node ./node_modules/serverless/bin/serverless remove
全局删除:
serverless remove
并通过运行以下命令再次部署它:
node ./node_modules/serverless/bin/serverless deploy -v
或
我的设想是,我想通过更改GSI的范围键来更新GSI。
-首先,您必须删除您正在更新的GSI,还记得删除由于删除GSI而可能不再需要的任何AttributeDefinition,即索引名等。通过CloudFormation上载模板以应用更改。
-然后将所需的属性和“更新的”GSI添加到模板中。问题是如何发生的? 对于我来说,在dynamoDB控制台中手动删除GSI,然后通过cloudformation添加GSI,更新堆栈得到这个错误 解决方案:删除cloudformation中的GSI,执行更新堆栈,然后添加回GSI,再次执行更新堆栈,工作正常
猜测cloudformation有自己的缓存,无法判断您在控制台中手动进行的更改。我可以确认,当我尝试添加GSI而不更改AttributeDefinitions时,也会发生同样的情况。文件还规定了以下内容:“更新要求:不支持更新。除了以下例外:如果只更新全局辅助索引的已设置吞吐量值,则可以不中断地更新表。您可以不间断地删除或添加一个全局辅助索引。如果在同一更新中同时执行这两项操作(例如,通过更改索引的逻辑ID),则更新将失败。“在亚马逊方面,我不明白的是,云信息如何可能对迪纳摩有用。当然,我想选择一个我命名的表…这对我来说毫无意义。您可以在运行时通过逻辑ID(CFN模板中的名称)从CloudFormation获取表名。如果这样做,您可以将备份的数据还原到新创建的表中吗?“还要记住删除任何可能不再需要的属性定义“,这就是我所缺少的。如果该属性未在gsi中使用,则该属性不应存在于AttributeDefinition中。这对我很有用。自定义表名应该没有问题。如果有相同的问题,我必须先执行
sls-remove
,然后执行sls-deploy-v
,以获得一个干净的列表:)
serverless deploy