10. Installing NGINX on creation of EC2 Instances with Shell Scripts (Terraform Hands-On Project)
Introduction
This hands-on project demonstrates how to use Terraform to launch an AWS EC2 instance and install NGINX on it using a shell script. The EC2 instance is configured with a user data script that performs the installation and setup of NGINX, including deploying a sample web application. This approach ensures that the necessary software is installed and configured automatically when the instance is launched.
Objective
The main objective of this project is to automatically configure an EC2 instance using Terraform and a shell script. The shell script is executed through the user data block, which performs the following tasks:
Updates the package index.
Installs NGINX.
Configures NGINX to start on boot.
Deploys a sample HTML web page.
Configures firewall rules to allow HTTP traffic.
AWS Resources Used
AWS EC2: The compute resource where NGINX is installed and configured.
AWS VPC & Subnets: Network configuration where the EC2 instance is deployed.
Infrastructure as Code (IaC) tool used to define and provision AWS resources.
Configuration
terraform {
required_providers {
aws = {
source = "hashicorp/aws" # Specifies the source of the AWS provider. In this case, it's from HashiCorp, the organization that maintains Terraform.
version = "~> 5.0" # Sets the version constraint for the AWS provider. The "~> 5.0" notation means any version in the 5.x series that is compatible with version 5.0, but not version 6.0 or higher.
}
}
}
provider "aws" {
region = var.aws_region # Specifies the AWS region where resources will be provisioned. The actual region value is fetched from a variable `aws_region`.
}
Terrafrom main.tf contains the primary resource configuration for the EC2 instance, including the AMI ID, instance type, subnet, key pair, and user data script that installs NGINX and sets up a sample web page.
# Resource block for an AWS EC2 instance, which will be used for accessing or managing an AWS EKS cluster
resource "aws_instance" "eks_access_instance" {
ami = var.ami_id # AMI ID for the EC2 instance, specifying which operating system to use
instance_type = var.instance_type # Type of the EC2 instance (e.g., t2.micro, m5.large), determining its compute and memory capacity
subnet_id = element(var.subnet_ids, 0) # Assign the instance to the first subnet in the provided list of subnet IDs
#iam_instance_profile = aws_iam_instance_profile.ec2_instance_profile.name # IAM role for granting the instance necessary permissions
key_name = var.key_name # SSH key pair name for secure shell access to the instance
# Provisioners for configuring the EC2 instance after it's launched
provisioner "file" {
source = "shellscript.sh" # Source path of the file to transfer
destination = "/tmp/shellscript.sh" # Destination path on the instance
}
provisioner "remote-exec" {
inline = [
"cat /tmp/shellscript.sh", # Display the content of the script
"chmod +x /tmp/shellscript.sh", # Make the script executable
"/tmp/shellscript.sh", # Execute the script
"ls -l /tmp", # List files in /tmp to verify file is transferred
]
}
# Connection block to specify how Terraform connects to the instance for provisioning
connection {
type = "ssh"
user = "ubuntu" # Default username for Ubuntu AMIs
private_key = file(var.private_key_path) # Private key for SSH access
host = self.public_ip # Use the instance's public IP address for SSH connection
}
# Tags for the instance, useful for organization and identifying resources within AWS
tags = {
Name = "${var.cluster_name}" # Tag the instance with the name of the EKS cluster for easy identification
}
}
Defines the outputs to be displayed after the Terraform apply command, such as the public IP of the created EC2 instance, allowing users to access the instance and verify the NGINX setup.
# Output block to display the public IP address of the created EC2 instance
output "instance_public_ip" {
description = "Public IP address of the EC2 instance."
value = aws_instance.eks_access_instance.public_ip
}
Declares variables for dynamic configuration, such as AWS region, instance details, and SSH key path, making the Terraform configuration flexible and reusable.
# Define the AWS region where resources will be created
variable "aws_region" {
description = "The AWS region to create resources in"
type = string
default = "us-east-1"
}
# Define the name for the EC2 instance
variable "instance_name" {
description = "Name of the EC2 Instance"
default = "My Instance"
}
# Define the subnet IDs where the EC2 instance will be launched
variable "subnet_ids" {
description = "List of subnet IDs for the Instance"
type = list(string)
default = ["subnet-04e3b5acc7f530ece"]
}
# Define the AMI ID to use for the EC2 instance
variable "ami_id" {
description = "The ID of the AMI to use for the instance."
type = string
default = "ami-0a0e5d9c7acc336f1"
}
# Define the instance type for the EC2 instance
variable "instance_type" {
description = "The instance type for the EC2 instance"
default = "t2.micro"
}
# Define the key name of the SSH key pair to attach to the EC2 instance
variable "key_name" {
description = "The key name of the SSH key pair to attach to the instance"
default = "north-virginiaASUS"
}
# Define the path to the private key file used for SSH access to the instance
variable "private_key_path" {
description = "Path to the private key file for SSH access"
type = string
default = "C:/Users/Shraddha/Downloads/north-virginiaASUS.pem"
}
# Define the name of the EKS cluster for tagging the EC2 instance
variable "cluster_name" {
description = "Name of the EKS cluster"
type = string
default = "my-eks-cluster-server"
}
Shell Script:
Contains the commands needed to install and configure NGINX. It is uploaded to the EC2 instance as part of the provisioning process but is executed via the user data script.
#!/bin/bash
# Update the package index
sudo apt-get update -y
# Install Nginx
sudo apt-get install nginx -y
# Start Nginx service
sudo systemctl start nginx
# Enable Nginx to start on boot
sudo systemctl enable nginx
# Create a sample web application
sudo mkdir -p /var/www/html
# Write a simple HTML file
sudo bash -c 'cat > /var/www/html/index.html << EOF
<!DOCTYPE html>
<html>
<head>
<title>Welcome to Your Sample Web Application!</title>
</head>
<body>
<h1>This is a sample web application served by Nginx created using Terraform !!!</h1>
</body>
</html>
EOF'
# Adjust firewall to allow traffic on port 80
sudo ufw allow 'Nginx HTTP'
# Reload Nginx to apply changes
sudo systemctl reload nginx
echo "Nginx has been installed and the sample web application has been deployed!"
Steps to Apply the Terraform Configuration Initialize Terraform.
Open your terminal and run the following command to initialize Terraform:
terraform init
Plan the Changes:
terraform plan
Apply the Changes:
terraform apply
Verification
To verify the infrastructure and ensure that NGINX is installed correctly, follow these steps:
Navigate to the EC2 Dashboard. Check EC2 Instance Status:
Go to the "Instances" section. Find the EC2 instance created by Terraform. Verify that the instance is in the "running" state and has passed status checks.
Obtain the Instance's Public IP:
- Find the public IP address of the EC2 instance from the "Instances" section.
Access the Sample Web Application:
Open a web browser and navigate to
http://<Public_IP_Address>
. Verify that the sample HTML page served by NGINX is displayed, confirming that NGINX is correctly installed and configured.
Conclusion
By using Terraform in conjunction with a shell script, the project effectively automates the deployment and configuration of NGINX on an EC2 instance. This setup minimizes manual intervention, ensures consistency across deployments, and demonstrates a practical use case for Terraform and user data scripts in AWS infrastructure management.
end
ens