Last active
December 5, 2024 10:33
-
-
Save random-robbie/c68a9458844eb034bff80bed391cef55 to your computer and use it in GitHub Desktop.
Deploy your free EC2 via Bash
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Set error handling | |
set -e | |
# Variables | |
KEY_NAME="my-testing-key" | |
SECURITY_GROUP_NAME="pentesting-ssh" | |
INSTANCE_TYPE="t2.micro" | |
SSH_KEY_PATH="$HOME/.ssh/id_rsa.pub" # SSH key location | |
MAX_EBS_FREE_TIER=30 # GB | |
FREE_TIER_HOURS=750 # Monthly free tier hours | |
# Colors for output | |
RED='\033[0;31m' | |
GREEN='\033[0;32m' | |
YELLOW='\033[1;33m' | |
NC='\033[0m' # No Color | |
# Function to check free tier usage | |
check_free_tier() { | |
echo -e "${YELLOW}Checking free tier usage...${NC}" | |
# Get the current month's t2.micro usage | |
MONTH=$(date +%Y-%m) | |
# Get running hours for t2.micro instances this month | |
HOURS=$(aws ce get-cost-and-usage \ | |
--time-period Start=${MONTH}-01,End=$(date +%Y-%m-%d) \ | |
--granularity MONTHLY \ | |
--metrics UsageQuantity \ | |
--filter "{\"Dimensions\":{\"Key\":\"USAGE_TYPE\",\"Values\":[\"BoxUsage:t2.micro\"]}}" \ | |
--query 'ResultsByTime[0].Total.UsageQuantity.Amount' \ | |
--output text 2>/dev/null || echo "0") | |
HOURS=${HOURS%.*} # Remove decimal places | |
REMAINING_HOURS=$((FREE_TIER_HOURS - HOURS)) | |
echo -e "${GREEN}Free tier usage this month:${NC}" | |
echo -e "Used Hours: ${YELLOW}$HOURS${NC} / ${GREEN}$FREE_TIER_HOURS${NC}" | |
echo -e "Remaining Hours: ${GREEN}$REMAINING_HOURS${NC}" | |
if [ $REMAINING_HOURS -lt 100 ]; then | |
echo -e "${RED}Warning: Less than 100 free tier hours remaining!${NC}" | |
read -p "Do you want to continue? (y/n) " -n 1 -r | |
echo | |
if [[ ! $REPLY =~ ^[Yy]$ ]]; then | |
exit 1 | |
fi | |
fi | |
} | |
# Function to check if key pair exists | |
check_key_pair() { | |
echo -e "${YELLOW}Checking for existing key pair...${NC}" | |
# First check if the SSH key file exists | |
if [ ! -f "$SSH_KEY_PATH" ]; then | |
echo -e "${RED}Error: SSH key not found at $SSH_KEY_PATH${NC}" | |
exit 1 | |
fi | |
if aws ec2 describe-key-pairs --key-names "$KEY_NAME" 2>/dev/null; then | |
echo -e "${GREEN}Key pair $KEY_NAME already exists${NC}" | |
return 0 | |
else | |
echo -e "${YELLOW}Creating new key pair...${NC}" | |
aws ec2 import-key-pair \ | |
--key-name "$KEY_NAME" \ | |
--public-key-material fileb://"$SSH_KEY_PATH" | |
echo -e "${GREEN}Key pair created successfully${NC}" | |
fi | |
} | |
# Function to get latest Ubuntu AMI | |
get_ubuntu_ami() { | |
echo -e "${YELLOW}Getting latest Ubuntu AMI...${NC}" | |
AMI_ID=$(aws ec2 describe-images \ | |
--owners 099720109477 \ | |
--filters \ | |
"Name=name,Values=ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*" \ | |
"Name=virtualization-type,Values=hvm" \ | |
"Name=root-device-type,Values=ebs" \ | |
--query 'sort_by(Images, &CreationDate)[-1].ImageId' \ | |
--output text) | |
echo -e "${GREEN}Found Ubuntu AMI: $AMI_ID${NC}" | |
} | |
# Function to check and create security group | |
setup_security_group() { | |
echo -e "${YELLOW}Checking for existing security group...${NC}" | |
if aws ec2 describe-security-groups --group-names "$SECURITY_GROUP_NAME" 2>/dev/null; then | |
echo -e "${GREEN}Security group $SECURITY_GROUP_NAME already exists${NC}" | |
SECURITY_GROUP_ID=$(aws ec2 describe-security-groups --group-names "$SECURITY_GROUP_NAME" --query 'SecurityGroups[0].GroupId' --output text) | |
else | |
echo -e "${YELLOW}Creating new security group...${NC}" | |
SECURITY_GROUP_ID=$(aws ec2 create-security-group \ | |
--group-name "$SECURITY_GROUP_NAME" \ | |
--description "Security group for SSH access" \ | |
--query 'GroupId' --output text) | |
# Get current public IP | |
MY_IP=$(curl -s ifconfig.me) | |
echo -e "${YELLOW}Adding SSH rule for IP $MY_IP...${NC}" | |
aws ec2 authorize-security-group-ingress \ | |
--group-id "$SECURITY_GROUP_ID" \ | |
--protocol tcp \ | |
--port 22 \ | |
--cidr "$MY_IP/32" | |
echo -e "${GREEN}Security group created and configured successfully${NC}" | |
fi | |
} | |
# Function to launch EC2 instance | |
launch_instance() { | |
echo -e "${YELLOW}Checking for existing running instances...${NC}" | |
EXISTING_INSTANCES=$(aws ec2 describe-instances \ | |
--filters "Name=instance-state-name,Values=running" \ | |
--query 'Reservations[*].Instances[*].[InstanceId]' \ | |
--output text) | |
if [ ! -z "$EXISTING_INSTANCES" ]; then | |
echo -e "${RED}Warning: You already have running instances:${NC}" | |
echo "$EXISTING_INSTANCES" | |
read -p "Do you want to continue? (y/n) " -n 1 -r | |
echo | |
if [[ ! $REPLY =~ ^[Yy]$ ]]; then | |
exit 1 | |
fi | |
fi | |
echo -e "${YELLOW}Launching new EC2 instance...${NC}" | |
INSTANCE_ID=$(aws ec2 run-instances \ | |
--image-id "$AMI_ID" \ | |
--instance-type "$INSTANCE_TYPE" \ | |
--key-name "$KEY_NAME" \ | |
--security-group-ids "$SECURITY_GROUP_ID" \ | |
--query 'Instances[0].InstanceId' \ | |
--output text \ | |
--block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":30,"VolumeType":"gp3","DeleteOnTermination":true}}]' \ | |
--tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=PenTest-Instance}]") | |
echo -e "${GREEN}Instance $INSTANCE_ID launched successfully${NC}" | |
return 0 | |
} | |
# Function to wait for instance to be running and get its IP | |
wait_for_instance() { | |
echo -e "${YELLOW}Waiting for instance to be running...${NC}" | |
aws ec2 wait instance-running --instance-ids "$INSTANCE_ID" | |
echo -e "${YELLOW}Waiting for system status checks...${NC}" | |
while true; do | |
STATUS=$(aws ec2 describe-instance-status \ | |
--instance-ids "$INSTANCE_ID" \ | |
--query 'InstanceStatuses[0].SystemStatus.Status' \ | |
--output text) | |
if [ "$STATUS" = "ok" ]; then | |
break | |
fi | |
echo -n "." | |
sleep 5 | |
done | |
echo | |
PUBLIC_IP=$(aws ec2 describe-instances \ | |
--instance-ids "$INSTANCE_ID" \ | |
--query 'Reservations[0].Instances[0].PublicIpAddress' \ | |
--output text) | |
echo -e "${GREEN}Instance is now fully running and accessible!${NC}" | |
echo -e "${GREEN}Instance ID: $INSTANCE_ID${NC}" | |
echo -e "${GREEN}Public IP: $PUBLIC_IP${NC}" | |
# Test SSH connectivity | |
echo -e "${YELLOW}Testing SSH connectivity...${NC}" | |
until nc -zv $PUBLIC_IP 22 2>/dev/null; do | |
echo -n "." | |
sleep 2 | |
done | |
echo -e "${GREEN}SSH port is now accessible!${NC}" | |
echo -e "${YELLOW}Connect using: ssh -i ${SSH_KEY_PATH%.*} ubuntu@$PUBLIC_IP${NC}" | |
} | |
# Function to monitor EBS volumes | |
check_ebs_volumes() { | |
echo -e "${YELLOW}Checking EBS volumes...${NC}" | |
TOTAL_EBS=$(aws ec2 describe-volumes \ | |
--query 'Volumes[*].Size' \ | |
--output text | tr '\t' '+' | bc) | |
echo -e "Total EBS storage: ${YELLOW}${TOTAL_EBS}GB${NC} / ${GREEN}${MAX_EBS_FREE_TIER}GB${NC} free tier limit" | |
if [ $TOTAL_EBS -gt $MAX_EBS_FREE_TIER ]; then | |
echo -e "${RED}Warning: Total EBS storage exceeds free tier limit!${NC}" | |
fi | |
} | |
# Main execution | |
echo -e "${YELLOW}Starting EC2 deployment script...${NC}" | |
# Check free tier usage first | |
check_free_tier | |
# Get latest Ubuntu AMI | |
get_ubuntu_ami | |
# Run all functions | |
check_key_pair | |
setup_security_group | |
launch_instance | |
wait_for_instance | |
check_ebs_volumes | |
echo -e "${GREEN}Setup completed successfully!${NC}" | |
echo -e "${YELLOW}Remember to terminate the instance when done to stay within free tier limits${NC}" | |
echo -e "${YELLOW}You can terminate using: aws ec2 terminate-instances --instance-ids $INSTANCE_ID${NC}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment