Terraform Modules + AWS Code Commit.
I did a project on the Terraform module the other day but just before that I did one on CodeCommit. Things get better when we can use Terraform along with Codecommit, which I will be experimenting with in this project. I would be creating an efficient and cost-effective solution for deploying and managing a SaaS application (our fictitious Humangov Application) in the AWS environment.
This project would demonstrate how we can easily and consistently provide a reusable SaaS multi-tenant infrastructure in the AWS environment, using Terraform modules and securely storing our Terraform configuration files on AWS CodeCommit. The services that would be provisioned for the multi-tenant application include EC2 instances, DynamoDB, and S3 buckets.
I was so glad I could lay my hands on this project. I tell you, it was really fun for me. I hope you find it fun as well.
My Approach:
I created a Git repository on AWS CodeCommit and got it connected to AWS Cloud9.
I named the repository: human-gov-infrastructure
I then configured the AWS CLI credential helper on your AWS Cloud9 EC2 development environment
```
# Config for DevOps Engineer
git config — global user.name “Ben Akin— DevOps Engineer”
git config — global user.email bennyakin@humangov.com
git config — global credential.helper ‘!aws codecommit credential-helper $@’
git config — global credential.UseHttpPath true
```
In the terminal on Cloud9, I ran the git clone command, specifying the HTTPS clone URL of the repository I wanted to clone. I cloned the repository named human-gov-infrastructure:
git clone <https://git-codecommit.us-east-1.amazonaws.com/v1/repos/human-gov-infrastructure>
git clone <https://git-codecommit.us-east-1.amazonaws.com/v1/repos/human-gov-application>
I went inside the human-gov-infrastructure folder:
cd human-gov-infrastructure and created a root directory folder to store Terraform files:
mkdir terraform
I created a new directory called modules/aws_humangov_infrastructure to hold the module files:
cd terraform
mkdir -p modules/aws_humangov_infrastructure
Inside the modules/aws_humangov_infrastructure directory, I created the following empty files: variable.tf, main.tf, and output.tf:
cd modules/aws_humangov_infrastructure
touch variables.tf main.tf outputs.tf
I worked on these files, starting with the variable file
variables.tf
variable “state_name” {
description = “The name of the US State”
}
Next, I worked on the main.tf file
main.tf
I saved the configuration in the main.tf file and then edited the output file:
The outputs.tf would give us 3 major outputs, the public DNS of the EC2 instance which gives us the public hostname of the EC2 instance allowing us to test the application once it is up and running, the dynamo DB table name so we can specify the application configuration and the S3 bucket name so we can know the name of the S3 bucket that was created by terraform with the dynamic character
output “state_ec2_public_dns” {
value = aws_instance.state_ec2.public_dns
}
output “state_dynamodb_table” {
value = aws_dynamodb_table.state_dynamodb.name
}
output “state_s3_bucket” {
value = aws_s3_bucket.state_s3.bucket
}
I went into the root project directory and created a main.tf file that would consume the modules/aws_humangov_infrastructure module:
Get Ben Olufemi akintounde’s stories in your inbox
Join Medium for free to get updates from this writer.
So under the Terraform directory, I created a new main.tf file(different from the one we created in the aws_humangov_infrastructure folder)
provider “aws” {
region = “us-east-1”
}
module “aws_humangov_infrastructure” {
source = “./modules/aws_humangov_infrastructure”
for_each = toset(var.states)
state_name = each.value
}
In your root project under the Terraform directory, I created a new file called variable.tf: this helps us to specify the list of states for which the configuration would be applied.
I started with just 3 states, California, Florida, and Texas. Any time we want to add a new state to the variable file, we can edit the file, using commas to separate the states. This way we can create a new infrastructure for the new state using the specified configuration.
variable “states” {
description = “A list of state names”
default = [“california”, “florida”,”texas”]
}
In the root project directory, I created the file outputs.tf:
output “state_infrastructure_outputs” {
value = {
for state, infrastructure in module.aws_humangov_infrastructure :
state => {
ec2_public_dns = infrastructure.state_ec2_public_dns
dynamodb_table = infrastructure.state_dynamodb_table
s3_bucket = infrastructure.state_s3_bucket
}
}
}
I went back to the root directory
I created the SSH key humangov-ec2-key and upload the private key humangov-ec2-key.pem to Cloud9.
Next, I initialized and applied the Terraform configuration:
terraform fmt
terraform init
terraform validate
terraform plan
It shows that Terraform would create a Dynamo DB table for the State of California, create an EC2 instance for the State of California, a security group, and create an S3 bucket for California as well as create a random string for the bucket.
Each one of the states would have these 5 resources.
terraform apply
I got the error below because I forgot to create an SSH key
I went to the EC2 instance service on AWS Console and created an SSH key that matches the specified key being used by Terraform.
Then apply the Terraform configuration again:
Terraform successfully created the resources.
Checking on the Resources created
I am happy these resources were successfully created. Since we now have the necessary setup to provision these infrastructures for each of the states and we can do it in an automated way anytime, I decided to destroy the resources to avoid unnecessary charges so I ran terraform destroy.









