DEV Community

Cover image for Creating an EC2 using Terrafrom.
Kranthidas Nallagatla
Kranthidas Nallagatla

Posted on

Creating an EC2 using Terrafrom.

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
Enter fullscreen mode Exit fullscreen mode

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"]
  }
Enter fullscreen mode Exit fullscreen mode

Step 2: SSH Access Setup

Actions:

Tried SSH into EC2:

  ssh -i my-keypair.pem ec2-user@<public-ip>
Enter fullscreen mode Exit fullscreen mode

Error:

Warning: Identity file my-keypair.pem not accessible: No such file or directory.
Permission denied (publickey)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Error:

Tomcat .tar.gz not found
startup.sh: No such file or directory
Enter fullscreen mode Exit fullscreen mode

Cause:

Script was trying to download:

  https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.86/bin/apache-tomcat-9.0.86.tar.gz
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Step 4: Browser Blocked HTTP

Error:

Browser blocks http://<public-ip>:8080
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

Key Lessons & Best Practices

Always verify if the URLs used in automation (like Tomcat tarballs) are still live

  • Always check cloud-init-output.log to debug user_data scripts
  • Allow SSH (22) in every security group for easy EC2 debugging
  • Use netstat and curl to test internally when browser fails Automate logging in user_data using:
  exec > /var/log/user-data.log 2>&1
Enter fullscreen mode Exit fullscreen mode

Top comments (0)