Sitemap

Terraform Modules + AWS Code Commit.

5 min readJan 3, 2024

--

Photo credits: boredpanda.com

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.

Press enter or click to view image in full size

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>

Press enter or click to view image in full size

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

This is the directory structure

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

Press enter or click to view image in full size
Main.tf file content
Press enter or click to view image in full size
The remaining content of the main.tf file

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”]
}

Press enter or click to view image in full size
variable.tf file

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
}
}
}

Press enter or click to view image in full size
Final Output

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

Press enter or click to view image in full size
terraform init

terraform validate

Press enter or click to view image in full size
Terraform validate

terraform plan

Press enter or click to view image in full size
terraform plan
terraform plan
terraform plan
Press enter or click to view image in full size

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​

Press enter or click to view image in full size

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

Press enter or click to view image in full size
The EC2 Instances for each of the states were created
Press enter or click to view image in full size
The S3 buckets for each of the states were created
Press enter or click to view image in full size
The Dynamo DB tables for each of the States were 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.

Press enter or click to view image in full size
Destroying the resources created with Terraform destroy.

--

--