This is the final part of the AWS and Linux Combo series. We bring everything together — EC2, Linux, Nginx, S3, IAM, Bash scripting, and CloudWatch — into a complete, production-like deployment. By the end of this lesson, you will have a real application running in the cloud with monitoring, backups, and security configured properly.
We will deploy a static website with Nginx, backed by S3 for media storage, secured with proper IAM roles and Security Groups, with CloudWatch monitoring and automated daily backups. This is a real-world pattern used by thousands of teams for lightweight web applications and content sites.
# Create a security group
aws ec2 create-security-group --group-name webapp-sg --description "Web app security group"
# Add rules
aws ec2 authorize-security-group-ingress --group-name webapp-sg --protocol tcp --port 22 --cidr YOUR_IP/32
aws ec2 authorize-security-group-ingress --group-name webapp-sg --protocol tcp --port 80 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-name webapp-sg --protocol tcp --port 443 --cidr 0.0.0.0/0
# Launch instance with the security group
aws ec2 run-instances --image-id ami-0f58b397bc5c1f2e8 --instance-type t2.micro --key-name my-key --security-groups webapp-sg --iam-instance-profile Name=EC2-S3-Reader --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=webapp-server}]'
Create a setup script that automates the full server configuration:
#!/bin/bash
set -e # Exit on any error
echo "=== Starting server setup ==="
# Update system
sudo dnf update -y
# Install required packages
sudo dnf install -y nginx git awscli amazon-cloudwatch-agent
# Start and enable Nginx
sudo systemctl start nginx
sudo systemctl enable nginx
# Create web directory
sudo mkdir -p /var/www/webapp
sudo chown -R ec2-user:ec2-user /var/www/webapp
# Configure Nginx
sudo tee /etc/nginx/conf.d/webapp.conf > /dev/null <<EOF
server {
listen 80;
server_name _;
root /var/www/webapp;
index index.html;
location / {
try_files \$uri \$uri/ =404;
}
access_log /var/log/nginx/webapp_access.log;
error_log /var/log/nginx/webapp_error.log;
}
EOF
# Reload Nginx
sudo systemctl reload nginx
echo "=== Setup complete ==="
#!/bin/bash
BUCKET="my-srjahir-bucket-2026"
APP_DIR="/var/www/webapp"
DATE=$(date +%Y-%m-%d-%H%M)
echo "Deploying application..."
# Sync from S3 (pull latest files)
aws s3 sync "s3://${BUCKET}/webapp/" "${APP_DIR}/"
# Set correct permissions
chmod -R 644 ${APP_DIR}/*.html
find ${APP_DIR} -type d -exec chmod 755 {} \;
# Log deployment
echo "[${DATE}] Deployment successful" >> /var/log/deploys.log
echo "Deployment complete!"
# Edit crontab
crontab -e
# Add these jobs:
# Daily backup at 2 AM
0 2 * * * /home/ec2-user/scripts/daily-backup.sh
# Deploy latest from S3 every hour
0 * * * * /home/ec2-user/scripts/deploy.sh
# Health check every 5 minutes
*/5 * * * * /home/ec2-user/scripts/health-check.sh
# Create SNS topic
TOPIC_ARN=$(aws sns create-topic --name webapp-alerts --query TopicArn --output text)
# Subscribe email
aws sns subscribe --topic-arn $TOPIC_ARN --protocol email --notification-endpoint your@email.com
# CPU alarm
aws cloudwatch put-metric-alarm --alarm-name "webapp-high-cpu" --metric-name CPUUtilization --namespace AWS/EC2 --threshold 80 --comparison-operator GreaterThanThreshold --evaluation-periods 2 --period 300 --statistic Average --alarm-actions $TOPIC_ARN
# 1. Nginx running?
sudo systemctl status nginx
# 2. Website accessible?
curl -I http://YOUR_EC2_IP
# 3. S3 access working?
aws s3 ls s3://my-srjahir-bucket-2026/
# 4. CloudWatch receiving metrics?
aws cloudwatch list-metrics --namespace AWS/EC2
# 5. Backup script works?
/home/ec2-user/scripts/daily-backup.sh
# 6. Logs flowing?
tail -f /var/log/nginx/webapp_access.log
You now have a production-ready web application deployed on AWS EC2 with Linux. It has a proper web server with Nginx configured with virtual host. Storage with S3 for media and backups. Security via IAM roles and Security Groups. Automation via Bash scripts and cron. Monitoring via CloudWatch with email alerts. This is the foundation of real cloud infrastructure. Every enterprise cloud setup — no matter how complex — is built on these same fundamentals. Master these, and you can handle any cloud engineering challenge.
This completes the AWS and Linux Combo series. The skills you have built here — Linux administration, AWS services, scripting, security, and monitoring — are exactly what cloud engineers use every day in professional environments.
Moving an application from development to production on AWS requires attention to several dimensions beyond making it functional. High availability means running multiple instances across multiple Availability Zones behind a load balancer — no single point of failure. An Application Load Balancer (ALB) distributes traffic across instances, performs health checks, and automatically removes unhealthy instances from rotation. Auto Scaling Groups maintain the desired number of instances, replacing failed ones and scaling capacity based on load. For the database, use RDS Multi-AZ deployment — AWS automatically maintains a standby replica in a different AZ and fails over to it in seconds if the primary fails.
Running production workloads cost-effectively on AWS requires ongoing attention. Right-size instances based on actual utilization — AWS Compute Optimizer analyzes your usage patterns and recommends appropriate instance types. Use Reserved Instances or Savings Plans for predictable workloads — committing to 1 or 3 years of usage in exchange for 30-60% discounts over on-demand pricing. Use Spot Instances for fault-tolerant batch processing — 60-90% discounts in exchange for the possibility of interruption. Implement auto-scaling to match capacity to actual demand rather than provisioning for peak load at all times. Review your AWS Cost Explorer monthly and investigate any unexpected cost increases immediately.
Build a production-ready deployment of a web application on AWS: create a VPC with public and private subnets across two availability zones, deploy an Application Load Balancer in the public subnets, run your application on EC2 instances in an Auto Scaling Group in the private subnets, deploy an RDS database in the private subnets accessible only from the application instances, configure CloudWatch monitoring and alerting, and set up a deployment pipeline using CodeDeploy or GitHub Actions that deploys new versions with zero downtime. Document the architecture with a diagram and cost estimate. This project represents a production-grade AWS deployment and serves as a strong portfolio piece demonstrating real cloud engineering capability.