6. Cloud Resume Challenge: Creating DynamoDB Table

I am a Sr. Windows Administrator looking to sharpen my skills within the cloud space. This blog serves not only as a guide for others to use but also to document my cloud journey.
Search for a command to run...

I am a Sr. Windows Administrator looking to sharpen my skills within the cloud space. This blog serves not only as a guide for others to use but also to document my cloud journey.
No comments yet. Be the first to comment.
In this series, I will outline the steps to integrate a fully functional serverless website hosted on CloudFront using Amazon S3. The implementation deployment will be through Terraform.
In this module, you will create a Simple Notification Service (SNS) Topic and an SNS email subscription for your site contact form. This will enable visitors to send emails to you via your website. Terraform SNS Topic Reference Terraform SNS Subscr...
Deploying my portfolio site with Terraform was an enriching experience. It allowed me to craft the architecture precisely as I envisioned it. Each resource deployment deepened my understanding of the services I employed, many of which were new to me....

In this final module, you will create an ACM certificate and Route53 entries for CloudFront and API Gateway using your custom domain name. This will present a more profession website that can be shared with others. Terraform ACM Reference Terraform...

In this module, you will be updating your HTML and JavaScript files to integrate your API Gateway resources. You will also make modifications to your terraform-apply_cloudfront-invalidation.yml to invalidate your CloudFront Distribution. The invalida...

In this module, you will be creating your API Gateway and a couple of resources that will interact with your Lambda Functions from the previous module. You will create API resources that will utilize POST HTTP Methods. Once your API Gateway is deploy...

In this module, I will walk you through each of the Lambda functions and how they work, upload those functions to AWS, and test their functionality with their respective resources. Terraform Lambda Reference Boto3 DynamoDB Reference Boto3 SNS Refer...

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
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
dynamodb folder in ./infra/modules/aws.
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
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, andtypeentries.
Save the file
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
nameandhash_keyvalues.
Save the file
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.

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 applyis 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
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.
dynamodb_table folder in ./infra/modules/dynamodb_table.
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
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
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
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
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
}

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
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.
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
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.
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
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
valuebeing 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.