Table of Contents
#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
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
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
Open Browser, type http://IP_Public_EC2 as below
Conclusion
You have to Deploy a Web Server with Terraform. I hope will this your helpful. Thank you for reading the DevopsRoles page!