Deploying a Scalable Web Application on AWS with EC2, ALB, and Route 53

ยท

4 min read

In this tutorial, we will walk through the process of launching an Amazon EC2 instance with Apache HTTPD installed, registering it with an Application Load Balancer (ALB), and creating a Route 53 subdomain. This setup provides a scalable and robust solution for hosting web applications on AWS.

Prerequisites

Before we begin, ensure you have the following:

  • An AWS account.

  • Basic knowledge of AWS services such as EC2, ALB, and Route 53.

  • Boto3 library installed in your AWS Lambda environment or local machine for Python.

Steps Overview

  1. Launch an EC2 instance with HTTPD installed.

  2. Register the instance with an ALB target group.

  3. Create a Route 53 subdomain pointing to the ALB.

Step 1: Launch an EC2 Instance

We will use AWS Lambda to automate the deployment of our EC2 instance. The Lambda function will include user data to install Apache HTTPD.

Hereโ€™s the Python code to achieve this:

import json
import boto3

# Initialize boto3 clients
ec2 = boto3.client('ec2')
elbv2 = boto3.client('elbv2')
route53 = boto3.client('route53')

def lambda_handler(event, context):
    # Parameters
    username = event['username']  # Username for subdomain
    ami_id = 'REPLACE_WITH_YOUR_AMI_ID'  # Replace with your AMI ID
    instance_type = 't2.micro'  # Instance type
    key_name = 'REPLACE_WITH_YOUR_KEY_PAIR_NAME'  # Replace with your key pair name
    security_group_ids = ['REPLACE_WITH_YOUR_SECURITY_GROUP_ID']  # Replace with your security group ID
    target_group_arn = 'REPLACE_WITH_YOUR_TARGET_GROUP_ARN'  # Replace with your target group ARN
    hosted_zone_id = 'REPLACE_WITH_YOUR_HOSTED_ZONE_ID'  # Replace with your hosted zone ID
    subdomain_name = f"{username}.YOUR_DOMAIN_NAME"  # Replace with your domain

    # Step 1: Launch an EC2 instance with httpd installed
    instance = ec2.run_instances(
        ImageId=ami_id,
        InstanceType=instance_type,
        KeyName=key_name,
        SecurityGroupIds=security_group_ids,
        MinCount=1,
        MaxCount=1,
        UserData='''#!/bin/bash
        yum update -y
        yum install -y httpd
        echo "<h1>Hello, from EC2 instance!</h1>" > /var/www/html/index.html
        systemctl start httpd
        systemctl enable httpd
        '''
    )

    instance_id = instance['Instances'][0]['InstanceId']
    print(f'Launched EC2 instance: {instance_id}')

    # Step 2: Wait for the instance to be running
    ec2.get_waiter('instance_running').wait(InstanceIds=[instance_id])
    print(f'EC2 instance {instance_id} is now running.')

    # Step 3: Register the EC2 instance with the ALB target group
    elbv2.register_targets(TargetGroupArn=target_group_arn, Targets=[{'Id': instance_id}])
    print(f'EC2 instance {instance_id} registered with target group {target_group_arn}.')

    # Step 4: Create a Route 53 record for the subdomain
    response = route53.change_resource_record_sets(
        HostedZoneId=hosted_zone_id,
        ChangeBatch={
            'Changes': [
                {
                    'Action': 'CREATE',
                    'ResourceRecordSet': {
                        'Name': subdomain_name,
                        'Type': 'A',
                        'AliasTarget': {
                            'HostedZoneId': 'REPLACE_WITH_YOUR_ALB_HOSTED_ZONE_ID',  # Replace with your ALB Hosted Zone ID
                            'DNSName': 'REPLACE_WITH_YOUR_ALB_DNS_NAME',  # Replace with your ALB DNS name
                            'EvaluateTargetHealth': False
                        }
                    }
                }
            ]
        }
    )

    print(f'Subdomain {subdomain_name} created in Route 53.')

    return {
        'statusCode': 200,
        'body': json.dumps({
            'message': f'Instance {instance_id} created and registered with ALB. Subdomain {subdomain_name} created.'
        })
    }

Explanation of the Code

  1. Initialization: We import necessary libraries and initialize Boto3 clients for EC2, ELB, and Route 53.

  2. Parameters: Set parameters such as AMI ID, instance type, key name, security group ID, target group ARN, and hosted zone ID.

  3. Launching the EC2 Instance:

    • We use the run_instances method to launch an EC2 instance with HTTPD installed using a bash script in UserData.

    • The bash script updates the system, installs Apache, and creates a simple HTML page.

  4. Waiting for the Instance: The Lambda function waits until the instance is in a running state.

  5. Registering with ALB: The EC2 instance is registered with the specified target group.

  6. Creating Route 53 Record: Finally, a Route 53 record is created to point the subdomain to the ALB.

Step 2: Configure Security Group

Ensure that your security group allows inbound traffic on port 80 (HTTP). This is crucial for the health checks and accessing your web server.

  1. Navigate to the EC2 Dashboard.

  2. Select Security Groups in the left menu.

  3. Find the security group you specified and edit its inbound rules:

    • Type: HTTP

    • Protocol: TCP

    • Port Range: 80

    • Source: 0.0.0.0/0 (or restrict to specific IPs)

Step 3: Configure ALB Health Check

Make sure the health check settings for your ALB target group are configured correctly:

  1. Go to the EC2 Dashboard and click on Target Groups.

  2. Select your target group and navigate to the Health checks tab.

  3. Ensure the health check path is set to / (or the path you are serving).

  4. Adjust the health check interval and timeout as needed.

Testing the Setup

Once you have deployed the Lambda function and ensured that everything is correctly configured:

  1. Invoke the Lambda function with a JSON payload like:

     jsonCopy code{
         "username": "testuser"
     }
    
  2. Access the subdomain you created (testuser.poojaclouddevops.online). You should see the message "Hello, from EC2 instance!" displayed in your web browser.

Conclusion

In this tutorial, we've successfully created a scalable web application hosted on AWS using EC2, ALB, and Route 53. This setup can easily be expanded to include more features, such as HTTPS support, database integration, and scaling policies.

Further Steps

  • Explore adding SSL certificates to secure your web application.

  • Investigate autoscaling features for handling increased traffic.

  • Consider implementing CI/CD pipelines for automatic deployment.

Feel free to ask any questions in the comments below, and happy cloud computing!

Did you find this article valuable?

Support NavyaDevops by becoming a sponsor. Any amount is appreciated!

ย