_This issue was originally opened by @nunoperalta as hashicorp/terraform#22942. It was migrated here as a result of the provider split. The original body of the issue is below._
Terraform v0.12.9
+ provider.aws v2.30.0
resource "aws_dynamodb_table" "dynamodb-testdb" {
name = "TestDb"
billing_mode = "PAY_PER_REQUEST"
hash_key = "PriKey"
range_key = "Quantity"
attribute {
name = "PriKey"
type = "S"
}
attribute {
name = "Quantity"
type = "N"
}
ttl {
attribute_name = "TimeToExist"
enabled = false
}
}
When doing "terraform apply" twice, there should be no changes to make.
First "terraform apply" will create the DynamoDB table.
However, second time, there will be a change at:
~ ttl {
+ attribute_name = "TimeToExist"
enabled = false
}
If I confirm the change, I get this crash:
Error: error updating DynamoDB Table (TestDb) time to live: error updating DynamoDB Table (TestDb) Time To Live: ValidationException: TimeToLive is already disabled
status code: 400, request id: XXXXXX
If I remove the "attribute_name", I get this error:
The argument "attribute_name" is required, but no definition was found.
Just to give more context here and to https://github.com/terraform-providers/terraform-provider-aws/issues/3463
I just found out talking with AWS that the DynamoDB TTL API is batched, meaning that there is no way without to set atomically AttributeName and Enabled. Running the same operation through AWS CLI will result in the same 400 BadRequest errors because that's just how Dynamo DB TTL API works.
It is normal for DynamoDB API to reply with an error when trying to disable an already-disabeld TTL; and it's normal to not be able to enable/disable in a short period of time, you would get this error form CLI
➜ ~ aws dynamodb update-time-to-live --table-name my-table --time-to-live-specification "Enabled=true, AttributeName=UpdateTime"
An error occurred (ValidationException) when calling the UpdateTimeToLive operation: Time to live has been modified multiple times within a fixed interval
This is a PITA for Terraform because it means that when operating through the DynamoDB TTL settings we should have a polling or a time-bound control that we can actually perform an atomic operation.
I'll chat again with AWS soon and hopefully prepare a pull request with a proposed fix...
As per this doc page
It can take up to one hour for the change to fully process. Any additional UpdateTimeToLive calls for the same table during this one hour duration result in a ValidationException.
so we can't really have this state reconciliation loop in Terraform...
The "ValidationException: TimeToLive is already disabled" error is quite annoying if you are trying to modularize this.
As a work around, consider using a dynamic block.
credit: https://www.reddit.com/r/Terraform/comments/d1va2o/terrfaorm_support_null_block/
locals {
ttl = (var.ttl_enable == true ? [
{
ttl_enable = var.ttl_enable
ttl_attribute : var.ttl_attribute
}
] : [])
}
...
dynamic "ttl" {
for_each = local.ttl
content {
enabled = local.ttl[0].ttl_enable
attribute_name = local.ttl[0].ttl_attribute
}
}
Most helpful comment
The "ValidationException: TimeToLive is already disabled" error is quite annoying if you are trying to modularize this.
As a work around, consider using a dynamic block.
credit: https://www.reddit.com/r/Terraform/comments/d1va2o/terrfaorm_support_null_block/