Deploy a Web Server with Terraform

#Introduction

In this tutorial, How to deploy a Web Server with Terraform.

  • Create EC2 instance
  • User user_data and create a script to install Nginx webserver on amazon linux 2.
  • Security group ingress rule to allow access web server from my laptop ?

Structure folder and files deploy a Web Server with Terraform

Created Single-WebServer folder contains files as below:

main.tf
output.tf
provider.tf
securitygroups.tf

Deploy a Web Server with Terraform

Create new file main.tf with the content as below

resource "aws_instance" "devopsroles-lab01" {
 ami = "ami-0c2d06d50ce30b442"
 instance_type = "t2.micro"
 vpc_security_group_ids = ["${aws_security_group.webserver_security_group.id}"]
 tags = {
	 Name = "DevopsRoles-Webserver"
 }
 key_name = "terraform-demo"
 user_data = <<EOF
#!/bin/bash -xe
exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1
sudo yum update -y
sudo amazon-linux-extras install nginx1 -y
sudo su -c "/bin/echo 'My Site: DevopsRoles.com' >/usr/share/nginx/html/index.html"
instance_ip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`
sudo su -c "echo $instance_ip >>/usr/share/nginx/html/index.html"
sudo systemctl start nginx
sudo systemctl enable  nginx
EOF
}

On AWS, we created key pair terraform-demo as the picture below

Deploy a Web Server with Terraform
Deploy a Web Server with Terraform

Create a new file provider.tf with the content as below

provider "aws" {
	region = "us-west-2"
}

New file securitygroups.tf with the content as below

resource "aws_security_group" "webserver_security_group" { 

    ingress {
        from_port = 22
        to_port = 22
        protocol = "tcp"
        cidr_blocks = [ "116.110.26.150/32"]
    }
    ingress {
        from_port = 80
        to_port = 80
        protocol = "tcp"
        cidr_blocks = [ "116.110.26.150/32"]
    }
    
egress {
    from_port       = 0
    to_port         = 0
    protocol        = "-1"
    cidr_blocks     = ["0.0.0.0/0"]
  }    
}

Create a new file output.tf with the content as below

output "public_ip" {
    value = "${aws_instance.devopsroles-lab01.public_ip}"
}

First, we run below to initialize, download the plugins and validate the terraform syntax…

terraform init
terraform validate

The output terminal is as follows

Deploy a Web Server with Terraform

Applying a template

$ terraform apply

The output terminal is as below

C:\Users\HuuPV\Desktop\Terraform\Single-WebServer>terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with
the following symbols:
  + create

Terraform will perform the following actions:

  # aws_instance.devopsroles-lab01 will be created
  + resource "aws_instance" "devopsroles-lab01" {
      + ami                                  = "ami-0c2d06d50ce30b442"
      + arn                                  = (known after apply)
      + associate_public_ip_address          = (known after apply)
      + availability_zone                    = (known after apply)
      + cpu_core_count                       = (known after apply)
      + cpu_threads_per_core                 = (known after apply)
      + disable_api_termination              = (known after apply)
      + ebs_optimized                        = (known after apply)
      + get_password_data                    = false
      + host_id                              = (known after apply)
      + id                                   = (known after apply)
      + instance_initiated_shutdown_behavior = (known after apply)
      + instance_state                       = (known after apply)
      + instance_type                        = "t2.micro"
      + ipv6_address_count                   = (known after apply)
      + ipv6_addresses                       = (known after apply)
      + key_name                             = "terraform-demo"
      + monitoring                           = (known after apply)
      + outpost_arn                          = (known after apply)
      + password_data                        = (known after apply)
      + placement_group                      = (known after apply)
      + primary_network_interface_id         = (known after apply)
      + private_dns                          = (known after apply)
      + private_ip                           = (known after apply)
      + public_dns                           = (known after apply)
      + public_ip                            = (known after apply)
      + secondary_private_ips                = (known after apply)
      + security_groups                      = (known after apply)
      + source_dest_check                    = true
      + subnet_id                            = (known after apply)
      + tags                                 = {
          + "Name" = "DevopsRoles-Webserver"
        }
      + tags_all                             = {
          + "Name" = "DevopsRoles-Webserver"
        }
      + tenancy                              = (known after apply)
      + user_data                            = "e210837ad2017cf0971bc0ed4af86edab9d8a10d"
      + user_data_base64                     = (known after apply)
      + vpc_security_group_ids               = (known after apply)

      + capacity_reservation_specification {
          + capacity_reservation_preference = (known after apply)

          + capacity_reservation_target {
              + capacity_reservation_id = (known after apply)
            }
        }

      + ebs_block_device {
          + delete_on_termination = (known after apply)
          + device_name           = (known after apply)
          + encrypted             = (known after apply)
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + snapshot_id           = (known after apply)
          + tags                  = (known after apply)
          + throughput            = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = (known after apply)
          + volume_type           = (known after apply)
        }

      + enclave_options {
          + enabled = (known after apply)
        }

      + ephemeral_block_device {
          + device_name  = (known after apply)
          + no_device    = (known after apply)
          + virtual_name = (known after apply)
        }

      + metadata_options {
          + http_endpoint               = (known after apply)
          + http_put_response_hop_limit = (known after apply)
          + http_tokens                 = (known after apply)
        }

      + network_interface {
          + delete_on_termination = (known after apply)
          + device_index          = (known after apply)
          + network_interface_id  = (known after apply)
        }

      + root_block_device {
          + delete_on_termination = (known after apply)
          + device_name           = (known after apply)
          + encrypted             = (known after apply)
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + tags                  = (known after apply)
          + throughput            = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = (known after apply)
          + volume_type           = (known after apply)
        }
    }

  # aws_security_group.webserver_security_group will be created
  + resource "aws_security_group" "webserver_security_group" {
      + arn                    = (known after apply)
      + description            = "Managed by Terraform"
      + egress                 = [
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + description      = ""
              + from_port        = 0
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "-1"
              + security_groups  = []
              + self             = false
              + to_port          = 0
            },
        ]
      + id                     = (known after apply)
      + ingress                = [
          + {
              + cidr_blocks      = [
                  + "116.110.26.150/32",
                ]
              + description      = ""
              + from_port        = 22
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 22
            },
          + {
              + cidr_blocks      = [
                  + "116.110.26.150/32",
                ]
              + description      = ""
              + from_port        = 80
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 80
            },
        ]
      + name                   = (known after apply)
      + name_prefix            = (known after apply)
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + tags_all               = (known after apply)
      + vpc_id                 = (known after apply)
    }

Plan: 2 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + public_ip = (known after apply)

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_security_group.webserver_security_group: Creating...
aws_security_group.webserver_security_group: Still creating... [10s elapsed]
aws_security_group.webserver_security_group: Creation complete after 15s [id=sg-08ad09dbfd038f567]
aws_instance.devopsroles-lab01: Creating...
aws_instance.devopsroles-lab01: Still creating... [10s elapsed]
aws_instance.devopsroles-lab01: Still creating... [20s elapsed]
aws_instance.devopsroles-lab01: Still creating... [30s elapsed]
aws_instance.devopsroles-lab01: Still creating... [40s elapsed]
aws_instance.devopsroles-lab01: Creation complete after 48s [id=i-085b38b93b9e04090]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Outputs:

public_ip = "34.221.162.57"

C:\Users\HuuPV\Desktop\Terraform\Single-WebServer>

The result, on EC2 AWS

Deploy a Web Server with Terraform

Open Browser, type http://IP_Public_EC2 as below

awsec2

Conclusion

You have to Deploy a Web Server with Terraform. I hope will this your helpful. Thank you for reading the DevopsRoles page!

About HuuPV

My name is Huu. I love technology, especially Devops Skill such as Docker, vagrant, git, and so forth. I like open-sources, so I created DevopsRoles.com to share the knowledge I have acquired. My Job: IT system administrator. Hobbies: summoners war game, gossip.
View all posts by HuuPV →

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.