π Terraform Series β Day 8

Automating AWS EC2 Setup with Terraform and user_data
Welcome back to our Terraform journey. In infrastructure as code, setting up a server is just the beginning. After your EC2 instance is running, you need to set it up, install what it needs, and start your apps. Doing this by hand goes against the idea of automation.
In this post, we will demonstrate how to completely automate your server bootstrapping process using Terraform and the AWS user_data feature.
π― Objective
By the end of this guide, you will learn how to automatically install and configure an Nginx web server on a newly provisioned AWS EC2 instance using a Terraform user_data script.
π§© Step 1: Understanding the Power of user_data
The Problem with Manual Configuration
Imagine you just used Terraform to spin up a fresh EC2 instance. Without an automation script, your next steps would look like this:
SSH into the instance.
Manually run package updates.
Install Nginx.
Start the service.
Create a custom HTML page.
This approach is time-consuming, prone to human error, and most importantly, not scalable. If you need to spin up 100 web servers behind a load balancer, logging into each one manually is impossible.
The Solution: Bootstrap Scripts
AWS provides a feature called user_data that allows you to pass a script to your instance at launch.
βοΈ Runs automatically the very first time the instance boots.
βοΈ Fully automates software installation and configuration.
βοΈ Scales infinitely across as many instances as you deploy.
In short: user_data is your EC2 bootstrapping engine.
π Step 2: Create the Bootstrapping Script (nginx.sh)
First, we need to define the commands we want our server to run on startup. We will create a simple bash script that installs Nginx and creates a custom landing page.
Create a new file named nginx.sh:3
touch nginx.sh
Add the following content to the file:-
#!/bin/bash
# Update package lists
sudo apt-get update
# Install Nginx silently (-y prevents the prompt)
sudo apt-get install nginx -y
# Start the Nginx service
sudo systemctl start nginx
# Enable Nginx to start automatically if the server reboots
sudo systemctl enable nginx
# Create a custom HTML landing page
echo "<h1> Terraform testing with scripting </h1>" > /var/www/html/index.html
π Step 3: Attach the Script in Terraform
Now, we need to tell Terraform to pass this script to our EC2 instance during creation. We do this by utilizing the file() function within the user_data argument of our aws_instance resource.
Open your ec2.tf file and configure your instance block:-
resource "aws_instance" "my_instance" {
ami = var.ec2_ami_id
instance_type = var.ec2_instance_type
# Attach your SSH key pair
key_name = aws_key_pair.my_key.key_name
# Attach the security group (make sure port 80 is open!)
vpc_security_group_ids = [aws_security_group.my_groups.id]
# Inject the bootstrap script here
user_data = file("nginx.sh")
# Define root storage
root_block_device {
volume_size = var.ec2_root_storage_size
volume_type = "gp3"
}
tags = {
Name = "terraform-ec2-nginx"
}
}
file("nginx.sh") keeps your Terraform code clean by separating the bash logic from the HCL infrastructure definitions.
βοΈ Step 4: Execute the Pipeline
With the script created and Terraform configured, it's time to deploy. Run the following commands in your terminal:
Bash
terraform init
terraform apply -auto-approve
What happens internally?
Once you hit apply, an elegant automated workflow kicks off:
Infrastructure Provisioned: Terraform calls the AWS API to launch a new EC2 instance.
Script Passed: The contents of
nginx.share passed to the instance metadata.Bootstrapping Execution: As the EC2 instance boots up, the OS executes the script as the
rootuser.App Deployed: Packages are updated, Nginx is installed, the service is started, and your custom HTML page is generated.
Within minutes, you can grab the public IP of your new EC2 instance, paste it into your browser, and see your custom HTML pageβzero SSH required.
π§ͺ Testing: Verify NGINX on EC2 Instance
After provisioning the EC2 instance using Terraform, we need to test whether NGINX is properly installed and running.
πΉ Step 1: Connect to EC2 via SSH
ssh -i "your-key.pem" ubuntu@<EC2-PUBLIC-IP>
β Replace:
your-key.pemβ your private key<EC2-PUBLIC-IP>β instance public IP
πΉ Step 2: Check NGINX Status
sudo systemctl status nginx
β Expected Output:
active (running)β β NGINX is workinginactive / failedβ β issue needs fixing
πΉ Step 3: Test via Browser
Open your browser and hit:
http://<EC2-PUBLIC-IP>
β Expected:
- Default NGINX Welcome Page
πΉ Step 5: Test via Curl (CLI Testing)
curl http://localhost
OR from your local system:
curl http://<EC2-PUBLIC-IP>
β If HTML response comes β β Server is working
πΉ Step 6: Check Port 80 (Important for DevOps)
sudo netstat -tulpn | grep :80
OR
sudo ss -tulpn | grep :80
β Confirms:
- NGINX is listening on port 80
π‘ Key Takeaways
No More Manual SSH: Bootstrapping completely eliminates the need to manually configure infrastructure after it is provisioned.
Separation of Concerns: By using the
file()function, you keep your shell scripts separate from your Terraform code, making both easier to maintain.Idempotency and Scale: A script guarantees that every server you provision will be configured exactly the same way, every single time.
π¨βπ» About the Author
βA complete Terraform series covering everything from fundamentals to advanced real-world infrastructure automation in a DevOps environment.β
π¬ Let's Stay Connected
π§ Email: gujjarapurv181@gmail.com
π GitHub: github.com/ApurvGujjar07
πΌ LinkedIn: linkedin.com/in/apurv-gujjar





