Creating a Complete Infrastructure To Launch Web-Server using AWS with Terraform.

Anish Garg
8 min readJul 16, 2020

Some basic terminologies of this project:

  • AWS:- Amazon Web Services (AWS) is the world’s most comprehensive and broadly adopted cloud platform, offering over 175 fully featured services from data centers globally. Millions of customers — including the fastest-growing startups, largest enterprises, and leading government agencies — are using AWS to lower costs, become more agile, and innovate faster.

What services AWS provides?🤔

1.) ELASTIC COMPUTE CLOUD(EC2): Amazon Elastic Compute Cloud is a part of Amazon.com’s cloud-computing platform, Amazon Web Services, that allows users to rent virtual computers on which to run their own computer applications.It provides compute as a service to the users(CAAS).

2.) Elastic File System(EFS): Amazon Elastic File System is a cloud storage service provided by Amazon Web Services designed to provide scalable, elastic, concurrent with some restrictions, and encrypted file storage for use with both AWS cloud services and on-premises resources.

3.) Amazon Simple Storage Service (Amazon S3): S3 bucket is an object storage service that offers industry-leading scalability, data availability, security, and performance. This means customers of all sizes and industries can use it to store and protect any amount of data for a range of use cases, such as websites, mobile applications, backup and restore, archive, enterprise applications, IoT devices, and big data analytics. Amazon S3 provides easy-to-use management features so you can organize your data and configure finely-tuned access controls to meet your specific business, organizational, and compliance requirements. Amazon S3 is designed for 99.999999999% (11 9’s) of durability, and stores data for millions of applications for companies all around the world.

4.)Amazon CloudFront:- CloudFront is a aws web service that speeds up distribution of your static and dynamic web content, such as .html, .css, .js, and image files, to your users. CloudFront delivers your content through a worldwide network of data centers called edge locations. When a user requests content that you’re serving with CloudFront, the user is routed to the edge location that provides the lowest latency (time delay), so that content is delivered with the best possible performance and thus improving access speed for downloading the content.

5.)Security Groups(SGs):- A security group acts as a virtual firewall for your EC2 instances to control incoming and outgoing traffic. Inbound rules control the incoming traffic to your instance, and outbound rules control the outgoing traffic from your instance.

  • Terraform:- Terraform is an open-source infrastructure as a code software tool created by HashiCorp. It enables users to define and provision a datacenter infrastructure using a high-level configuration language known as Hashicorp Configuration Language (HCL).The infrastructure Terraform can manage includes low-level components such as compute instances, storage, and networking, as well as high-level components such as DNS entries, SaaS features, etc.

Task Synopsis : To create/launch Application in AWS using Terraform

1. Create Security group which allow the port 80.

2. Launch EC2 instance.

3. In this Ec2 instance use the existing key or provided key and security group which we have created in step 1.

4. Launch one Volume using the EFS service and attach it in your vpc, then mount that volume into /var/www/html

5. Developer have uploded the code into github repo also the repo has some images.

6. Copy the github repo code into /var/www/html

7. Create S3 bucket, and copy/deploy the images from github repo into the s3 bucket and change the permission to public readable.

8. Create a Cloudfront using s3 bucket(which contains images) and use the Cloudfront URL to update in code in /var/www/html

Prerequisites

1. For AWS

  • To Create an AWS account and log in from here.
  • Create an IAM account and generate profile.
  • Download the AWS CLI tool.

2. For Terraform

  • Download and extract Terraform software from here
  • After extracting, add terraform to path
  • Create a directory to manage terraform code.

Step by Step solution to create the infrastructure

STEP 1: AWS login through command line
On creating an account, AWS provides a credentials.csv file. Download the file and save it. Now enter the following command from the terminal to login to the account and use the credentials generated from the csv file

aws configure --profile=<profile name>

STEP 2: Give credentials of the profile:

Now we are going to write all our source code in one notepad file.

STEP 3: WRITE THE NAME OF YOUR PROVIDER (AWS ) FROM WHOM YOUR TERRAFORM WILL CONTACT

provider "aws" {
region = "ap-south-1"
profile = "anish"
}

STEP 4: Creating Security group with allowing Port 80 For http and Port 22 For ssh

resource "aws_security_group" "sg" {
name = "security group"
description = "Give Security permissions"

ingress {
description = "For SSH"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

ingress {
description = "For HTTP"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "security group"
}
}

STEP 5: Create public and private key pair

resource "tls_private_key" "private_key" {
algorithm = "RSA"
rsa_bits = 4096
}

resource "aws_key_pair" "pub_key" {
key_name = "key"
public_key = tls_private_key.private_key.public_key_openssh
}
output "key_ssh"{
value = tls_private_key.private_key.public_key_openssh
}
output "pubkey"{
value = tls_private_key.private_key.public_key_pem
}
resource "local_file" "private_key" {
depends_on = [tls_private_key.private_key]
content = tls_private_key.private_key.private_key_pem
filename = "key.pem"
file_permission = 0400
}

STEP 6: Launch EC2 instances

resource "aws_instance"  "instance" {
ami = "ami-0732b62d310b80e97"
instance_type = "t2.micro"
key_name = aws_key_pair.pub_key.key_name
security_groups = ["sg"]
availability_zone = "ap-south-1b"
tags = {
Name = "My_instance"
}
}

STEP 7: Launch one Volume using the EFS service and attach it in your vpc, then mount that volume into /var/www/html

resource "aws_efs_file_system" "EFS-task"{
creation_token="efs"
tags = {
Name= "EFS-task"
}
}
resource "aws_efs_mount_target" "mount" {
file_system_id = aws_efs_file_system.EFS-task.id
subnet_id = "subnet-d0006b9c"
security_groups= [aws_security_group.security_group.id]
}
resource "null_resource" "mounting" {
depends_on = [ aws_efs_mount_target.mount, ]
connection {
type = "ssh"
user = "ec2-user"
private_key = tls_private_key.private_key.private_key_pem
host = aws_instance.Task-2.public_ip
}
provisioner "remote-exec" {
inline = [
"sudo yum install httpd php git -y",
"sudo systemctl restart httpd",
"sudo systemctl enable httpd",
"sudo mkfs.ext4 /dev/xvdh",
" sudo mount /dev/xvdh /var/www/html",
" sudo rm -rf /var/www/html/*",
"sudo git clone
https://github.com/anish5207/hybrid-task1.git /var/www/html",
"sudo yum install nfs-utils -y"
]
}
}

STEP 8: Create S3 bucket, and copy deploy the images from github repo into the s3 bucket and change the permission to public readable.

resource "aws_s3_bucket" "task2-anish-bucket" {
bucket = "task2-anish-bucket"
acl = "public-read"

versioning {
enabled = true
}
tags = {
Name = "task2-anish-bucket"
}
}
resource "aws_s3_bucket_object" "task2_object" {
bucket = aws_s3_bucket.task2-anish-bucket.id
key = "image.jpg"
source = "C:/Users/Anish garg/Desktop/practical.jpg"
acl = "public-read"

force_destroy = true
}

locals{
s3_origin_id = "S3-${aws_s3_bucket.task2-anish-bucket.bucket}"
}

STEP 9. Create a Cloudfront using s3 bucket(which contains images) and use the Cloudfront URL to update in code in /var/www/html

resource "aws_cloudfront_distribution" "task2_cf" {
depends_on=[aws_s3_bucket.task2-anish-bucket]
origin {
domain_name = aws_s3_bucket.task2-anish-bucket.bucket_regional_domain_name
origin_id = aws_s3_bucket.task2-anish-bucket.id
custom_origin_config {
http_port = 80
https_port = 80
origin_protocol_policy = "match-viewer"
origin_ssl_protocols = ["TLSv1", "TLSv1.1", "TLSv1.2"]
}
}

enabled = true
is_ipv6_enabled = true
default_cache_behavior {
allowed_methods = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "${aws_s3_bucket.task2-anish-bucket.id}"
forwarded_values {
query_string = false

cookies {
forward = "none"
}
}
viewer_protocol_policy = "allow-all"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
}
# Restricts who is able to access this content

restrictions {
geo_restriction {
restriction_type = "none"
}
}
viewer_certificate {
cloudfront_default_certificate = true
}

connection {
type = "ssh"
user = "ec2-user"
private_key = tls_private_key.private_key.private_key_pem
host = aws_instance.Task-2.public_ip
}

provisioner "remote-exec" {

inline = [

"sudo su << EOF",
"echo \"<img src='
http://${self.domain_name}/${aws_s3_bucket_object.task2_object.key}'>\" >> /var/www/html/index.php",
"EOF",
]
}
}

STEP 10. Now finally my instance is ready and we can access it, As Below code will automatically start my webserver in chrome and print a IP address in a cmd.

output "my-ip"{
value = aws_instance.Task-2.public_ip
}
resource "null_resource" "running_the_website" {
depends_on = [null_resource.mounting]
provisioner "local-exec" {
command = "chrome ${aws_instance.Task-2.public_ip}"
}
}

Now Compiling time:

Use the following commands to initialize and run the code. Make sure to run the command from the same directory having the code file:

  • terraform init: It will download all the required plugin
  • terraform apply: To run the terraform code

Now, by using the public IP of instance we can connect to the webpage.

So, finally this webpage is created by terraform just by running a single command.So, now if we want to destroy complete setup, then by using this command terraform destroy It will destroy everything automatically.

So, our setup is destroyed completely. Our task is completed😎. THANKS FOR READING.😍

Here is link of my previous task: https://www.linkedin.com/pulse/creating-complete-infrastructure-aws-using-terraform-anish-garg/?trackingId=d8REoBVL1NoiftrSd8Q4zQ%3D%3D

Click here for github link.

Any Suggestions and queries are most welcome .Feel free to comment below for any query or suggestions !!!

--

--

Anish Garg

Computer related tech, Cyber Security, Cloud Computing