“In order to host multiple websites, administrators usually configure Virtual hosting on a single machine. In virtual hosting, we can use either an “IP-based” hosting or a “name-based.” In “IP-based” hosting, we have distinct IP addresses for each website. In the case of “name-based” hosting, we have multiple names running on each IP address.”
In this guide, we will see how we can configure virtual hosts on an Amazon EC2 Ubuntu 22.04 instance. In this lab, we will use name-based virtual hosting. We will use Terraform to deploy the desired infrastructure.
In this lab, we will create two virtual hosts; domain1 and domain2. We will install an apache web server on our Ubuntu machine. Each virtual host has a different index.html file with the content: “This is Virtual host 1.” for domain1 and “This is Virtual host 2.” for domain2.
Instead of registering the domain name for each host, we are using the localhost IP address to map the domain names. This can be done by modifying the “hosts” file. To simplify the deployment of this infrastructure, we have divided the overall configuration into multiple files. In this way, we’ll save ourselves from code clumsiness. Outlines of the files used here:
Step 1. Let us first create a working directory that will keep all our .tf files:
Step 2. Create the userdata.sh file:
Now paste the following lines inside it:
sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get install apache2 -y
sudo systemctl restart apache2
sudo sh -c “echo 127.0.0.1 www.domain1.com >> /etc/hosts”
sudo sh -c “echo 127.0.0.1 www.domain2.com >> /etc/hosts”
sudo mkdir -p /var/www/domain_1/public_html
sudo mkdir -p /var/www/domain_2/public_html
sudo chown -R $USER:$USER /var/www/domain_1/public_html
sudo chown -R $USER:$USER /var/www/domain_2/public_html
sudo chmod -R 755 /var/www
sudo echo “This is Virtual Host 1.” > /var/www/domain_1/public_html/index.html
sudo echo “This is Virtual Host 2.” > /var/www/domain_2/public_html/index.html
sudo cp /home/ubuntu/domain_1.conf /etc/apache2/sites-available/domain_1.conf
sudo cp /home/ubuntu/domain_2.conf /etc/apache2/sites-available/domain_2.conf
sudo a2ensite domain_1.conf
sudo a2ensite domain_2.conf
sudo a2dissite 000-default.conf
sudo systemctl restart apache2
In the above script, we installed an apache web server and modified the host’s file to map the localhost address to the two virtual hosts’ domain names we want to configure. Also, we have configured the web server for the new websites and disabled the default one.
Step 3. Create the secgrp.tf file to allow SSH and HTTP ingress traffic from anywhere and outgoing traffic to anywhere.
Paste the following lines inside it:
ingress {
from_port = 80
to_port = 80
protocol = “tcp”
cidr_blocks = [“0.0.0.0/0”]
}
ingress {
from_port = 22
to_port = 22
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”]
}
}
Step 4. For virtual host configuration, create two files: domain_1.conf and domain_2.conf. Note the document root location in each file.
ServerAdmin admin@domain1.com
ServerName domain1
ServerAlias www.domain1.com
DocumentRoot /var/www/domain_1/public_html
ErrorLog ${APACHE_LOG_DIR}/error.log
VirtualHost>
ServerAdmin admin@domain2.com
ServerName domain2
ServerAlias www.domain2.com
DocumentRoot /var/www/domain_2/public_html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
VirtualHost>
Step 5. Finally, create the main.tf to complete the infrastructure declaration:
provider “aws” {
region =“us-east-1”
}
resource “aws_instance” “webserver” {
ami =“ami-09d56f8956ab235b3”
instance_type = “t2.micro”
key_name = “Name-of-your-Ec2-Key-pair”
vpc_security_group_ids = [aws_security_group.demo-sg.id]
associate_public_ip_address = true
provisioner “file” {
source = “domain_1.conf”
destination = “/home/ubuntu/domain_1.conf”
connection {
type = “ssh”
user = “ubuntu”
private_key = “${file(“/Path/to//EC2-keyPair.pem”)}“
host = “${self.public_dns}“
}
}
provisioner “file” {
source = “domain_2.conf”
destination = “/home/ubuntu/domain_2.conf”
connection {
type = “ssh”
user = “ubuntu”
private_key = “${file(“/Path/to//EC2-keyPair.pem”)}“
host = “${self.public_dns}“
}
}
user_data = “${file(“userdata.sh”)}“
tags = {
Name = “VirtualHosts”
}
}
output “IPAddress” {
value = “${aws_instance.webserver.public_ip}“
}
In the above .tf file, we have used the file provisioner to copy the “domain.conf” file from our local system to the EC2 instance. This “domain.conf” will be used as a template file for making domain specific virtual host files, i.e., “domain_1.conf” and “domain_2.conf”.
Step 6. All our configuration files are ready now; it’s now time to actually deploy this configuration. Initialize the project directory using:
Finally, build the project by running the command:
Enter “yes” on the terminal when asked. From your EC2 instance, use the “curl” command to see what each domain address is displaying:
Virtual hosting is a very efficient technique for managing multiple websites from a single server. In this lab, we have seen how Terraform can be used for deploying a simple two-host infrastructure. Try to make this configuration more scalable by implementing Terraform modules.
Microsoft Edge is now available for Ubuntu. In this guide, I’ll walk you through the…
Our latest Canonical website rebrand did not just bring the new Vanilla-based frontend, it also…
At Canonical, the work of our teams is strongly embedded in the open source principles…
Welcome to the Ubuntu Weekly Newsletter, Issue 873 for the week of December 29, 2024…
Have WiFi troubles on your Ubuntu 24.04 system? Don’t worry, you’re not alone. WiFi problems…
The following is a post from Mark Shuttleworth on the Ubuntu Discourse instance. For more…