Containing the Chaos Part 2 of 3: Amazon DynamoDB | Amazon S3, Amazon Elastic Container Services (ECS) | AWS Fargate

This article is part of a three-part series:

Containing the Chaos Part 1 of 3: Docker | Amazon Elastic Container Registry (ECR)
In part 1, the application will be placed into a container image. The container image will then be stored in the Amazon Elastic Container Registtry (ECR).

Containing the Chaos Part 2 of 3: Amazon DynamoDB | Amazon Simple Storage Service (S3) | Amazon Elastic Container Services (ECS) | AWS Fargate | Terraform
In part 2, the DynamoDB table and Amazon S3 buckets will created using Terraform. Further the Amazon Elastic Container Services (EC2) cluster will be initiated on AWS Fargate.

Containing the Chaos Part 3 of 3: Amazon Elastic Container Service (EC2) | Amazon Elastic Load Balancing (ELB) | Terraform
In part 3 (the final part), the task definition will be created for the cluster. A service will be created to handle running the defined tasks. The application will then be tested. Finally, will decommission the resources.

For background on this series, go here:

Containing the Chaos! | A Three-Part Series Demonstrating the Usefulness of Containerization to HumanGov

1 of 5. Open AWS Cloud9

2 of 5. Disable temp credentials and create access key for Cloud9

Disable temporary credentials

Settings -/- AWS Settings -/-Credentials -/- Disable: "AWS managed temporary credentials"

Create new access key

IAM -/- users -/- cloud9-user -/- Security credentials -/- select existing access key -/- Actions:Delete [Create access key] Use case: Command Line interface (CLI) I understand ... [Next] [Create access key]

Cloud9: Create a new file: export.sh

Note: This file will be deleted before this article is published. Regardless, not neccessarily a recommended security practice to put credentials in plain text in files.

vi export.sh export AWS_ACCESS_KEY_ID="AKIAXKHBMWXLOFCZWPKK" export AWS_SECRET_ACCESS_KEY="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"

set environment variables

source export.sh

3 of 5. Edit the terrafoom files

Comment out any of the ec2 stuff in terraform/modules/aws_humangov_infrastructure/main.tf , terraform/modules/aws_humangov_infrastructure/output.tf and terraform/outputs.tf.

In addition, make sure that only one state is in the terraform/variables.tf

cd /home/ec2-user/environment/human-gov-infrastructure/terraform terraform show

terraform/modules/aws_humangov_infrastructure/main.tf

/* resource "aws_security_group" "state_ec2_sg" { name = "humangov-${var.state_name}-ec2-sg" description = "Allow traffic on ports 22 and 80" ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 5000 to_port = 5000 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 0 to_port = 0 protocol = "-1" security_groups = ["sg-027f57abd3fefda49"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "humangov-${var.state_name}" } } resource "aws_instance" "state_ec2" { ami = "ami-007855ac798b5175e" instance_type = "t2.micro" key_name = "humangov-ec2-key" vpc_security_group_ids = [aws_security_group.state_ec2_sg.id] iam_instance_profile = aws_iam_instance_profile.s3_dynamodb_full_access_instance_profile.name provisioner "local-exec" { command = "sleep 30; ssh-keyscan ${self.private_ip} >> ~/.ssh/known_hosts" } provisioner "local-exec" { command = "echo ${var.state_name} id=${self.id} ansible_host=${self.private_ip} ansible_user=ubuntu us_state=${var.state_name} aws_region=${var.region} aws_s3_bucket=${aws_s3_bucket.state_s3.bucket} aws_dynamodb_table=${aws_dynamodb_table.state_dynamodb.name} >> /etc/ansible/hosts" } provisioner "local-exec" { command = "sed -i '/${self.id}/d' /etc/ansible/hosts" when = destroy } tags = { Name = "humangov-${var.state_name}" } } */ resource "aws_dynamodb_table" "state_dynamodb" { name = "humangov-${var.state_name}-dynamodb" billing_mode = "PAY_PER_REQUEST" hash_key = "id" attribute { name = "id" type = "S" } tags = { Name = "humangov-${var.state_name}" } } resource "random_string" "bucket_suffix" { length = 4 special = false upper = false } resource "aws_s3_bucket" "state_s3" { bucket = "humangov-${var.state_name}-s3-${random_string.bucket_suffix.result}" tags = { Name = "humangov-${var.state_name}" } } /* resource "aws_iam_role" "s3_dynamodb_full_access_role" { name = "humangov-${var.state_name}-s3_dynamodb_full_access_role" assume_role_policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Principal": { "Service": "ec2.amazonaws.com" }, "Effect": "Allow", "Sid": "" } ] } EOF tags = { Name = "humangov-${var.state_name}" } } resource "aws_iam_role_policy_attachment" "s3_full_access_role_policy_attachment" { role = aws_iam_role.s3_dynamodb_full_access_role.name policy_arn = "arn:aws:iam::aws:policy/AmazonS3FullAccess" } resource "aws_iam_role_policy_attachment" "dynamodb_full_access_role_policy_attachment" { role = aws_iam_role.s3_dynamodb_full_access_role.name policy_arn = "arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess" } resource "aws_iam_instance_profile" "s3_dynamodb_full_access_instance_profile" { name = "humangov-${var.state_name}-s3_dynamodb_full_access_instance_profile" role = aws_iam_role.s3_dynamodb_full_access_role.name tags = { Name = "humangov-${var.state_name}" } } */

terraform/modules/aws_humangov_infrastructure/output.tf

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

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

terraform/variables.tf

variable "states" { description = "A list of state names" default = ["california"] }

4 of 5. Create the DB and S3 using Terraform

Note the resource names of the table and S3 bucket. Will need it for the next article.

terraform plan terraform apply

5 of 5. Create the cluster on Fargate

Amazon Elastic Container Service -/- Create cluster Cluster name: humangov-cluster Infrastructure: AWS Fargate (serverless) [Create]

References

Amazon ECS on AWS Fargate

Amazon Elastic Container Registry Documentation

Amazon Elastic Container Service Documentation

Amazon Elastic Compute Cloud Documentation

Amazon DynamoDB Documentation

Amazon Simple Storage Service Documentation

AWS Cloud9 Documentation

Elastic Load Balancing Documentation

AWS Identity and Access Management Documentation

Docker Docs

Documentation | Terraform | HashiCorp Developer

Python 3.12.1 documentation

nginx documentation


Lewis Lampkin, III - Blog

Lewis Lampkin, III - LinkedIn

Lewis Lampkin, III - Medium

Comments

Popular posts from this blog

Orphaned No More: Adopting AWS Lambda

Containing the Chaos! | A Three-Part Series Demonstrating the Usefulness of Containerization to HumanGov

Ansible is the Answer! | A Three-Part Series Demonstrating the Usefulness of Ansible to HumanGov