This project provides an automated solution for monitoring the health of AWS EC2 instances using Ansible. It collects various system metrics and sends detailed reports via email, helping system administrators keep track of their infrastructure's health status.
Monitor_VM_Health/
├── ansible.cfg # Ansible configuration file
├── playbook.yaml # Main playbook that orchestrates the monitoring flow
├── collect_metrics.yaml # Playbook for collecting VM metrics
├── send_report.yaml # Playbook for generating and sending email reports
├── group_vars/
│ └── all.yaml # Global variables configuration
├── inventory/
│ └── aws_ec2.yaml # AWS EC2 dynamic inventory configuration
└── templates/
└── report_email.html.j2 # Email report template in HTML format
- 📊 Real-time system metrics collection
- 🔄 Dynamic AWS EC2 instance discovery
- 📧 Automated HTML email reports
- 📈 Performance monitoring and alerting
- 🎯 Customizable metrics and thresholds
Connect to the Ansible master node using SSH.
# Update the system
sudo apt update && sudo apt upgrade -y
# Add Ansible PPA (for latest versions)
sudo add-apt-repository --yes --update ppa:ansible/ansible
# Install Ansible
sudo apt install ansible -y
# Install AWS CLI
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
sudo apt install unzip
unzip awscliv2.zip
sudo ./aws/install
aws configureCreate a script (rename_instances.sh) to automatically rename EC2 instances:
#!/bin/bash
# Fetch instance IDs that match Environment=dev and Role=web
instance_ids=$(aws ec2 describe-instances \
--filters "Name=tag:Environment,Values=dev" "Name=instance-state-name,Values=running" \
--query 'Reservations[*].Instances[*].InstanceId' \
--output text)
# Sort instance IDs deterministically
sorted_ids=($(echo "$instance_ids" | tr '\t' '\n' | sort))
# Rename instances sequentially
counter=1
for id in "${sorted_ids[@]}"; do
name="web-$(printf "%02d" $counter)"
echo "Tagging $id as $name"
aws ec2 create-tags --resources "$id" \
--tags Key=Name,Value="$name"
((counter++))
done# Create public and private key pair for connecting with managed nodes
ssh-keygen -t rsa -b 4096 -C "Ansible-Master"Create a file at inventory/aws_ec2.yaml with the following content:
# Dynamic Inventory Configuration
plugin: amazon.aws.aws_ec2
regions:
- ap-south-1
filters:
tag:Environment: dev
instance-state-name: running
compose:
ansible_host: public_ip_address
keyed_groups:
- key: tags.Name
prefix: name
- key: tags.Environment
prefix: env# Install venv module if not already present
sudo apt install python3-venv -y
# Create a virtual environment
python3 -m venv ansible-env
# Activate it
source ansible-env/bin/activate# Install required Python packages
pip install boto3 botocore docker# Test the dynamic inventory configuration
ansible-inventory -i inventory/aws_ec2.yaml --graphCopy the private key of the instance inside the ansible-env directory:
# Create private key with same name and paste content
cp /path/to/your/private/key ansible-env/give permission to file
sudo chmod +x mykey.pem
and execute the file
./mykey.pem
Create a script (copy-public-key.sh) to distribute your SSH public key to all instances:
#!/bin/bash
# Define variables
PEM_FILE="mykey.pem"
PUB_KEY=$(cat ~/.ssh/id_rsa.pub)
USER="ubuntu" # or ec2-user for Amazon Linux
INVENTORY_FILE="inventory/aws_ec2.yaml"
# Extract hostnames/IPs from dynamic inventory
HOSTS=$(ansible-inventory -i $INVENTORY_FILE --list | jq -r '._meta.hostvars | keys[]')
# Distribute SSH key to all hosts
for HOST in $HOSTS; do
echo "Injecting key into $HOST"
ssh -o StrictHostKeyChecking=no -i $PEM_FILE $USER@$HOST "
mkdir -p ~/.ssh && \
echo \"$PUB_KEY\" >> ~/.ssh/authorized_keys && \
chmod 700 ~/.ssh && \
chmod 600 ~/.ssh/authorized_keys
"
doneMake the script executable:
sudo chmod +x copy-public-key.shNote: This script automatically handles SSH host key checking, eliminating the need to manually respond to yes/no prompts for each instance. So we will disable this option or force to connect. By this script" [defaults] inventory = ./inventory/aws_ec2.yaml host_key_checking = False [ssh_connection] ssh_args = -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
ansible-playbook playbook.yaml