tfmodule-aws-dynamodb-global
Reusable and configurable Terraform AWS DynamoDB module
Prerequisites
Install Terraform CLI
Terraform must first be installed on your machine. Terraform is distributed as a binary package for all supported platforms and architectures.
https://releases.hashicorp.com/terraform/0.12.21/terraform_0.12.21_darwin_amd64.zip
https://releases.hashicorp.com/terraform/0.12.21/terraform_0.12.21_linux_amd64.zip
https://releases.hashicorp.com/terraform/0.12.21/terraform_0.12.21_windows_amd64.zip
Install Terraform by unzipping it and moving it to a directory included in your system's PATH.
How to use
main.tf
Module source can be instantiated multiple times, add as many times as many tables you need.
module "dynamodb" {
source = "git::https://github.com/melastmohican/tfmodule-aws-dynamodb-global"
environment = var.environment
table_name = "${upper(var.environment)}_ABC_TABLE"
attribute_list = [
{
name = "convState"
type = "S"
},
{
name = "id"
type = "S"
},
{
name = "tag"
type = "S"
}
]
hash_key = "id"
range_key = "tag"
tags = {
Application = "Example"
Environment = "Non-production::${upper(var.environment)}"
Owner = "devops@example.org"
Role = "DataSource"
}
global_secondary_index_list = [{
hash_key = "convState"
range_key = null
name = "convState-index"
non_key_attributes = []
projection_type = "ALL"
read_capacity = 0
write_capacity = 0
}]
local_secondary_index_list = []
ttl_list = [{
attribute_name = "expirationTime"
enabled = true
}]
providers = {
aws.us-west-2 = aws.us-west-2
aws.us-east-1 = aws.us-east-1
}
}
provider "aws" {
alias = "us-west-2"
}
provider "aws" {
alias = "us-east-1"
}
provider.tf
You can use an AWS credentials file to specify your credentials. The default location is $HOME/.aws/credentials on Linux and OS X, or "%USERPROFILE%.aws\credentials" for Windows users.
provider "aws" {
region = "us-west-2"
alias = "us-west-2"
shared_credentials_file = "$HOME/.aws/creds"
profile = "default"
}
provider "aws" {
region = "us-east-1"
alias = "us-east-1"
shared_credentials_file = "$HOME/.aws/creds"
profile = "default"
}
variables.tf
variable "environment" {
default = "dev"
}
Terraform workflow
- terraform init
- terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# module.dynamodb.aws_dynamodb_global_table.global_table will be created
+ resource "aws_dynamodb_global_table" "global_table" {
+ arn = (known after apply)
+ id = (known after apply)
+ name = "DEV_ABC_TABLE"
+ replica {
+ region_name = "us-east-1"
}
+ replica {
+ region_name = "us-west-2"
}
}
# module.dynamodb.aws_dynamodb_table.table_east will be created
+ resource "aws_dynamodb_table" "table_east" {
+ arn = (known after apply)
+ billing_mode = "PAY_PER_REQUEST"
+ hash_key = "ID"
+ id = (known after apply)
+ name = "DEV_ABC_TABLE"
+ range_key = "TYPE"
+ read_capacity = 0
+ stream_arn = (known after apply)
+ stream_enabled = true
+ stream_label = (known after apply)
+ stream_view_type = "NEW_AND_OLD_IMAGES"
+ tags = {
+ "Application" = "Example"
+ "Environment" = "Non-production"
+ "Owner" = "devops@example.org"
+ "Role" = "DataSource"
+ "Stack" = "Example"
}
+ write_capacity = 0
+ attribute {
+ name = "ID"
+ type = "S"
}
+ attribute {
+ name = "TYPE"
+ type = "S"
}
+ global_secondary_index {
+ hash_key = "TYPE"
+ name = "TYPE-ID-index"
+ non_key_attributes = []
+ projection_type = "ALL"
+ range_key = "ID"
+ read_capacity = 0
+ write_capacity = 0
}
+ point_in_time_recovery {
+ enabled = false
}
+ server_side_encryption {
+ enabled = (known after apply)
+ kms_key_arn = (known after apply)
}
}
# module.dynamodb.aws_dynamodb_table.table_west will be created
+ resource "aws_dynamodb_table" "table_west" {
+ arn = (known after apply)
+ billing_mode = "PAY_PER_REQUEST"
+ hash_key = "ID"
+ id = (known after apply)
+ name = "DEV_ABC_TABLE"
+ range_key = "TYPE"
+ read_capacity = 0
+ stream_arn = (known after apply)
+ stream_enabled = true
+ stream_label = (known after apply)
+ stream_view_type = "NEW_AND_OLD_IMAGES"
+ tags = {
+ "Application" = "Example"
+ "Environment" = "Non-production"
+ "Owner" = "devops@example.org"
+ "Role" = "DataSource"
+ "Stack" = "Example"
}
+ write_capacity = 0
+ attribute {
+ name = "ID"
+ type = "S"
}
+ attribute {
+ name = "TYPE"
+ type = "S"
}
+ global_secondary_index {
+ hash_key = "TYPE"
+ name = "TYPE-ID-index"
+ non_key_attributes = []
+ projection_type = "ALL"
+ range_key = "ID"
+ read_capacity = 0
+ write_capacity = 0
}
+ point_in_time_recovery {
+ enabled = false
}
+ server_side_encryption {
+ enabled = (known after apply)
+ kms_key_arn = (known after apply)
}
}
Plan: 3 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
- terraform apply
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# module.dynamodb.aws_dynamodb_global_table.global_table will be created
+ resource "aws_dynamodb_global_table" "global_table" {
+ arn = (known after apply)
+ id = (known after apply)
+ name = "DEV_ABC_TABLE"
+ replica {
+ region_name = "us-east-1"
}
+ replica {
+ region_name = "us-west-2"
}
}
# module.dynamodb.aws_dynamodb_table.table_east will be created
+ resource "aws_dynamodb_table" "table_east" {
+ arn = (known after apply)
+ billing_mode = "PAY_PER_REQUEST"
+ hash_key = "ID"
+ id = (known after apply)
+ name = "DEV_ABC_TABLE"
+ range_key = "TYPE"
+ read_capacity = 0
+ stream_arn = (known after apply)
+ stream_enabled = true
+ stream_label = (known after apply)
+ stream_view_type = "NEW_AND_OLD_IMAGES"
+ tags = {
+ "Application" = "Example"
+ "Environment" = "Non-production"
+ "Owner" = "devops@example.org"
+ "Role" = "DataSource"
+ "Stack" = "Example"
}
+ write_capacity = 0
+ attribute {
+ name = "ID"
+ type = "S"
}
+ attribute {
+ name = "TYPE"
+ type = "S"
}
+ global_secondary_index {
+ hash_key = "TYPE"
+ name = "TYPE-ID-index"
+ non_key_attributes = []
+ projection_type = "ALL"
+ range_key = "ID"
+ read_capacity = 0
+ write_capacity = 0
}
+ point_in_time_recovery {
+ enabled = false
}
+ server_side_encryption {
+ enabled = (known after apply)
+ kms_key_arn = (known after apply)
}
}
# module.dynamodb.aws_dynamodb_table.table_west will be created
+ resource "aws_dynamodb_table" "table_west" {
+ arn = (known after apply)
+ billing_mode = "PAY_PER_REQUEST"
+ hash_key = "ID"
+ id = (known after apply)
+ name = "DEV_ABC_TABLE"
+ range_key = "TYPE"
+ read_capacity = 0
+ stream_arn = (known after apply)
+ stream_enabled = true
+ stream_label = (known after apply)
+ stream_view_type = "NEW_AND_OLD_IMAGES"
+ tags = {
+ "Application" = "Example"
+ "Environment" = "Non-production"
+ "Owner" = "devops@example.org"
+ "Role" = "DataSource"
+ "Stack" = "Example"
}
+ write_capacity = 0
+ attribute {
+ name = "ID"
+ type = "S"
}
+ attribute {
+ name = "TYPE"
+ type = "S"
}
+ global_secondary_index {
+ hash_key = "TYPE"
+ name = "TYPE-ID-index"
+ non_key_attributes = []
+ projection_type = "ALL"
+ range_key = "ID"
+ read_capacity = 0
+ write_capacity = 0
}
+ point_in_time_recovery {
+ enabled = false
}
+ server_side_encryption {
+ enabled = (known after apply)
+ kms_key_arn = (known after apply)
}
}
Plan: 3 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
module.dynamodb.aws_dynamodb_table.table_west: Creating...
module.dynamodb.aws_dynamodb_table.table_east: Creating...
module.dynamodb.aws_dynamodb_table.table_west: Still creating... [10s elapsed]
module.dynamodb.aws_dynamodb_table.table_east: Still creating... [10s elapsed]
module.dynamodb.aws_dynamodb_table.table_west: Creation complete after 17s [id=DEV_ABC_TABLE]
module.dynamodb.aws_dynamodb_table.table_east: Creation complete after 19s [id=DEV_ABC_TABLE]
module.dynamodb.aws_dynamodb_global_table.global_table: Creating...
module.dynamodb.aws_dynamodb_global_table.global_table: Still creating... [10s elapsed]
module.dynamodb.aws_dynamodb_global_table.global_table: Creation complete after 13s [id=DEV_ABC_TABLE]
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
- terraform destroy
module.dynamodb.aws_dynamodb_table.table_west: Refreshing state... [id=DEV_ABC_TABLE]
module.dynamodb.aws_dynamodb_table.table_east: Refreshing state... [id=DEV_ABC_TABLE]
module.dynamodb.aws_dynamodb_global_table.global_table: Refreshing state... [id=DEV_ABC_TABLE]
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# module.dynamodb.aws_dynamodb_global_table.global_table will be destroyed
- resource "aws_dynamodb_global_table" "global_table" {
- arn = "arn:aws:dynamodb::***************:global-table/DEV_ABC_TABLE" -> null
- id = "DEV_ABC_TABLE" -> null
- name = "DEV_ABC_TABLE" -> null
- replica {
- region_name = "us-east-1" -> null
}
- replica {
- region_name = "us-west-2" -> null
}
}
# module.dynamodb.aws_dynamodb_table.table_east will be destroyed
- resource "aws_dynamodb_table" "table_east" {
- arn = "arn:aws:dynamodb:us-east-1:***************:table/DEV_ABC_TABLE" -> null
- billing_mode = "PAY_PER_REQUEST" -> null
- hash_key = "ID" -> null
- id = "DEV_ABC_TABLE" -> null
- name = "DEV_ABC_TABLE" -> null
- range_key = "TYPE" -> null
- read_capacity = 0 -> null
- stream_arn = "arn:aws:dynamodb:us-east-1:***************:table/DEV_ABC_TABLE/stream/2020-03-12T05:36:47.046" -> null
- stream_enabled = true -> null
- stream_label = "2020-03-12T05:36:47.046" -> null
- stream_view_type = "NEW_AND_OLD_IMAGES" -> null
- tags = {
- "Application" = "Example"
- "Environment" = "Non-production"
- "Owner" = "devops@example.org"
- "Role" = "DataSource"
- "Stack" = "Example"
} -> null
- write_capacity = 0 -> null
- attribute {
- name = "ID" -> null
- type = "S" -> null
}
- attribute {
- name = "TYPE" -> null
- type = "S" -> null
}
- global_secondary_index {
- hash_key = "TYPE" -> null
- name = "TYPE-ID-index" -> null
- non_key_attributes = [] -> null
- projection_type = "ALL" -> null
- range_key = "ID" -> null
- read_capacity = 0 -> null
- write_capacity = 0 -> null
}
- point_in_time_recovery {
- enabled = false -> null
}
- ttl {
- enabled = false -> null
}
}
# module.dynamodb.aws_dynamodb_table.table_west will be destroyed
- resource "aws_dynamodb_table" "table_west" {
- arn = "arn:aws:dynamodb:us-west-2:***************:table/DEV_ABC_TABLE" -> null
- billing_mode = "PAY_PER_REQUEST" -> null
- hash_key = "ID" -> null
- id = "DEV_ABC_TABLE" -> null
- name = "DEV_ABC_TABLE" -> null
- range_key = "TYPE" -> null
- read_capacity = 0 -> null
- stream_arn = "arn:aws:dynamodb:us-west-2:***************:table/DEV_ABC_TABLE/stream/2020-03-12T05:36:46.848" -> null
- stream_enabled = true -> null
- stream_label = "2020-03-12T05:36:46.848" -> null
- stream_view_type = "NEW_AND_OLD_IMAGES" -> null
- tags = {
- "Application" = "Example"
- "Environment" = "Non-production"
- "Owner" = "devops@example.org"
- "Role" = "DataSource"
- "Stack" = "Example"
} -> null
- write_capacity = 0 -> null
- attribute {
- name = "ID" -> null
- type = "S" -> null
}
- attribute {
- name = "TYPE" -> null
- type = "S" -> null
}
- global_secondary_index {
- hash_key = "TYPE" -> null
- name = "TYPE-ID-index" -> null
- non_key_attributes = [] -> null
- projection_type = "ALL" -> null
- range_key = "ID" -> null
- read_capacity = 0 -> null
- write_capacity = 0 -> null
}
- point_in_time_recovery {
- enabled = false -> null
}
- ttl {
- enabled = false -> null
}
}
Plan: 0 to add, 0 to change, 3 to destroy.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
module.dynamodb.aws_dynamodb_global_table.global_table: Destroying... [id=DEV_ABC_TABLE]
module.dynamodb.aws_dynamodb_global_table.global_table: Still destroying... [id=DEV_ABC_TABLE, 10s elapsed]
module.dynamodb.aws_dynamodb_global_table.global_table: Destruction complete after 12s
module.dynamodb.aws_dynamodb_table.table_east: Destroying... [id=DEV_ABC_TABLE]
module.dynamodb.aws_dynamodb_table.table_west: Destroying... [id=DEV_ABC_TABLE]
module.dynamodb.aws_dynamodb_table.table_west: Still destroying... [id=DEV_ABC_TABLE, 10s elapsed]
module.dynamodb.aws_dynamodb_table.table_east: Still destroying... [id=DEV_ABC_TABLE, 10s elapsed]
module.dynamodb.aws_dynamodb_table.table_east: Still destroying... [id=DEV_ABC_TABLE, 20s elapsed]
module.dynamodb.aws_dynamodb_table.table_west: Still destroying... [id=DEV_ABC_TABLE, 20s elapsed]
module.dynamodb.aws_dynamodb_table.table_west: Destruction complete after 26s
module.dynamodb.aws_dynamodb_table.table_east: Destruction complete after 28s
Destroy complete! Resources: 3 destroyed.