#!/bin/bash

# A script to create a multi-tier VPC for a web application using AWS CLI.
# This sets up a VPC with one public subnet and two private subnets,
# an Internet Gateway for public traffic, and a NAT Gateway for private outbound traffic.

# --- Configuration ---
REGION="us-east-1"
VPC_CIDR="10.0.0.0/16"
PUBLIC_SUBNET_CIDR="10.0.1.0/24"
PRIVATE_SUBNET_APP_CIDR="10.0.2.0/24"
PRIVATE_SUBNET_DB_CIDR="10.0.3.0/24"
VPC_NAME="MyWebAppVPC"
AZ_1="${REGION}a"
AZ_2="${REGION}b"

# --- VPC Creation ---
echo "Creating VPC..."
VPC_ID=$(aws ec2 create-vpc \
  --cidr-block $VPC_CIDR \
  --region $REGION \
  --tag-specifications "ResourceType=vpc,Tags=[{Key=Name,Value=$VPC_NAME}]" \
  --query 'Vpc.VpcId' \
  --output text)
echo "VPC created with ID: $VPC_ID"

# --- Subnet Creation ---
echo "Creating subnets..."
PUBLIC_SUBNET_ID=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block $PUBLIC_SUBNET_CIDR \
  --availability-zone $AZ_1 \
  --region $REGION \
  --tag-specifications "ResourceType=subnet,Tags=[{Key=Name,Value=${VPC_NAME}-Public-Subnet}]" \
  --query 'Subnet.SubnetId' \
  --output text)
echo "Public Subnet created with ID: $PUBLIC_SUBNET_ID"

PRIVATE_SUBNET_APP_ID=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block $PRIVATE_SUBNET_APP_CIDR \
  --availability-zone $AZ_1 \
  --region $REGION \
  --tag-specifications "ResourceType=subnet,Tags=[{Key=Name,Value=${VPC_NAME}-Private-App-Subnet}]" \
  --query 'Subnet.SubnetId' \
  --output text)
echo "Private App Subnet created with ID: $PRIVATE_SUBNET_APP_ID"

PRIVATE_SUBNET_DB_ID=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block $PRIVATE_SUBNET_DB_CIDR \
  --availability-zone $AZ_2 \
  --region $REGION \
  --tag-specifications "ResourceType=subnet,Tags=[{Key=Name,Value=${VPC_NAME}-Private-DB-Subnet}]" \
  --query 'Subnet.SubnetId' \
  --output text)
echo "Private DB Subnet created with ID: $PRIVATE_SUBNET_DB_ID"

# --- Internet Gateway ---
echo "Creating and attaching Internet Gateway..."
IGW_ID=$(aws ec2 create-internet-gateway \
  --region $REGION \
  --tag-specifications "ResourceType=internet-gateway,Tags=[{Key=Name,Value=${VPC_NAME}-IGW}]" \
  --query 'InternetGateway.InternetGatewayId' \
  --output text)
aws ec2 attach-internet-gateway --vpc-id $VPC_ID --internet-gateway-id $IGW_ID --region $REGION
echo "Internet Gateway created and attached: $IGW_ID"

# --- NAT Gateway ---
echo "Creating NAT Gateway..."
EIP_ALLOC_ID=$(aws ec2 allocate-address --domain vpc --region $REGION --query 'AllocationId' --output text)
NAT_GW_ID=$(aws ec2 create-nat-gateway \
  --subnet-id $PUBLIC_SUBNET_ID \
  --allocation-id $EIP_ALLOC_ID \
  --region $REGION \
  --tag-specifications "ResourceType=nat-gateway,Tags=[{Key=Name,Value=${VPC_NAME}-NAT-GW}]" \
  --query 'NatGateway.NatGatewayId' \
  --output text)
echo "NAT Gateway created: $NAT_GW_ID. Waiting for it to become available..."
aws ec2 wait nat-gateway-available --nat-gateway-ids $NAT_GW_ID --region $REGION
echo "NAT Gateway is available."

# --- Route Tables ---
echo "Creating and configuring Route Tables..."
# Public Route Table
PUBLIC_RT_ID=$(aws ec2 create-route-table --vpc-id $VPC_ID --region $REGION --query 'RouteTable.RouteTableId' --output text)
aws ec2 create-route --route-table-id $PUBLIC_RT_ID --destination-cidr-block 0.0.0.0/0 --gateway-id $IGW_ID --region $REGION
aws ec2 associate-route-table --subnet-id $PUBLIC_SUBNET_ID --route-table-id $PUBLIC_RT_ID --region $REGION
aws ec2 create-tags --resources $PUBLIC_RT_ID --tags Key=Name,Value=${VPC_NAME}-Public-RT --region $REGION
echo "Public Route Table created and associated: $PUBLIC_RT_ID"

# Private Route Table
PRIVATE_RT_ID=$(aws ec2 create-route-table --vpc-id $VPC_ID --region $REGION --query 'RouteTable.RouteTableId' --output text)
aws ec2 create-route --route-table-id $PRIVATE_RT_ID --destination-cidr-block 0.0.0.0/0 --nat-gateway-id $NAT_GW_ID --region $REGION
aws ec2 associate-route-table --subnet-id $PRIVATE_SUBNET_APP_ID --route-table-id $PRIVATE_RT_ID --region $REGION
aws ec2 associate-route-table --subnet-id $PRIVATE_SUBNET_DB_ID --route-table-id $PRIVATE_RT_ID --region $REGION
aws ec2 create-tags --resources $PRIVATE_RT_ID --tags Key=Name,Value=${VPC_NAME}-Private-RT --region $REGION
echo "Private Route Table created and associated: $PRIVATE_RT_ID"

# --- Security Groups ---
echo "Creating Security Groups..."
# Web Tier SG
WEB_SG_ID=$(aws ec2 create-security-group --group-name "${VPC_NAME}-Web-SG" --description "Allow HTTP/HTTPS" --vpc-id $VPC_ID --region $REGION --query 'GroupId' --output text)
aws ec2 authorize-security-group-ingress --group-id $WEB_SG_ID --protocol tcp --port 80 --cidr 0.0.0.0/0 --region $REGION
aws ec2 authorize-security-group-ingress --group-id $WEB_SG_ID --protocol tcp --port 443 --cidr 0.0.0.0/0 --region $REGION
echo "Web Tier Security Group created: $WEB_SG_ID"

# App Tier SG
APP_SG_ID=$(aws ec2 create-security-group --group-name "${VPC_NAME}-App-SG" --description "Allow traffic from Web SG" --vpc-id $VPC_ID --region $REGION --query 'GroupId' --output text)
aws ec2 authorize-security-group-ingress --group-id $APP_SG_ID --protocol tcp --port 8080 --source-group $WEB_SG_ID --region $REGION
echo "App Tier Security Group created: $APP_SG_ID"

# DB Tier SG
DB_SG_ID=$(aws ec2 create-security-group --group-name "${VPC_NAME}-DB-SG" --description "Allow traffic from App SG" --vpc-id $VPC_ID --region $REGION --query 'GroupId' --output text)
aws ec2 authorize-security-group-ingress --group-id $DB_SG_ID --protocol tcp --port 3306 --source-group $APP_SG_ID --region $REGION
echo "DB Tier Security Group created: $DB_SG_ID"

echo "--- Multi-Tier VPC setup complete! ---"
echo "VPC ID: $VPC_ID"
echo "Public Subnet ID: $PUBLIC_SUBNET_ID"
echo "App Subnet ID: $PRIVATE_SUBNET_APP_ID"
echo "DB Subnet ID: $PRIVATE_SUBNET_DB_ID"
echo "Web SG ID: $WEB_SG_ID"
echo "App SG ID: $APP_SG_ID"
echo "DB SG ID: $DB_SG_ID"
