USING TERRAFORM TO CREATE A WEB SERVER ON AWS

ADITYA RAJ
7 min readJun 12, 2020

This tasks comprises creation of the following codes in the terraform tool:

  1. Create the key and security group which allow the port 80.
  2. Launch EC2 instance.
  3. In this Ec2 instance use the key and security group which we have created in step 1.
  4. Launch one Volume (EBS) and 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

First I began with creating an AMI with various services installed which will be used later on to create instances as per the needs. It contain Jenkins, Httpd, Java, Git. Its better to setup jenkins and set jenkins as a sudoer so that it has the power to work on all the jobs without need for passwords.

Just type ‘vi /etc/sudoers

Inside at bottom, add a line “Jenkins ALL = (ALL) NOPASSWD = (ALL)

To do the task i have started this project by creating a 4096 bits of SSH-2 RSA key using the putty generator.

The key generated have private key as well as public key. Copy the authorized key access and paste it in the public key argument(in the terraform file).

Let’s begin with the code!!!

TERRAFORM FILE

I have created a single terraform file for the whole infrastructure. The file will have ‘.tf’ as extension.

After describing the provider which we are going to use mentioning region and profile, I have created the security group which allow the ports 80 , 8080 and 22 to perform the specific work.

Port 80 — http, Port 8080 — Jenkins, Port 22 — SSH

Inbound/Ingress rules for http, jenkins, ssh

For connecting to the instance we all need a private key and everyone have different key name so I created a variable which first asks for the key name and then it will store it as a variable name and that variable can be used multiple times with different values.

And also I have created one EBS volume to attach it on the instance. The main reason for it is to create a persistent storage where developer keeps all the codes. So that even when to EC2 instance fails/terminates, file still remains without being affected and simply we can attach it to the new instance.

I have given name /dev/sdf to the attached hard disk and also for attaching the volumes we need the instance id and the volume id , here I have done the same work as what I did to store the key name as a variable.

After completing this part I have created one S3 bucket and given an public-read access to it. Permissions can be configured according to use cases.

And then Istored the output of this bucket into different variables for further use. Like it zone id , region id etc. so that I can configure the Cloudfront arguments using these variables.

Note — I used all the key terms in my code with the help of official docs from the terraform without remembering even a single line of code. As per the need in my setup I designed it.

Finally the complete terraform code is completed. From now onwards with one single command i’ll be able to do multiple things like creating a volume attaching it creating diff buckets giving different permissions. Even destroying whole setup in single command. This looks big but see one can’t remember what infrastructure one setup. Suppose when we have to perform some tweaks add few other services like cloudwatch, GlobalAccelerator, etc. or upgrading the current resources, there is no 100% guarantee that one cannot make mistakes in large setup. Writing a terraform code saves our time, money as well as it can guarantee that what we did was correct because we have proofs as the file itself.

After running the “terraform apply” command give the key name and it will start creating all the necessary infrastructure for running the webserver.

All the outputs related to the EC2 instances, S3 bucket , CDN, security groups are given in these pictures.

OUTPUT OF INFRASTRUCTURE

These outputs can be verified from the webUI interface also.

WebUI showing creation of various setups

After creating the infrastructure successfully, now we need to login to our instance. Here again I have used Putty to login via ssh. I used the private key which I initially generated with putty generator.

After login to the ssh we first switch to the root user and mount the hard disk to the /var/www/html directory. But for this we need to first create the partitions in it ,then format it and then mount to that folder.

fdisk -l

fdisk /dev/xvda

mkfs.ext4 /dev/xvdf1

mount /dev/xvdf1 /var/www/html

Here, we use format using mkfs.ext4 to create file system on our Linux instance. and with fdisk -l we can get the volumes attached to the instance. While fdisk /dev/xvda is used to create new partition for use. Just google it if you find it tough to understand as this is linux commands not at all Cloud commands.

Partition and Mount

After mounting the hard disc to the directory I have enabled the jenkins and httpd services if it was not active. HTTPD is used for running the apache webserver and the best use of jenkins i ll tell you in the end. For now after enabling the services i have created the one job in jenkins which will copy the code from the github repository to the /var/www/html folder.(Here comes the use of sudo power to jenkins if you did it as I said you won’t get error like permission denied, no place to enter password for jenkins, etc.

Jenkins Job Scenario and Output

Now in this code to access the image I have created the S3 bucket and used CloudFront service. Here we can upload the static data like video, images, etc to the S3 bucket and that can be accessed by the CloudFront front i.e we need to use the ‘url’ which is given by the CloudFront to access that data.

The url can be found in the CDN created. If you find it tough search for the docs, or blogs on CDN and S3 setup.

And to access the website we need to use the public ip/dns which is given by the instance.

It took me approximately 1 day to write the complete code(as I have just begun my journey with terraform, the time gets less and less with practice) and for creating the infrastructure it took less than 5 mins. This is the power of terraform. Also this complete structure can be disposed by writing one command.

Now the best case we can solve using this infrastructure is that we do not have to give any key to login to the system. We do not have to provide the port 22 to login in the webserver. As it will enhance the security. Instead we can give the port no. 80 and 8080 just to use these services. And for updating the code we can use jenkins as we can update the code by uploading it to the repsitory and then it can be directly updated to our webpage.

Feel free to contact me in case of any doubt and suggest me to improve this project if needed.

For reference use the github link below.

https://github.com/rajadityaranjan/HC1

LinkedIn Profile — https://www.linkedin.com/in/aditya-raj-762977178

Thank You!!!

--

--