Building a Rock-Solid Foundation: A Secure and Resilient AWS Architecture for Your 3-Tier Project

Building a Rock-Solid Foundation: A Secure and Resilient AWS Architecture for Your 3-Tier Project

In today's world, building applications that are not only functional but also secure and resilient is paramount. AWS provides a wealth of tools and services to achieve this, but architecting it effectively requires careful planning and execution. This blog post will guide you through the steps of building a secure and resilient 3-tier architecture on AWS, leveraging VPC, EC2, Lambda, S3, RDS, and other necessary resources.

Understanding the 3-Tier Architecture:

The 3-tier architecture separates an application into three logical layers:

  • Presentation Tier (Web Tier): Handles user interaction and serves the user interface. This is typically where your EC2 instances running web servers (e.g., Apache, Nginx) or Lambda functions that serve static content reside.
  • Application Tier (Business Logic Tier): Processes requests from the presentation tier and interacts with the data tier. This could involve application servers running your business logic on EC2 instances or Lambda functions executing specific tasks.
  • Data Tier: Stores and manages the application's data. This is often an RDS database instance.


Let's Get Started! Here's a Step-by-Step Guide:

1. VPC Setup: The Foundation of Security

A Virtual Private Cloud (VPC) isolates your AWS resources.

  • Create a VPC:

????? aws ec2 create-vpc --cidr-block 10.0.0.0/16 --query Vpc.VpcId --output text???        

  • Create Subnets: We need at least two public subnets for the presentation tier and two private subnets for the application and data tiers for high availability.

VPC_ID="<YOUR_VPC_ID>" # Replace with your VPC ID

# Public Subnets

aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block 10.0.1.0/24 --availability-zone us-east-1a --query Subnet.SubnetId --output text

aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block 10.0.2.0/24 --availability-zone us-east-1b --query Subnet.SubnetId --output text 

# Private Subnets

aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block 10.0.3.0/24 --availability-zone us-east-1a --query Subnet.SubnetId --output text

aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block 10.0.4.0/24 --availability-zone us-east-1b --query Subnet.SubnetId --output text???        

  • Create an Internet Gateway (IGW): Allows public subnets to communicate with the internet.

aws ec2 create-internet-gateway --query InternetGateway.InternetGatewayId --output text

IGW_ID="<YOUR_IGW_ID>" # Replace with the IGW ID

aws ec2 attach-internet-gateway --internet-gateway-id $IGW_ID --vpc-id $VPC_ID???        

  • Create Route Tables: Control traffic flow. We need one public route table and one private route table.

# Public Route Table

aws ec2 create-route-table --vpc-id $VPC_ID --query RouteTable.RouteTableId --output text

PUBLIC_ROUTE_TABLE_ID="<YOUR_PUBLIC_ROUTE_TABLE_ID>" # Replace with your Public Route Table ID 

aws ec2 create-route --route-table-id $PUBLIC_ROUTE_TABLE_ID --destination-cidr-block 0.0.0.0/0 --gateway-id $IGW_ID 

aws ec2 associate-route-table --route-table-id $PUBLIC_ROUTE_TABLE_ID --subnet-id <YOUR_PUBLIC_SUBNET_ID_1>  # Replace with your public subnet ID

aws ec2 associate-route-table --route-table-id $PUBLIC_ROUTE_TABLE_ID --subnet-id <YOUR_PUBLIC_SUBNET_ID_2>  # Replace with your public subnet ID 

# Private Route Table

aws ec2 create-route-table --vpc-id $VPC_ID --query RouteTable.RouteTableId --output text

PRIVATE_ROUTE_TABLE_ID="<YOUR_PRIVATE_ROUTE_TABLE_ID>" # Replace with your Private Route Table ID 

aws ec2 associate-route-table --route-table-id $PRIVATE_ROUTE_TABLE_ID --subnet-id <YOUR_PRIVATE_SUBNET_ID_1> # Replace with your private subnet ID

aws ec2 associate-route-table --route-table-id $PRIVATE_ROUTE_TABLE_ID --subnet-id <YOUR_PRIVATE_SUBNET_ID_2> # Replace with your private subnet ID???        

  • NAT Gateway (for Private Subnet Internet Access): Allows instances in private subnets to initiate outbound traffic to the internet while preventing inbound traffic. Consider using NAT Gateway for production, or NAT Instances (with proper hardening) for cost-sensitive development environments.

Create a NAT Gateway (Requires Elastic IP):

EIP_ALLOCATION_ID="<YOUR_EIP_ALLOCATION_ID>"  # Replace with your Elastic IP Allocation ID

aws ec2 create-nat-gateway --subnet-id <YOUR_PUBLIC_SUBNET_ID_1> --allocation-id $EIP_ALLOCATION_ID --query NatGateway.NatGatewayId --output text

NAT_GATEWAY_ID="<YOUR_NAT_GATEWAY_ID>" # Replace with your NAT Gateway ID 

aws ec2 create-route --route-table-id $PRIVATE_ROUTE_TABLE_ID --destination-cidr-block 0.0.0.0/0 --nat-gateway-id $NAT_GATEWAY_ID        

2. Security Groups: Your Virtual Firewalls

Security Groups act as virtual firewalls, controlling inbound and outbound traffic for your instances.

  • Web Tier Security Group: Allows inbound traffic on ports 80 (HTTP) and 443 (HTTPS) from the internet, and outbound traffic to the application tier. Also allow SSH (port 22) from your trusted source IP address for administration.

aws ec2 create-security-group --group-name web-tier-sg --description "Web Tier Security Group" --vpc-id $VPC_ID --output json 

WEB_SG_ID="<YOUR_WEB_SG_ID>" # replace with the web tier sg id 

aws ec2 authorize-security-group-ingress --group-id $WEB_SG_ID --protocol tcp --port 80 --cidr 0.0.0.0/0

aws ec2 authorize-security-group-ingress --group-id $WEB_SG_ID --protocol tcp --port 443 --cidr 0.0.0.0/0

aws ec2 authorize-security-group-ingress --group-id $WEB_SG_ID --protocol tcp --port 22 --cidr <YOUR_IP_ADDRESS>/32 # Restrict SSH access! 

# Outbound traffic to Application Tier (Assuming application tier uses port 8080)

aws ec2 authorize-security-group-egress --group-id $WEB_SG_ID --protocol tcp --port 8080 --cidr 10.0.3.0/24  # Replace with application tier CIDR

aws ec2 authorize-security-group-egress --group-id $WEB_SG_ID --protocol tcp --port 8080 --cidr 10.0.4.0/24  # Replace with application tier CIDR???        

  • Application Tier Security Group: Allows inbound traffic from the web tier, and outbound traffic to the data tier (RDS).

aws ec2 create-security-group --group-name app-tier-sg --description "Application Tier Security Group" --vpc-id $VPC_ID --output json 

APP_SG_ID="<YOUR_APP_SG_ID>" # replace with the app tier sg id

# Inbound traffic from Web Tier (Assuming web tier uses port 8080 to reach application tier)

aws ec2 authorize-security-group-ingress --group-id $APP_SG_ID --protocol tcp --port 8080 --cidr 10.0.1.0/24  # Replace with Web Tier CIDR

aws ec2 authorize-security-group-ingress --group-id $APP_SG_ID --protocol tcp --port 8080 --cidr 10.0.2.0/24  # Replace with Web Tier CIDR 

# Outbound traffic to RDS (Assuming RDS uses port 3306 for MySQL)

aws ec2 authorize-security-group-egress --group-id $APP_SG_ID --protocol tcp --port 3306 --cidr 10.0.3.0/24 # Replace with Data Tier CIDR

aws ec2 authorize-security-group-egress --group-id $APP_SG_ID --protocol tcp --port 3306 --cidr 10.0.4.0/24 # Replace with Data Tier CIDR??        

  • Data Tier Security Group (RDS): Allows inbound traffic from the application tier only.

aws ec2 create-security-group --group-name data-tier-sg --description "Data Tier Security Group" --vpc-id $VPC_ID --output json

DATA_SG_ID="<YOUR_DATA_SG_ID>" # replace with the data tier sg id 

# Inbound traffic from Application Tier (Assuming RDS uses port 3306 for MySQL)

aws ec2 authorize-security-group-ingress --group-id $DATA_SG_ID --protocol tcp --port 3306 --cidr 10.0.3.0/24  # Replace with Application Tier CIDR

aws ec2 authorize-security-group-ingress --group-id $DATA_SG_ID --protocol tcp --port 3306 --cidr 10.0.4.0/24  # Replace with Application Tier CIDR???        

3. IAM Roles: Secure Access to AWS Services

IAM Roles grant permissions to your EC2 instances and Lambda functions to access other AWS services.

  • Create Roles for EC2 Instances: Use the AWS Management Console to create IAM roles with policies that allow instances to access services like S3, CloudWatch, etc. Avoid using access keys directly on your instances.
  • Create Roles for Lambda Functions: Similar to EC2 instances, create IAM roles for Lambda functions with necessary permissions.

4. EC2 Instances (Web & Application Tiers):

  • Launch EC2 Instances: Launch at least two EC2 instances in each public subnet (for the web tier) and private subnet (for the application tier) for high availability. Distribute them across Availability Zones.

???? # Example (Replace with your AMI ID, Instance Type, Key Pair, Subnet ID, Security Group ID)

aws ec2 run-instances --image-id ami-xxxxxxxxxxxxxxxxx --count 1 --instance-type t2.micro --key-name my-key-pair --subnet-id <YOUR_PUBLIC_SUBNET_ID_1> --security-group-ids $WEB_SG_ID --iam-instance-profile Name=<YOUR_EC2_INSTANCE_PROFILE_NAME>

aws ec2 run-instances --image-id ami-xxxxxxxxxxxxxxxxx --count 1 --instance-type t2.micro --key-name my-key-pair --subnet-id <YOUR_PUBLIC_SUBNET_ID_2> --security-group-ids $WEB_SG_ID --iam-instance-profile Name=<YOUR_EC2_INSTANCE_PROFILE_NAME> 

aws ec2 run-instances --image-id ami-xxxxxxxxxxxxxxxxx --count 1 --instance-type t2.micro --key-name my-key-pair --subnet-id <YOUR_PRIVATE_SUBNET_ID_1> --security-group-ids $APP_SG_ID --iam-instance-profile Name=<YOUR_EC2_INSTANCE_PROFILE_NAME>

aws ec2 run-instances --image-id ami-xxxxxxxxxxxxxxxxx --count 1 --instance-type t2.micro --key-name my-key-pair --subnet-id <YOUR_PRIVATE_SUBNET_ID_2> --security-group-ids $APP_SG_ID --iam-instance-profile Name=<YOUR_EC2_INSTANCE_PROFILE_NAME>???        

  • Configure Load Balancer (ELB): Distribute traffic across the web tier instances. Use Application Load Balancer (ALB) for HTTP/HTTPS traffic or Network Load Balancer (NLB) for TCP/UDP traffic.

# Create Target Group

aws elbv2 create-target-group --name web-target-group --protocol HTTP --port 80 --vpc-id $VPC_ID --target-type instance --output json 

TARGET_GROUP_ARN="<YOUR_TARGET_GROUP_ARN>"  # Replace with your target group ARN 

# Register Targets (EC2 Instances)

aws elbv2 register-targets --target-group-arn $TARGET_GROUP_ARN --targets Id=<YOUR_EC2_INSTANCE_ID_1> Id=<YOUR_EC2_INSTANCE_ID_2> 

# Create Load Balancer (ALB)

aws elbv2 create-load-balancer --name my-web-lb --subnets <YOUR_PUBLIC_SUBNET_ID_1> <YOUR_PUBLIC_SUBNET_ID_2> --security-groups $WEB_SG_ID --scheme internet-facing --output json 

LOAD_BALANCER_ARN="<YOUR_LOAD_BALANCER_ARN>"  # Replace with your load balancer ARN 

# Create Listener (HTTP)

aws elbv2 create-listener --load-balancer-arn $LOAD_BALANCER_ARN --protocol HTTP --port 80 --default-actions Type=forward,TargetGroupArn=$TARGET_GROUP_ARN 

# Get the load balancer DNS name

aws elbv2 describe-load-balancers --load-balancer-arns $LOAD_BALANCER_ARN --query "LoadBalancers[0].DNSName" --output text???        

  • Auto Scaling Group (ASG): Automatically scales the number of EC2 instances based on demand.

?# Create Launch Template

aws ec2 create-launch-template --launch-template-name my-launch-template --launch-template-data "ImageId=ami-xxxxxxxxxxxxxxxxx,InstanceType=t2.micro,KeyName=my-key-pair,SecurityGroupIds=[$WEB_SG_ID],IamInstanceProfile={Name=<YOUR_EC2_INSTANCE_PROFILE_NAME>}" --output json

LAUNCH_TEMPLATE_ID="<YOUR_LAUNCH_TEMPLATE_ID>"  # Replace with your launch template ID 

# Create Auto Scaling Group

aws autoscaling create-auto-scaling-group --auto-scaling-group-name my-asg --launch-template LaunchTemplateId=$LAUNCH_TEMPLATE_ID,Version=\$Default --min-size 2 --max-size 5 --desired-capacity 2 --vpc-zone-identifier <YOUR_PUBLIC_SUBNET_ID_1>,<YOUR_PUBLIC_SUBNET_ID_2> --target-group-arns $TARGET_GROUP_ARN???        

5. Lambda Functions (Optional - For APIs or Backend Processing):

  • Create Lambda Functions: Write your code and configure the necessary resources (memory, timeout, etc.).
  • API Gateway (If using Lambda for APIs): Create an API Gateway to expose your Lambda functions as APIs.
  • Configure IAM Roles: Grant the Lambda functions necessary permissions to access other AWS resources.

6. S3 Bucket (For Static Content and Data Storage):

  • Create an S3 Bucket:

aws s3api create-bucket --bucket my-unique-bucket-name --region us-east-1 

# Replace with your bucket name and region???        

  • Configure Bucket Policy: Restrict access to the bucket.

????? # Example Bucket Policy (Restrict access to only specific IAM role)

{

    "Version": "2012-10-17",

    "Statement": [

        {

            "Sid": "AllowSpecificIAMRole",

            "Effect": "Allow",

            "Principal": {

                "AWS": "arn:aws:iam::<YOUR_ACCOUNT_ID>:role/your-iam-role"

            },

            "Action": "s3:*",

            "Resource": "arn:aws:s3:::my-unique-bucket-name/*"

        },

        {

            "Sid": "DenyAllOthers",

            "Effect": "Deny",

            "Principal": "*",

            "Action": "s3:*",

            "NotResource": "arn:aws:s3:::my-unique-bucket-name/*",

            "Condition": {

                "StringNotEquals": {

                    "aws:userId": "<YOUR_ACCOUNT_ID>"

                }

            }

        }

    ]

}???        

  • Enable Versioning: Protect against accidental deletion or modification of data.
  • Enable Encryption: Encrypt data at rest and in transit. Use Server-Side Encryption with KMS (SSE-KMS) for enhanced security.

7. RDS Database (Data Tier):

  • Create an RDS Instance: Choose the appropriate database engine (MySQL, PostgreSQL, etc.) and instance size. Enable Multi-AZ for high availability.

# Example (Replace with your RDS Configuration)

aws rds create-db-instance --db-instance-identifier my-db-instance --db-instance-class db.t2.micro --engine mysql --master-username admin --master-user-password my-secret-password --allocated-storage 20 --vpc-security-group-ids $DATA_SG_ID --db-subnet-group-name my-db-subnet-group --multi-az true --engine-version 8.0 

#  Ensure you create DB Subnet Group first!

# aws rds create-db-subnet-group --db-subnet-group-name my-db-subnet-group --db-subnet-group-description "My DB Subnet Group" --subnet-ids <YOUR_PRIVATE_SUBNET_ID_1> <YOUR_PRIVATE_SUBNET_ID_2>???        

  • Configure Security Groups: Only allow inbound traffic from the application tier.
  • Enable Backups: Automated backups are crucial for data recovery.
  • Enable Encryption: Encrypt data at rest and in transit.
  • Parameter Groups: Configure database parameters for performance and security.

8. Resilience Considerations:

  • Multi-AZ Deployment (RDS): Provides automatic failover to a standby instance in another Availability Zone.
  • Auto Scaling Groups (EC2): Automatically replaces unhealthy or failed instances.
  • Load Balancing: Distributes traffic and provides fault tolerance.
  • Regular Backups: Enable automated backups for all critical services (RDS, S3, etc.).
  • Disaster Recovery Plan: Define a plan for recovering from regional outages (using services like AWS Backup, and CloudEndure Disaster Recovery).

9. Security Best Practices:

  • Principle of Least Privilege: Grant only the necessary permissions to IAM roles and security groups.
  • Regular Security Audits: Use AWS Trusted Advisor, AWS Inspector, and other tools to identify security vulnerabilities.
  • Patch Management: Keep your operating systems and applications up to date with the latest security patches.
  • Encryption: Encrypt data at rest and in transit.
  • Monitoring and Logging: Use CloudWatch and CloudTrail to monitor your infrastructure and detect security threats.
  • Network Access Control Lists (NACLs): Use NACLs for an additional layer of security at the subnet level.

10. Monitoring and Logging:

  • CloudWatch: Monitor metrics and set up alarms for performance and security issues.
  • CloudTrail: Log all API calls made to your AWS resources.
  • AWS Config: Track changes to your AWS resource configurations.
  • Centralized Logging: Use services like CloudWatch Logs or third-party logging solutions to collect and analyze logs from all your components.

Example Configuration (Illustrative):



Conclusion:

Building a secure and resilient 3-tier architecture on AWS requires careful planning and implementation. By following these steps and adhering to security best practices, you can create a robust foundation for your applications that can withstand attacks and outages. Remember to continuously monitor and improve your security posture and adapt your architecture as your application evolves. This blog provides a solid starting point; always consult the official AWS documentation and tailor the architecture to your specific requirements.

Remember to replace placeholder values like <YOUR_VPC_ID>, <YOUR_AMI_ID> etc. with your actual resource IDs and configurations. Good luck building your rock-solid AWS infrastructure!

?

Amit Mishra

progress to Cloud Architect

1 天前

Very informative

要查看或添加评论,请登录

Manish Kumar的更多文章