我有一个现有的DynamoDB表,它被定义为CloudFormation堆栈的一部分。根据CFN AWS::DynamoDB::表文档,GlobalSecondaryIndexes属性不需要替换。它甚至详细说明了以下几点。
您可以不间断地删除或添加一个全局辅助索引。
以及下面的..。
如果更新一个表以包含新的全局辅助索引,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,这表明它确实需要替换。然而,即使我试图添加一个只定义在AttributeDefinitions中的现有属性的GSI,我仍然会得到相同的错误消息。
下面是我的表的原始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"
}
}
}
]
}
}
}但是,正如我前面提到的,即使我没有在userId中定义AttributeDefinitions并在新的GSI定义中使用一个现有属性,它也不能工作,并且在相同的错误消息中失败。
发布于 2016-04-30 02:07:46
我今天也犯了同样的错误,并得到了亚马逊技术支持部门的答复。问题是您提供了一个TableName字段。CloudFormation想要负责为您命名您的表。显然,当您为它们提供您自己的名称时,这是您在更新中得到的替换表的错误(不确定它为什么需要替换,但这是医生说的)
对我来说,这使得CloudFormation在维护我的DynamoDB表时毫无用处。我必须在配置中构建,这样我的代码才能动态地知道CloudFormation为我生成的随机表名是什么。
发布于 2016-05-17 15:40:40
AWS支助部门对我的答复:
解决办法A
优点是,应用程序代码可以继续使用固定名称。但是,两次更新堆栈和导出/导入数据需要一些工作才能在自定义脚本中实现自动化。
变通办法B
虽然我认为这避免了额外的堆栈更新(仍然认为需要导出/导入数据),但缺点是在代码中使用网络调用来获取表名。见* http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CloudFormation.html#describeStackResource-property
同样,这是一个已知的问题--支持正在推动服务团队前进,因为我们知道这是一个非常常见的用例和痛点。在测试产品之前,请先在测试环境上尝试一种解决方法。
发布于 2020-01-03 07:48:17
这个问题是怎么发生的?对于我来说,在dynamoDB控制台中手动删除GSI,然后通过cloudformation添加GSI,更新堆栈得到了这个错误。
解决方案:删除cloudformation中的GSI,执行更新堆栈,然后添加回GSI,再次执行更新堆栈,工作正常。
猜测cloudformation有自己的缓存,无法告诉您在控制台中手动进行的更改。
https://stackoverflow.com/questions/36918408
复制相似问题