Skip to content

Instantly share code, notes, and snippets.

@random-robbie
Last active December 5, 2024 10:33
Show Gist options
  • Save random-robbie/c68a9458844eb034bff80bed391cef55 to your computer and use it in GitHub Desktop.
Save random-robbie/c68a9458844eb034bff80bed391cef55 to your computer and use it in GitHub Desktop.
Deploy your free EC2 via Bash
#!/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