Building a Rock-Solid Foundation: A Secure and Resilient AWS Architecture for Your 3-Tier Project
Manish Kumar
Cloud & IT Infrastructure Consultant | Architecting Secure, Scalable Solutions for Digital Transformation
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:
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.
????? aws ec2 create-vpc --cidr-block 10.0.0.0/16 --query Vpc.VpcId --output text???
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???
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???
# 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???
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.
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???
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??
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.
4. EC2 Instances (Web & Application Tiers):
???? # 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>???
# 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???
?# 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):
6. S3 Bucket (For Static Content and Data Storage):
aws s3api create-bucket --bucket my-unique-bucket-name --region us-east-1
# Replace with your bucket name and region???
????? # 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>"
}
}
}
]
}???
7. RDS Database (Data Tier):
# 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>???
8. Resilience Considerations:
9. Security Best Practices:
10. Monitoring and Logging:
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!
?
progress to Cloud Architect
1 天前Very informative