6. Cloud Resume Challenge: Creating DynamoDB Table

6. Cloud Resume Challenge: Creating DynamoDB Table

In this module, you will create a DynamoDB table and table item for your visitor count. This will store your visitor counts whenever someone loads your site.

Note: This data will be added later to be viewable on your site.


Terraform DynamoDB Table Reference

Terraform DynamoDB Table Item Reference


Create a new branch in GitHub

  • Login to GitHub

  • Select the Issues tab > Select New Issue

  • Add the a title, e.g. Create DynamoDB table with table item

  • Select Submit new issue

  • On the right pane, under Development, Select Create a branch

  • Leave the defaults > Select Create branch

  • Open your IDE Terminal.

  • Input the following:

git fetch origin
git checkout YOUR_BRANCH_NAME

Modifying dynamodb

  • In this section, you will create the DynamoDB table. Locate the dynamodb folder in ./infra/modules/aws.

main.tf

  • To create the DynamoDB table, input the following:

      resource "aws_dynamodb_table" "table" {
        name           = var.name
        billing_mode   = var.billing_mode
        read_capacity  = var.read_capacity
        write_capacity = var.write_capacity
        hash_key       = var.hash_key
    
        attribute {
          name = var.hash_key
          type = var.type
        }
    
        ttl {
          attribute_name = var.attribute
          enabled        = var.enabled
        }
    
        tags = {
          Name        = "${var.name}"
          Environment = "${var.environment}"
        }
    
        lifecycle {
          ignore_changes = [ ttl ]
        }
      }
    

    This will create the DynamoDB table. Majority of the variables will be defined with default values.

  • Save the file

variables.tf

  • Input the following to create variables for each of the arguments:

      variable "attribute" {
        description = "(Required) Set of nested attribute definitions. Only required for hash_key and range_key attributes."
        type = string
        default = "TimeToExist"
      }
    
      variable "enabled" {
        description = "(Required) Whether TTL is enabled."
        type = bool
        default = false
      }
    
      variable "environment" {
        description = "Tag value for what environment this applies to."
        type = string
        default = "Development"
      }
    
      variable "hash_key" {
        description = "(Required, Forces new resource) Attribute to use as the hash (partition) key. Must also be defined as an attribute"
        type = string
      }
    
      variable "name" {
        description = "(Required) Unique within a region name of the table."
        type = string
      }
    
      variable "billing_mode" {
        description = "(Optional) Controls how you are charged for read and write throughput and how you manage capacity. The valid values are PROVISIONED and PAY_PER_REQUEST. Defaults to PROVISIONED."
        type = string
        default = "PROVISIONED"
      }
    
      variable "read_capacity" {
        description = "(Optional) Number of read units for this table. If the billing_mode is PROVISIONED, this field is required."
        type = number
        default = 5
      }
    
      variable "type" {
        description = "(Required) Attribute type. Valid values are S (string), N (number), B (binary)."
        type = string
      }
    
      variable "write_capacity" {
        description = "(Optional) Number of write units for this table. If the billing_mode is PROVISIONED, this field is required."
        type = number
        default = 5
      }
    

    The only variables without default values are the name, hash_key, and type entries.

  • Save the file

outputs.tf

  • Here are some default output variables that you can include.

    • Input the following:

        output "arn" {
          description = "ARN of the table"
          value = aws_dynamodb_table.table.arn
        }
      
        output "id" {
          description = "Name of the table"
          value = aws_dynamodb_table.table.id
        }
      
        output "hash_key" {
          description = "Hash key to use for lookups and identification of the item"
          value = aws_dynamodb_table.table.hash_key
        }
      
        output "name" {
          description = "Name of the table"
          value = aws_dynamodb_table.table.name
        }
      
        output "tags_all" {
          description = "Map of tags assigned to the resource, including those inherited from the provider default_tags configuration block."
          value = aws_dynamodb_table.table.tags_all
        }
      

      The only required outputs are the name and hash_key values.

  • Save the file


Modifying dynamodb_table_item

  • Within the ./infra/modules/aws/dynamodb, there is a subfolder named dynamodb_table_item. Here you will modify the Terraform files associated with that module.

main.tf

  • Input the following to create your table item

      resource "aws_dynamodb_table_item" "item" {
        table_name = var.table_name
        hash_key   = var.hash_key
    
        item = var.item
    
        lifecycle {
          ignore_changes = [ item ]
        }
      }
    

    This will create a table item for Table that will be created and will use the hash_key associated with that table.

    The lifecycle ignore_changes will not attempt to update the item variable back to it's defined value when terraform apply is executed. The table item will be the actual value of your visitor count, so you do not want this to be overwritten each time.

  • Save the file

variables.tf

  • Input the following to define the values for each entry:

      variable "table_name" {
        description = "(Required) Name of the table to contain the item"
        type = string
      }
    
      variable "hash_key" {
        description = "(Required) Hash key to use for lookups and identification of the item"
        type = string
      }
    
      variable "item" {
        description = "(Required) JSON representation of a map of attribute name/value pairs, one for each attribute. Only the primary key attributes are required; you can optionally provide other attribute name-value pairs for the item."
        type = string
      }
    

  • Save the file.

Note there is no requirement for any output variable definitions.


Modifying dynamodb_table

  • In this section, you will combine the DynamoDB Table and DynamoDB Table Item into a singular module. Locate the dynamodb_table folder in ./infra/modules/dynamodb_table.

main.tf

  • Include the following:

      module "dynamodb" {
        source = "../aws/dynamodb"
    
        name           = var.table_name
        hash_key       = var.hash_key
        type           = var.type
      }
    
      module "dynamodb_item" {
        source = "../aws/dynamodb/dynamodb_table_item"
    
        table_name = module.dynamodb.name
        hash_key   = module.dynamodb.hash_key
        item       = var.table_item
      }
    

    This module will create the DynamoDB table and table item associated with the table.

  • Save the file

variables.tf

  • Input the following to define variable inputs:

      variable "table_name" {
        description = "Name for DynamoDB table"
        type = string
      }
    
      variable "hash_key" {
        description = "Hash key for DynamoDB table"
        type = string
      }
    
      variable "type" {
        description = "Type value for hash key"
        type = string
      }
    
      variable "table_item" {
        description = "Item values for DynamoDB table"
        type = string
      }
    

  • Save the file

outputs.tf

  • Input the following for return values for this module:

      output "arn" {
        description = "ARN for DynamoDB table"
        value = module.dynamodb.arn
      }
    
      output "id" {
        description = "ID for DynamoDB table"
        value = module.dynamodb.id
      }
    
      output "table_name" {
        description = "Name of the table to contain the item"
        value = module.dynamodb.name
      }
    
      output "hash_key" {
        description = "Hash key to use for lookups and identification of the item"
        value = module.dynamodb.hash_key
      }
    
      output "tags_all" {
        description = "Tags associated with DynamoDB table"
        value = module.dynamodb.tags_all
      }
    

  • Save the file


Modifying my_portfolio

  • Modify your my_portfolio module to include the creation of the DynamoDB table and table item

main.tf

  • Include the following to call the dynamodb_table module:

      module "dynamodb" {
        source = "../dynamodb_table"
    
        table_name     = var.table_name
        hash_key       = var.hash_key
        type           = var.type
        table_item     = var.table_item
      }
    

  • Save the file

variables.tf

  • Include the following to define the variables for the dynamodb module:

      variable "table_name" {
        description = "Name for DynamoDB table"
        type = string
      }
    
      variable "hash_key" {
        description = "Hash key for DynamoDB table"
        type = string
      }
    
      variable "type" {
        description = "Type value for hash key"
        type = string
      }
    
      variable "table_item" {
        description = "Item values for DynamoDB table"
        type = string
      }
    

    • Save the file

outputs.tf

  • Input the following for return values for this module:

      output "table_arn" {
        description = "ARN for DynamoDB table"
        value = module.dynamodb.arn
      }
    
      output "table_id" {
        description = "ID for DynamoDB table"
        value = module.dynamodb.id
      }
    
      output "table_name" {
        description = "Name of the table to contain the item"
        value = module.dynamodb.table_name
      }
    
      output "hash_key" {
        description = "Hash key to use for lookups and identification of the item"
        value = module.dynamodb.hash_key
      }
    
      output "table_tags_all" {
        description = "Tags associated with DynamoDB table"
        value = module.dynamodb.tags_all
      }
    

  • Save the file


Modifying ./infra/main.tf

main.tf

  • Modify your ./infra/main.tf

    • Input the following:

          # DynamoDB
          table_name = "my_site_visitors"
          hash_key = "Id"
          type = "N"
          table_item = <<ITEM
        {
          "Id": {"N": "0"},
          "value": {"N": "0"}
        }
        ITEM
      

      The table_item is a heredoc that defines the structure of the DynamoDB Table.

variables.tf and outputs.tf

  • Since the variables have been hard-coded, you do not have to modify your variables.tf

  • There are no mandatory outputs, but you can include the following if you wish to receive those outputs:

      output "table_arn" {
        description = "ARN for DynamoDB table"
        value = module.my_static_website.table_arn
      }
    
      output "table_id" {
        description = "ID for DynamoDB table"
        value = module.my_static_website.table_id
      }
    
      output "table_name" {
        description = "Name of the table to contain the item"
        value = module.my_static_website.table_name
      }
    
      output "hash_key" {
        description = "Hash key to use for lookups and identification of the item"
        value = module.my_static_website.hash_key
      }
    
      output "table_tags_all" {
        description = "Tags associated with DynamoDB table"
        value = module.my_static_website.table_tags_all
      }
    

  • Save the file


Pushing to GitHub

  • Ensure your files are saved.

  • In your IDE Terminal, type the following:

git add .

Add all files that were changed.

git commit -m "Created DynamoDB table and table item for viewer count"

Commit the changes with a comment.

git push

Push to GitHub.


Create Pull Request

  • Login to GitHub.

  • You should see the push on your repository.

  • Select Compare and pull request.

  • Validate the changes that were made to be pushed to main

  • Select Create pull request.

Your Terraform Plan should run before you can merge to main.

If you are using the same site files from the original template, the plan to add 2 should match.

  • Select Merge pull request > Confirm merge.

  • Delete branch.

  • In your IDE Terminal, type the following:

git checkout main
git pull

Validation:

  • AWS Management Console:

  • In the Search bar, search for "dynamodb" > Select Tables

  • You should see your new table listed under the Tables section

  • Under Tables > Select Explore items > Select your table

  • You should see the values set as below:

    In the later modules, you will validate the Table item value being updated via your Lambda function.


You have successfully created your DynamoDB table. In the next module, you will create your SNS topic and subscription to send you emails from your website contact form.