dynamo (terraform)
Reference
cloudposse/terraform-aws-dynamodb
https://github.com/cloudposse/terraform-aws-dynamodb/blob/master/main.tf
Table with other attributes in addition to the KeySchema (either only hash_key or with range_key)
Update: Terraform AWS provider 4.39.0 added resource:
aws_dynamodb_table_item
which represents a 'record' of the table, not an individual attribute.
Although it's possible in the AWS Console to define a Dynamo table with hash_key (no range_key) and several other attributes; this isn't possible with Terraform:
all attributes must be indexed. Unused attributes
Alternatives:
a) Declare table with only attributes that are going to be used as:
Table hash key or range key
LSI or GSI hash key or range key
Best option. Leave other attributes undeclared.
b) Global Secondary Index (GSI)
Not recommended. Create as many secondary indexes (using their hash_key either with or without range_key) as needed for all defined attributes.
The number of GSIs per table are limited.
Note: When creating an item from the AWS console, only the hash_key (and range_key if exists) appear, but any additional attribute can be added.
c) Local Secondary Index (LSI)
Not a viable option because local_secondary_index requires that the table KeySchema have a range key
Sample: Create table with auto scaling
pro/main.tf
...
module "dynamodb" {
source = "../modules/dynamodb"
env = local.COUEnv
ci = local.ci
department = local.Departament
program = local.Programa
#PITR only enabled for PRO environment
point_in_time_recovery_enabled = false
dynamo_EmailRedirect_read_cap = "1" # Default Read Capacity
dynamo_EmailRedirect_write_cap = "1" # Default Write Capacity
dynamo_EmailRedirect_aut_max = "40" # Autoscale Max Capacity
dynamo_EmailRedirect_aut_min = "1" # Autoscale Min Capacity
dynamo_EmailRedirect_aut_target = "60" # Autoscale Target Read/Write Capacity %
}
modules/dynamo/variables.tf
variable "env" {}
variable "ci" {}
variable "department" {}
variable "program" {}
#
variable "point_in_time_recovery_enabled" { type = bool }
variable "dynamo_EmailRedirect_read_cap" {}
variable "dynamo_EmailRedirect_write_cap" {}
variable "dynamo_EmailRedirect_aut_max" {}
variable "dynamo_EmailRedirect_aut_min" {}
variable "dynamo_EmailRedirect_aut_target" {}
modules/dynamo/dynamo.tf
# Table EmailRedirect
resource "aws_dynamodb_table" "EmailRedirect" {
name = "${var.env}-${var.ci}-EmailRedirect"
billing_mode = "PROVISIONED"
read_capacity = var.dynamo_EmailRedirect_read_cap
write_capacity = var.dynamo_EmailRedirect_write_cap
hash_key = "Email"
range_key = "Alias"
point_in_time_recovery {
#PITR provides continuous backups, and you can restore to any point in time up to the second during the preceding 35 days.
enabled = var.point_in_time_recovery_enabled
}
lifecycle {
ignore_changes = [
read_capacity,
write_capacity
]
}
attribute {
name = "Email"
type = "S"
}
attribute {
name = "Alias"
type = "S"
}
tags = {
COUEnv = var.env
ci = var.ci
Departament = var.department
Programa = var.program
}
}
# Autoscaling Read
resource "aws_appautoscaling_target" "EmailRedirect_read_target" {
max_capacity = var.dynamo_EmailRedirect_aut_max
min_capacity = var.dynamo_EmailRedirect_aut_min
resource_id = "table/${aws_dynamodb_table.EmailRedirect.name}"
scalable_dimension = "dynamodb:table:ReadCapacityUnits"
service_namespace = "dynamodb"
}
resource "aws_appautoscaling_policy" "EmailRedirect_read_policy" {
name = "DynamoDBReadCapacityUtilization:${aws_appautoscaling_target.EmailRedirect_read_target.resource_id}"
policy_type = "TargetTrackingScaling"
resource_id = aws_appautoscaling_target.EmailRedirect_read_target.resource_id
scalable_dimension = aws_appautoscaling_target.EmailRedirect_read_target.scalable_dimension
service_namespace = aws_appautoscaling_target.EmailRedirect_read_target.service_namespace
target_tracking_scaling_policy_configuration {
predefined_metric_specification {
predefined_metric_type = "DynamoDBReadCapacityUtilization"
}
target_value = var.dynamo_EmailRedirect_aut_target
}
}
# Autoscaling Write
resource "aws_appautoscaling_target" "EmailRedirect_write_target" {
max_capacity = var.dynamo_EmailRedirect_aut_max
min_capacity = var.dynamo_EmailRedirect_aut_min
resource_id = "table/${aws_dynamodb_table.EmailRedirect.name}"
scalable_dimension = "dynamodb:table:WriteCapacityUnits"
service_namespace = "dynamodb"
}
resource "aws_appautoscaling_policy" "EmailRedirect_write_policy" {
name = "DynamoDBWriteCapacityUtilization:${aws_appautoscaling_target.EmailRedirect_write_target.resource_id}"
policy_type = "TargetTrackingScaling"
resource_id = aws_appautoscaling_target.EmailRedirect_write_target.resource_id
scalable_dimension = aws_appautoscaling_target.EmailRedirect_write_target.scalable_dimension
service_namespace = aws_appautoscaling_target.EmailRedirect_write_target.service_namespace
target_tracking_scaling_policy_configuration {
predefined_metric_specification {
predefined_metric_type = "DynamoDBWriteCapacityUtilization"
}
target_value = var.dynamo_EmailRedirect_aut_target
}
}