Deploy an EC2 instance using Terraform, install Apache Tomcat automatically using user_data, and access it from a browser via http://<public-ip>:8080.
Step 1: Terraform EC2 Instance Setup
Actions:
Created a main.tf file with:
aws_instance
aws_security_group (for port 8080)
user_data to install and start Tomcat
Error:
This site can’t be reached — <public-ip> refused to connect
Cause:
EC2 was running, but Tomcat wasn’t listening.
SSH access wasn’t set up.
Only port 8080 was allowed (not SSH 22).
Solution:
Updated the security group to allow port 22 and port 8080.
Added:
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
Step 2: SSH Access Setup
Actions:
Tried SSH into EC2:
ssh -i my-keypair.pem ec2-user@<public-ip>
Error:
Warning: Identity file my-keypair.pem not accessible: No such file or directory.
Permission denied (publickey)
Cause:
.pem file was missing or incorrect
Wrong key_name in Terraform
Solution:
Placed correct .pem file in the project directory
Ensured key_name = "my-keypair" matched AWS key
Retried SSH successfully
Step 3: user_data Script Not Executing
Actions:
SSH into EC2
Checked logs:
cat /var/log/cloud-init-output.log
Error:
Tomcat .tar.gz not found
startup.sh: No such file or directory
Cause:
Script was trying to download:
https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.86/bin/apache-tomcat-9.0.86.tar.gz
But version 9.0.86 had been removed from Apache mirror
Solution:
Manually tested newer version (9.0.105) and confirmed it worked
Updated user_data to:
wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.105/bin/apache-tomcat-9.0.105.tar.gz -P /tmp
Step 4: Browser Blocked HTTP
Error:
Browser blocks http://<public-ip>:8080
Cause:
Browser (like Chrome) was enforcing HTTPS only
Port 8080 was non-standard and considered insecure
Solutions:
Use curl instead of browser:
curl http://<public-ip>:8080
OR disable secure-only setting in browser:
Chrome: chrome://settings/security → Turn off "Always use secure connections"
OR switch to Firefox or incognito mode
Step 5: curl Failed to Connect
Error:
curl: (7) Failed to connect to <ip> port 8080: Couldn't connect to server
Cause:
Tomcat wasn't running
user_data download or extract failed earlier
Port not listening
Solution:
SSH into EC2 and ran:
sudo /opt/tomcat/bin/startup.sh
sudo netstat -tulnp | grep 8080
Verified Tomcat was listening
Finally: Tomcat worked on port 8080
Final main.tf file with all the above issues fixed
provider "aws" {
region = "us-east-2" # Change region if needed
}
# Get latest Amazon Linux 2 AMI
data "aws_ami" "amazon_linux" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-gp2"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
}
# Use default VPC
data "aws_vpc" "default" {
default = true
}
# Security Group: Allow port 22 (SSH) and 8080 (Tomcat)
resource "aws_security_group" "allow_ssh_tomcat" {
name = "allow_ssh_tomcat"
description = "Allow SSH and Tomcat access"
vpc_id = data.aws_vpc.default.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # SSH - Open to all for test
}
ingress {
from_port = 8080
to_port = 8080
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # Tomcat port
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# EC2 Instance with Tomcat Installation
resource "aws_instance" "tomcat_instance" {
ami = data.aws_ami.amazon_linux.id
instance_type = "t2.micro"
key_name = "my-keypair" # Replace with your actual AWS key pair name
vpc_security_group_ids = [aws_security_group.allow_ssh_tomcat.id]
user_data = <<-EOF
#!/bin/bash
exec > /var/log/user-data.log 2>&1
echo "Updating system..."
yum update -y
echo "Installing Java and wget..."
yum install -y java-1.8.0-openjdk wget
echo "Creating tomcat user..."
groupadd tomcat || true
useradd -M -s /bin/nologin -g tomcat -d /opt/tomcat tomcat || true
echo "Downloading Tomcat 9.0.105..."
wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.105/bin/apache-tomcat-9.0.105.tar.gz -P /tmp
echo "Extracting Tomcat..."
mkdir -p /opt/tomcat
tar -xf /tmp/apache-tomcat-9.0.105.tar.gz -C /opt/tomcat --strip-components=1
echo "Setting permissions..."
chown -R tomcat: /opt/tomcat
chmod +x /opt/tomcat/bin/*.sh
echo "Starting Tomcat..."
sh /opt/tomcat/bin/startup.sh
EOF
tags = {
Name = "Terraform-Tomcat-EC2"
}
}
# Output the public IP after apply
output "public_ip" {
value = aws_instance.tomcat_instance.public_ip
}
Key Lessons & Best Practices
Always verify if the URLs used in automation (like Tomcat tarballs) are still live
- Always check
cloud-init-output.logto debug user_data scripts - Allow SSH (22) in every security group for easy EC2 debugging
- Use
netstatandcurlto test internally when browser fails Automate logging in user_data using:
exec > /var/log/user-data.log 2>&1
Top comments (0)