For hosting multiple websites, administrators commonly use the ‘Virtual Hosting’ technique. Virtual hosting allows the hosting of multiple websites on a single server and can be achieved using either the ‘IP-based’ method or the ‘name-based’ approach. In ‘IP-based’ hosting, each website has a distinct IP address. On the other hand, ‘name-based’ hosting involves multiple domain names running on a single IP address.
There are numerous tools available today for automating cloud-based infrastructure, and Terraform is one such tool that has recently gained enormous popularity in the DevOps world. Terraform, an open-source tool developed by HashiCorp, uses its own HashiCorp Configuration Language (HCL) to provision multiple cloud service providers. Essentially, Terraform compares your current infrastructure configuration to the desired state and only modifies those parts of the infrastructure that are required to achieve the desired state.
What Will We Cover?
In this tutorial, we will demonstrate how to host two virtual hosts on an Ubuntu 22.04 system using Terraform, utilizing the Apache web server to achieve this setup.
Pre-Flight Check
Before proceeding, ensure you meet the following prerequisites:
- Familiarity with Terraform basics.
- Terraform installed on your system.
- AWS account configured on your local system.
- Understanding of setting up a virtual host using the Apache web server.
Setting Up the Lab
We will use an Ubuntu 22.04 server to install the Apache web server. We’ll configure two virtual hosts, each serving a unique index.html
file:
- “Webpage from: Virtual Host 1.” for vhost1
- “Webpage from: Virtual Host 2.” for vhost2
For simplicity, the domain names for the two virtual hosts (vhosts) are mapped to the localhost IP address (127.0.0.1). This setup uses the following files:
userdata.sh
: A bash script to set up the EC2 server and configure the web server for virtual hosts.sec-grp.tf
: Defines a resource for creating a security group.vhost-template.tf
: Contains the actual configuration for the virtual hosts.main.tf
: Declares the web server resource and the rest of the infrastructure.
Multiple files help maintain clarity and facilitate code review. Let’s proceed with the main steps:
Step 1: Create a directory for your project files:
$ mkdir virtual-hosts-terraform
Step 2: Set up the EC2 instance for virtual hosting using a userdata script to automate common server configurations:
$ vi userdata.sh
#!/bin/bash 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.vhost1.com >> /etc/hosts" sudo sh -c "echo 127.0.0.1 www.vhost2.com >> /etc/hosts" sudo mkdir -p /var/www/vhost_1/public_html sudo mkdir -p /var/www/vhost_2/public_html sudo chown -R $USER:$USER /var/www/vhost_1/public_html sudo chown -R $USER:$USER /var/www/vhost_2/public_html sudo chmod -R 755 /var/www sudo echo "Webpage from: Virtual Host 1." > /var/www/vhost_1/public_html/index.html sudo echo "Webpage from: Virtual Host 2." > /var/www/vhost_2/public_html/index.html sudo cp /home/ubuntu/vhosts.conf /etc/apache2/sites-available/vhosts.conf sudo a2ensite vhosts.conf sudo a2dissite 000-default.conf sudo systemctl restart apache2
Step 3: Configure a security group resource to set the traffic rules, allowing SSH and HTTP traffic:
$ vi sec-grp.tf
resource "aws_security_group" "ec2-sg" { name = "ec2-grp" description = "Set Ingress and Egress Rules" 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: Define the configuration for each virtual host:
$ vi vhost-template.conf
<VirtualHost *:80> ServerAdmin admin@vhost1.com ServerName vhost1 ServerAlias www.vhost1.com DocumentRoot /var/www/vhost_1/public_html ErrorLog ${APACHE_LOG_DIR}/error.log </VirtualHost> <VirtualHost *:80> ServerAdmin admin@vhost2.com ServerName vhost2 ServerAlias www.vhost2.com DocumentRoot /var/www/vhost_2/public_html ErrorLog ${APACHE_LOG_DIR}/error.log </VirtualHost>
Step 5: Set up the main Terraform configuration file:
$ vi main.tf
provider "aws" { region = "us-east-1" } resource "aws_instance" "webserver" { ami = "ami-09d56f8956ab235b3" instance_type = "t2.micro" key_name = "Name-of-EC2-Key-Pair" vpc_security_group_ids = [aws_security_group.ec2-sg.id] associate_public_ip_address = true provisioner "file" { source = "vhost-template.conf" destination = "/home/ubuntu/vhosts.conf" connection { type = "ssh" user = "ubuntu" private_key = "${file("/Path/to/EC2-Key-Pair")}" host = "${self.public_dns}" } } user_data = "${file("userdata.sh")}" tags = { Name = "VirtualHostTutorial" } } output "IPAddress" { value = "${aws_instance.webserver.public_dns}" }
The file provisioner uploads the ‘vhost-template.conf’ file to the EC2 instance, and the ‘file’ command executes the userdata script.
Step 6: Initialize the project directory and apply the configuration:
$ terraform init
$ terraform apply
Testing the Setup
SSH into your instance and run the following command to test the virtual host setup:
$ curl www.vhost1.com
The above command should return the message from the virtual host1 index page. Similarly, run this command to test virtual host2:
$ curl www.vhost2.com
Conclusion
Congratulations! You have successfully set up virtual hosting on your system using Terraform. This tutorial can be a foundation for more complex Terraform implementations. Give it a try and explore further possibilities.
FAQ
What is virtual hosting?
Virtual hosting allows multiple domain names to be served by a single web server. It can be implemented using IP-based or name-based hosting.
What is Terraform?
Terraform is an open-source tool by HashiCorp for automating cloud infrastructure. It uses HashiCorp Configuration Language (HCL) to define and provision infrastructure as code.
Why use the Apache web server in this setup?
Apache is a widely-used open-source web server that supports name-based and IP-based virtual hosting, making it a popular choice for hosting multiple domains.
Can I add more virtual hosts using this setup?
Yes, you can add more virtual hosts by modifying the vhost-template.conf
to include additional <VirtualHost>
entries.