Skip to content

Commit c4a8306

Browse files
feat: Added autoscaled table resource (may cause unexpected changes) (#43)
1 parent 91ee4cb commit c4a8306

File tree

5 files changed

+120
-10
lines changed

5 files changed

+120
-10
lines changed

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,22 @@ module "dynamodb_table" {
2525
}
2626
```
2727

28+
## Notes
29+
30+
**Warning: enabling or disabling autoscaling can cause your table to be recreated**
31+
32+
There are two separate Terraform resources used for the DynamoDB table: one is for when any autoscaling settings are used and the other when not. The following scenarios will make Terraform recreate the table:
33+
34+
- Upgrading from an older version of this module with autoscaling settings enabled
35+
- Enabling autoscaling settings when they were previously disabled
36+
- Disabling autoscaling settings when they were previously enabled
37+
38+
In these scenarios you will need to move the old `aws_dynamodb_table` resource that is being `destroyed` to the new resource that is being `created`. For example:
39+
40+
```
41+
terraform state mv module.dynamodb_table.aws_dynamodb_table.this module.dynamodb_table.aws_dynamodb_table.autoscaled
42+
```
43+
2844
## Examples
2945

3046
- [Basic example](https://github.com/terraform-aws-modules/terraform-aws-dynamodb-table/tree/master/examples/basic)
@@ -61,6 +77,7 @@ No modules.
6177
| [aws_appautoscaling_target.index_write](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/appautoscaling_target) | resource |
6278
| [aws_appautoscaling_target.table_read](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/appautoscaling_target) | resource |
6379
| [aws_appautoscaling_target.table_write](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/appautoscaling_target) | resource |
80+
| [aws_dynamodb_table.autoscaled](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/dynamodb_table) | resource |
6481
| [aws_dynamodb_table.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/dynamodb_table) | resource |
6582

6683
## Inputs

autoscaling.tf

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ resource "aws_appautoscaling_target" "table_read" {
33

44
max_capacity = var.autoscaling_read["max_capacity"]
55
min_capacity = var.read_capacity
6-
resource_id = "table/${aws_dynamodb_table.this[0].name}"
6+
resource_id = "table/${aws_dynamodb_table.autoscaled[0].name}"
77
scalable_dimension = "dynamodb:table:ReadCapacityUnits"
88
service_namespace = "dynamodb"
99
}
@@ -33,7 +33,7 @@ resource "aws_appautoscaling_target" "table_write" {
3333

3434
max_capacity = var.autoscaling_write["max_capacity"]
3535
min_capacity = var.write_capacity
36-
resource_id = "table/${aws_dynamodb_table.this[0].name}"
36+
resource_id = "table/${aws_dynamodb_table.autoscaled[0].name}"
3737
scalable_dimension = "dynamodb:table:WriteCapacityUnits"
3838
service_namespace = "dynamodb"
3939
}
@@ -63,7 +63,7 @@ resource "aws_appautoscaling_target" "index_read" {
6363

6464
max_capacity = each.value["read_max_capacity"]
6565
min_capacity = each.value["read_min_capacity"]
66-
resource_id = "table/${aws_dynamodb_table.this[0].name}/index/${each.key}"
66+
resource_id = "table/${aws_dynamodb_table.autoscaled[0].name}/index/${each.key}"
6767
scalable_dimension = "dynamodb:index:ReadCapacityUnits"
6868
service_namespace = "dynamodb"
6969
}
@@ -93,7 +93,7 @@ resource "aws_appautoscaling_target" "index_write" {
9393

9494
max_capacity = each.value["write_max_capacity"]
9595
min_capacity = each.value["write_min_capacity"]
96-
resource_id = "table/${aws_dynamodb_table.this[0].name}/index/${each.key}"
96+
resource_id = "table/${aws_dynamodb_table.autoscaled[0].name}/index/${each.key}"
9797
scalable_dimension = "dynamodb:index:WriteCapacityUnits"
9898
service_namespace = "dynamodb"
9999
}

examples/autoscaling/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# DynamoDB Table autoscaling example
22

3-
Configuration in this directory creates AWS DynamoDB table with autoscaling.
3+
Configuration in this directory creates AWS DynamoDB table with autoscaling. Be sure to read [the note](../../README.md#Notes) about autoscaling settings causing the table to be recreated.
44

55
## Usage
66

main.tf

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
locals {
2+
autoscaling_enabled = length(var.autoscaling_read) + length(var.autoscaling_write) + length(var.autoscaling_indexes) > 0 ? true : false
3+
create_normal_table = var.create_table && !local.autoscaling_enabled ? 1 : 0
4+
create_autoscaled_table = var.create_table && local.autoscaling_enabled ? 1 : 0
5+
}
6+
17
resource "aws_dynamodb_table" "this" {
2-
count = var.create_table ? 1 : 0
8+
count = local.create_normal_table
39

410
name = var.name
511
billing_mode = var.billing_mode
@@ -80,3 +86,90 @@ resource "aws_dynamodb_table" "this" {
8086
update = lookup(var.timeouts, "update", null)
8187
}
8288
}
89+
90+
resource "aws_dynamodb_table" "autoscaled" {
91+
count = local.create_autoscaled_table
92+
93+
name = var.name
94+
billing_mode = var.billing_mode
95+
hash_key = var.hash_key
96+
range_key = var.range_key
97+
read_capacity = var.read_capacity
98+
write_capacity = var.write_capacity
99+
stream_enabled = var.stream_enabled
100+
stream_view_type = var.stream_view_type
101+
102+
ttl {
103+
enabled = var.ttl_enabled
104+
attribute_name = var.ttl_attribute_name
105+
}
106+
107+
point_in_time_recovery {
108+
enabled = var.point_in_time_recovery_enabled
109+
}
110+
111+
dynamic "attribute" {
112+
for_each = var.attributes
113+
114+
content {
115+
name = attribute.value.name
116+
type = attribute.value.type
117+
}
118+
}
119+
120+
dynamic "local_secondary_index" {
121+
for_each = var.local_secondary_indexes
122+
123+
content {
124+
name = local_secondary_index.value.name
125+
range_key = local_secondary_index.value.range_key
126+
projection_type = local_secondary_index.value.projection_type
127+
non_key_attributes = lookup(local_secondary_index.value, "non_key_attributes", null)
128+
}
129+
}
130+
131+
dynamic "global_secondary_index" {
132+
for_each = var.global_secondary_indexes
133+
134+
content {
135+
name = global_secondary_index.value.name
136+
hash_key = global_secondary_index.value.hash_key
137+
projection_type = global_secondary_index.value.projection_type
138+
range_key = lookup(global_secondary_index.value, "range_key", null)
139+
read_capacity = lookup(global_secondary_index.value, "read_capacity", null)
140+
write_capacity = lookup(global_secondary_index.value, "write_capacity", null)
141+
non_key_attributes = lookup(global_secondary_index.value, "non_key_attributes", null)
142+
}
143+
}
144+
145+
dynamic "replica" {
146+
for_each = var.replica_regions
147+
148+
content {
149+
region_name = replica.value.region_name
150+
kms_key_arn = lookup(replica.value, "kms_key_arn", null)
151+
}
152+
}
153+
154+
server_side_encryption {
155+
enabled = var.server_side_encryption_enabled
156+
kms_key_arn = var.server_side_encryption_kms_key_arn
157+
}
158+
159+
tags = merge(
160+
var.tags,
161+
{
162+
"Name" = format("%s", var.name)
163+
},
164+
)
165+
166+
timeouts {
167+
create = lookup(var.timeouts, "create", null)
168+
delete = lookup(var.timeouts, "delete", null)
169+
update = lookup(var.timeouts, "update", null)
170+
}
171+
172+
lifecycle {
173+
ignore_changes = [read_capacity, write_capacity]
174+
}
175+
}

outputs.tf

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
output "dynamodb_table_arn" {
22
description = "ARN of the DynamoDB table"
3-
value = element(concat(aws_dynamodb_table.this.*.arn, [""]), 0)
3+
value = try(aws_dynamodb_table.this[0].arn, aws_dynamodb_table.autoscaled[0].arn, "")
44
}
55

66
output "dynamodb_table_id" {
77
description = "ID of the DynamoDB table"
8-
value = element(concat(aws_dynamodb_table.this.*.id, [""]), 0)
8+
value = try(aws_dynamodb_table.this[0].id, aws_dynamodb_table.autoscaled[0].id, "")
99
}
1010

1111
output "dynamodb_table_stream_arn" {
1212
description = "The ARN of the Table Stream. Only available when var.stream_enabled is true"
13-
value = var.stream_enabled ? concat(aws_dynamodb_table.this.*.stream_arn, [""])[0] : null
13+
value = var.stream_enabled ? try(aws_dynamodb_table.this[0].id, aws_dynamodb_table.autoscaled[0].stream_arn, "") : null
1414
}
1515

1616
output "dynamodb_table_stream_label" {
1717
description = "A timestamp, in ISO 8601 format of the Table Stream. Only available when var.stream_enabled is true"
18-
value = var.stream_enabled ? concat(aws_dynamodb_table.this.*.stream_label, [""])[0] : null
18+
value = var.stream_enabled ? try(aws_dynamodb_table.this[0].id, aws_dynamodb_table.autoscaled[0].stream_label, "") : null
1919
}

0 commit comments

Comments
 (0)