<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Harshil Thummar</title>
    <description>The latest articles on DEV Community by Harshil Thummar (@harshil_thummar).</description>
    <link>https://dev.to/harshil_thummar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3052419%2Fa8964ae8-0e40-4fe3-a5b6-a2a44c88d573.jpg</url>
      <title>DEV Community: Harshil Thummar</title>
      <link>https://dev.to/harshil_thummar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/harshil_thummar"/>
    <language>en</language>
    <item>
      <title>🛡️ Enforcing Auto Logout for Idle Bash Sessions on Ubuntu</title>
      <dc:creator>Harshil Thummar</dc:creator>
      <pubDate>Mon, 25 Aug 2025 12:35:23 +0000</pubDate>
      <link>https://dev.to/harshil_thummar/enforcing-auto-logout-for-idle-bash-sessions-on-ubuntu-309o</link>
      <guid>https://dev.to/harshil_thummar/enforcing-auto-logout-for-idle-bash-sessions-on-ubuntu-309o</guid>
      <description>&lt;p&gt;Idle shell sessions pose a significant risk on shared or multi-user systems. Unattended terminals can become an easy target for unauthorized access or accidental command execution. Fortunately, with a simple configuration tweak, you can automatically log out users after a defined period of inactivity — adding an extra layer of security to your Ubuntu system.&lt;/p&gt;

&lt;p&gt;In this guide, we’ll walk through how to enforce automatic logout in Bash by setting the (TMOUT) environment variable—and crucially, how to make sure users cannot override it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Objectives&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To configure Ubuntu systems running the Bash shell to automatically log out idle sessions after a specified time and prevent users from disabling or modifying this behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Environment&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Operating System: Ubuntu (also applies to most Linux systems using Bash)&lt;/li&gt;
&lt;li&gt;User Privileges: Root or sudo access required&lt;/li&gt;
&lt;li&gt;Shell: Bash (/bin/bash)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Implementation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Step 1: Edit the Global Bash Configuration&lt;br&gt;
We’ll begin by setting a global TMOUT value in /etc/bash.bashrc, which applies to all interactive non-login Bash shells.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open the file in a text editor with elevated privileges:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;sudo nano /etc/bash.bashrc&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Scroll to the bottom and add the following lines:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;# Enforce TMOUT for all users&lt;br&gt;
readonly TMOUT=300 # 5 minutes&lt;br&gt;
export TMOUT&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Pro Tip: For testing, you can use TMOUT=20 for a quicker timeout.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Save and exit:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Press Ctrl + O, then Enter to save&lt;/p&gt;

&lt;p&gt;Press Ctrl + X to close the editor&lt;/p&gt;

&lt;p&gt;Step 2: Apply the Configuration&lt;/p&gt;

&lt;p&gt;To apply the new settings, simply open a new terminal window or run:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;source /etc/bash.bashrc&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Step 3: Verify the Setting&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Confirm the TMOUT Value:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;echo $TMOUT&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Expected output:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;300&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Try to Override:&lt;/p&gt;

&lt;p&gt;Attempt to change the value:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;export TMOUT=100&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bash: TMOUT: readonly variable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This confirms that the setting is enforced and protected from user tampering.&lt;/p&gt;

&lt;p&gt;Step 4: Test the Auto Logout&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open a new terminal window.&lt;/li&gt;
&lt;li&gt;Leave it idle—don’t touch the keyboard or mouse.&lt;/li&gt;
&lt;li&gt;After 300 seconds (or 20 seconds, if you’re testing), you should see a message like:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;timed out waiting for input: auto-logout
logout
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj9iemuarsh6nqu2b4e68.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj9iemuarsh6nqu2b4e68.webp" alt=" " width="396" height="97"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Additional Notes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This method enforces the timeout in interactive non-login shells (e.g., terminals launched from a GUI).&lt;/p&gt;

&lt;p&gt;To enforce the same behavior in login shells (such as SSH sessions), add the same lines to /etc/profile.&lt;/p&gt;

&lt;p&gt;Be aware: users with sudo or root access can still edit these files. For high-security environments, consider more advanced restrictions like mandatory access controls (e.g., SELinux or AppArmor).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Security isn’t just about firewalls and permissions—it’s also about reducing surface area. Auto-logout is a small but powerful way to tighten system access control and reduce the risk of unauthorized activity. Whether you’re managing a multi-user lab, a development server, or your personal workstation, enabling (TMOUT) is a no-brainer.&lt;/p&gt;

&lt;p&gt;Thanks for reading! If you found this guide helpful, feel free to share or leave a comment below.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>bash</category>
      <category>ubuntu</category>
      <category>devops</category>
    </item>
    <item>
      <title>Amazon Elastic Kubernetes Service (AWS EKS) Auto Mode</title>
      <dc:creator>Harshil Thummar</dc:creator>
      <pubDate>Mon, 25 Aug 2025 12:26:44 +0000</pubDate>
      <link>https://dev.to/harshil_thummar/amazon-elastic-kubernetes-service-aws-eks-auto-mode-11ea</link>
      <guid>https://dev.to/harshil_thummar/amazon-elastic-kubernetes-service-aws-eks-auto-mode-11ea</guid>
      <description>&lt;p&gt;AWS announced during AWS re:Invent 2024, introducing a significant advancement in Kubernetes cluster management, targeting simplicity and scalability, named AWS EKS Auto Mode. This feature focuses on reducing the operational overhead traditionally associated with Kubernetes cluster lifecycle management, such as provisioning, scaling, and upgrading.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is AWS EKS Auto Mode?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This mode automates key management tasks related to Kubernetes node groups, making it easier for users to operate their Kubernetes workloads without needing to manage each aspect of the infrastructure manually. The goal is to help users save time and reduce operational complexity by automating certain aspects of cluster management.&lt;/p&gt;

&lt;p&gt;AWS EKS Auto Mode is designed for teams aiming to focus on their application workloads rather than infrastructure management. When using Auto Mode, EKS abstracts the complexities of managing the Kubernetes control plane and automatically provisions a fully managed environment. This allows users to deploy containerized applications without worrying about the underlying Kubernetes configuration or node setup. This can be enabled in any EKS cluster (1.29) and above with no additional charges.&lt;/p&gt;

&lt;p&gt;AWS EKS Auto Mode streamlines the operation of your Amazon EKS clusters by automating key infrastructure components such as compute, nodes, auto-scaling, load balancing, storage, networking, etc. Enabling EKS Auto Mode further reduces the tasks to manage your EKS clusters. Click here for more detail: &lt;a href="https://docs.aws.amazon.com/eks/latest/userguide/automode.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/eks/latest/userguide/automode.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, in EKS Control Plane, AWS will configure, manage, and secure the AWS infrastructure in EKS clusters that your applications need to run. Basically, AWS EKS Auto Mode is now available in all AWS regions except China.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc3059i42cfwu5g4w5mu1.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc3059i42cfwu5g4w5mu1.webp" alt=" " width="720" height="754"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Automated Node Scaling: EKS automatically adjusts the number of worker nodes in your node groups based on the resource requirements of your Kubernetes workloads (pods).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Managed Node Groups: EKS takes care of node provisioning, configuration, and lifecycle management (including updates and patches). You don’t need to manually configure individual EC2 instances for your worker nodes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Seamless Integration with EC2 Auto Scaling: EKS Managed Node Groups are backed by EC2 Auto Scaling Groups (ASG), which automatically adjust the number of EC2 instances in the group based on the workload demands, with settings for minimum, maximum, and desired node counts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Flexibility in Instance Types: You can configure your EKS node groups to use multiple EC2 instance types (e.g., t3.medium, m5.large, etc.), enabling cost optimization by choosing the best instances for different workloads. EKS also allows you to use Spot Instances in your node groups, which can help reduce costs by leveraging unused EC2 capacity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enhanced Security with IAM Roles: EKS provides built-in support for associating IAM roles with your nodes. This allows nodes to securely access AWS resources (such as S3, DynamoDB, etc.) and Kubernetes services with fine-grained access control.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Simplified Cost Management: By using Auto Scaling and Spot Instances, you can optimize your costs based on demand. The ability to select the right instance type for different workloads can help you strike a balance between performance and cost.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Important Links &amp;amp; References:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Streamline Kubernetes cluster management with new Amazon EKS Auto Mode:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/blogs/aws/streamline-kubernetes-cluster-management-with-new-amazon-eks-auto-mode/?trk=d57158fd-77e3-423f-9e1e-005fd2a64d89&amp;amp;sc_channel=el" rel="noopener noreferrer"&gt;https://aws.amazon.com/blogs/aws/streamline-kubernetes-cluster-management-with-new-amazon-eks-auto-mode/?trk=d57158fd-77e3-423f-9e1e-005fd2a64d89&amp;amp;sc_channel=el&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Checkout all EKS Auto mode features on AWS doc:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/about-aws/whats-new/2024/12/amazon-eks-auto-mode/" rel="noopener noreferrer"&gt;https://aws.amazon.com/about-aws/whats-new/2024/12/amazon-eks-auto-mode/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To learn more about how EKS Auto Mode can accelerate your time to deploy workloads to production, click here for more detail:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws-experience.com/emea/smb/events/series/simplifying-kubernetes-operations-with-amazon-eks-auto-mode" rel="noopener noreferrer"&gt;https://aws-experience.com/emea/smb/events/series/simplifying-kubernetes-operations-with-amazon-eks-auto-mode&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>AWS Security Group Change Monitoring with Slack Alerts</title>
      <dc:creator>Harshil Thummar</dc:creator>
      <pubDate>Mon, 25 Aug 2025 12:21:34 +0000</pubDate>
      <link>https://dev.to/harshil_thummar/aws-security-group-change-monitoring-with-slack-alerts-36b3</link>
      <guid>https://dev.to/harshil_thummar/aws-security-group-change-monitoring-with-slack-alerts-36b3</guid>
      <description>&lt;p&gt;This project is designed to monitor AWS Security Group changes and send Slack alerts when changes are detected. It uses AWS CloudTrail logs to track security group changes and Python to process these logs. The Python script runs as a systemd service on an EC2 instance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Objectives&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monitor AWS Security Group changes.&lt;/li&gt;
&lt;li&gt;Send Slack notifications when changes are detected.&lt;/li&gt;
&lt;li&gt;Run a Python script as a systemd service on an EC2 instance.&lt;/li&gt;
&lt;li&gt;Able to run automatically for changes using CloudTrail logs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Implementation Steps&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Enable CloudTrail&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;-- Sign in to the AWS Management Console.&lt;br&gt;
-- Go to the CloudTrail service.&lt;br&gt;
-- Create or use an existing trail.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The trail must track Management Events (not just data events).&lt;/li&gt;
&lt;li&gt;Ensure “Read/Write events” includes Write-only or All.&lt;/li&gt;
&lt;li&gt;Enable the trial for all regions (recommended).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;-- Save the trail.&lt;/p&gt;

&lt;p&gt;CloudTrail is required for tracking security group changes such as AuthorizeSecurityGroupIngress, RevokeSecurityGroupEgress, etc.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Prepare the EC2 Instance&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;-- Launch an Ubuntu EC2 instance (or any Linux-based instance).&lt;br&gt;
-- Ensure the instance has internet access (for Slack webhook).&lt;br&gt;
-- Update system packages:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt install -y python3-pip&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
-- Install Python libraries from requirements.txt:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install -r requirements.txt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;-- Also, do not forget to create your AWS profile using the access key and secret key in your server.&lt;br&gt;
-- Python boto3 library will automatically detect the profile to scan the aws account based on the configured profile.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Create IAM Role&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;-- Go to IAM &amp;gt; Roles.&lt;br&gt;
-- Click Create Role.&lt;br&gt;
-- Select EC2 as the trusted entity type.&lt;br&gt;
-- Attach the following custom policy to the role:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeSecurityGroups",
        "cloudtrail:LookupEvents"
      ],
      "Resource": "*"
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;-- Name the role: SecurityGroupMonitorRole.&lt;br&gt;
-- Attach this role to your EC2 instance.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Create the Python Script&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;-- Create the script ‘sg-monitoring.py’ that checks for security group changes using CloudTrail logs and sends Slack alerts.&lt;br&gt;
-- Note: 🔁 You can include “while True:” to run continuously every 5 minutes at the end of the code.&lt;br&gt;
-- If you’re creating the service in systemd (GONNA PERFORM THE 5th STEP), kindly ignore adding the “while true:” at the end of the code.&lt;br&gt;
-- IMPORTANT: Create your slack channel and generate the ‘Webhook’ for the same and mention it in the script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import boto3
import json
import hashlib
import os
import requests
import pytz
from datetime import datetime, timedelta

#Slack
WEBHOOK_URL = '&amp;lt;WEBHOOK_URL&amp;gt;'

# File to track and store the last state of security group
HASH_FILE = '/home/ubuntu/sg_snapshot.hash'

# AWS settings
REGION = '&amp;lt;REGION&amp;gt;'

def get_security_groups():
    session = boto3.Session()  # Removed profile_name
    ec2 = session.client('ec2', region_name=REGION)
    response = ec2.describe_security_groups()

    # Extract only relevant rule information
    filtered_sgs = []
    for sg in response['SecurityGroups']:
        filtered_sgs.append({
            'GroupId': sg['GroupId'],
            'GroupName': sg['GroupName'],
            'IpPermissions': sg.get('IpPermissions', []),
            'IpPermissionsEgress': sg.get('IpPermissionsEgress', [])
        })

    # Sort keys to make hash consistent
    sg_data = json.dumps(filtered_sgs, sort_keys=True)
    return sg_data

def get_hash(data):
    return hashlib.md5(data.encode('utf-8')).hexdigest()

def get_recent_sg_events():
    session = boto3.Session()  # Removed profile_name
    cloudtrail = session.client('cloudtrail', region_name=REGION)

    now = datetime.utcnow()
    start_time = now - timedelta(minutes=10)  # Check last 10 minutes of activity

    event_names = [
        'AuthorizeSecurityGroupIngress',
        'RevokeSecurityGroupIngress',
        'AuthorizeSecurityGroupEgress',
        'RevokeSecurityGroupEgress',
        'UpdateSecurityGroupRuleDescriptionsIngress',
        'UpdateSecurityGroupRuleDescriptionsEgress',
        'ModifySecurityGroupRules'
    ]

    events = []
    for event_name in event_names:
        response = cloudtrail.lookup_events(
            LookupAttributes=[{'AttributeKey': 'EventName', 'AttributeValue': event_name}],
            StartTime=start_time,
            EndTime=now,
            MaxResults=5
        )
        for event in response['Events']:
            evt = json.loads(event['CloudTrailEvent'])
            user = evt.get('userIdentity', {}).get('arn', 'Unknown')
            ip = evt.get('sourceIPAddress', 'Unknown')
            changes = evt.get('requestParameters', {})
            events.append({
                'eventName': event_name,
                'user': user,
                'ip': ip,
                'changes': changes,
                'time': event['EventTime'].strftime('%Y-%m-%d %H:%M:%S UTC')
            })
    return events

def send_alert(message):
    payload = {"text": message}  # Slack expects "text" instead of "content"
    headers = {'Content-Type': 'application/json'}
    response = requests.post(WEBHOOK_URL, data=json.dumps(payload), headers=headers)
    print(f"Notification sent to Slack: {response.status_code} - {response.text}")

def format_event_summary(events):
    if not events:
        return ":warning: No recent changes to security groups detected."

    lines = [":mag: *Details are as below:*\n"]

    # Define IST timezone
    IST = pytz.timezone('Asia/Kolkata')

    for evt in events:
        changes = evt.get('changes', {})
        event_name = evt['eventName']

        # Convert UTC time to IST
        event_time_utc = evt['time']
        event_time_utc = datetime.strptime(event_time_utc, "%Y-%m-%d %H:%M:%S UTC")
        event_time_ist = event_time_utc.replace(tzinfo=pytz.utc).astimezone(IST)
        formatted_time = event_time_ist.strftime("%Y-%m-%d %H:%M:%S IST")

        # ✅ Updated Event Type Handling
        if event_name == 'ModifySecurityGroupRules':
            emoji = ":wrench:"  # 🔧 Rule modified
            action = "Rule Modified"
        elif event_name.startswith('Authorize') or event_name.startswith('Update'):
            emoji = ":white_check_mark:"  # ✅ Rule added/updated
            action = "Rule Added/Updated"
        elif event_name.startswith('Revoke'):
            emoji = ":x:"  # ❌ Rule deleted
            action = "Rule Removed"
        else:
            emoji = ":grey_question:"
            action = event_name

        lines.append(f"{emoji} **{action}** at `{formatted_time}`")
        lines.append(f"  - User: `{evt.get('user', 'Unknown')}`")
        lines.append(f"  - IP: `{evt.get('ip', 'Unknown')}`")

        # ModifySecurityGroupRules structure is different
        if event_name == 'ModifySecurityGroupRules':
            modify_req = changes.get('ModifySecurityGroupRulesRequest', {})
            group_id = modify_req.get('GroupId', 'Unknown')
            lines.append(f"  - Group ID: `{group_id}`")

            rule = modify_req.get('SecurityGroupRule', {}).get('SecurityGroupRule', {})
            proto = rule.get('IpProtocol', 'any')
            from_port = rule.get('FromPort', 'all')
            to_port = rule.get('ToPort', 'all')
            cidr = rule.get('CidrIpv4', 'N/A')
            desc = rule.get('Description', '—')

            lines.append(f"    - Protocol: `{proto}` | Ports: `{from_port}` - `{to_port}`")
            lines.append(f"    - CIDR: `{cidr}` | Desc: _{desc}_")

        else:
            group_id = changes.get('groupId', 'Unknown')
            lines.append(f"  - Group ID: `{group_id}`")

            ip_permissions = changes.get('ipPermissions', {}).get('items', [])
            if ip_permissions:
                for perm in ip_permissions:
                    proto = perm.get('ipProtocol', 'any')
                    from_port = perm.get('fromPort', 'all')
                    to_port = perm.get('toPort', 'all')
                    lines.append(f"    - Protocol: `{proto}` | Ports: `{from_port}` - `{to_port}`")

                    for ip_range in perm.get('ipRanges', {}).get('items', []):
                        cidr = ip_range.get('cidrIp', 'N/A')
                        desc = ip_range.get('description', '—')
                        lines.append(f"      - CIDR: `{cidr}` | Desc: _{desc}_")
            else:
                lines.append("    - No IP permissions found.")

        lines.append("\n")  # Spacing between entries

    # Add a separator line at the end for easy differentiation
    lines.append("\n" + "="*40 + "\n")  # 40 dashes for separation

    return "\n".join(lines)

def main():
    sg_data = get_security_groups()
    current_hash = get_hash(sg_data)

    if os.path.exists(HASH_FILE):
        with open(HASH_FILE, 'r') as f:
            old_hash = f.read().strip()
    else:
        old_hash = None

    if old_hash != current_hash:
        print("Security Group change detected. Checking CloudTrail for events...")
        events = get_recent_sg_events()

        if events:
            event_summary = format_event_summary(events)
            send_alert(f"⚠️  AWS Security Group Change Detected!\n\n{event_summary}")
        else:
            print("Hash changed, but no CloudTrail events found. Skipping alert.")

        # ✅ Always update hash to avoid duplicate alerts
        with open(HASH_FILE, 'w') as f:
            f.write(current_hash)
    else:
        print("No changes in Security Groups.")

if __name__ == "__main__":
    main()
if __name__ == "__main__":
    while True:
        main()
        time.sleep(300)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Create systemd Service&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;-- Create file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo nano /etc/systemd/system/sg-monitoring.service&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#Please take care of the given paths. 
[Unit]
Description=AWS Security Group Monitoring Service
After=network.target

[Service]
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu/sg-monitoring
Environment="PATH=/home/ubuntu/sg-monitoring/sg-venv/bin"
ExecStart=/home/ubuntu/sg-monitoring/sg-venv/bin/python /home/ubuntu/sg-monitoring/sg-monitoring.py

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NOTE: If you’re not using ‘while True’ in the script, then you must create a ‘.timer’ file in systemd to run the service continuously.&lt;/p&gt;

&lt;p&gt;-- Once you create the service file, run the commands given below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo chmod 644 /etc/systemd/system/sg-monitoring.service
sudo systemctl daemon-reload
sudo systemctl enable sg-monitoring.service
sudo systemctl start sg-monitoring.service
sudo systemctl status sg-monitoring.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Create systemd Timer for Service&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;-- Create file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo nano /etc/systemd/system/sg-monitoring.timer&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Unit]
Description=AWS Security Group Monitoring Timer
Requires=sg-monitoring.service

[Timer]
OnBootSec=60
OnUnitActiveSec=60
Unit=sg-monitoring.service
Persistent=true

[Install]
WantedBy=timers.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;-- Once you create the service file, run the commands given below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo chmod 644 /etc/systemd/system/sg-monitoring.timer
sudo systemctl daemon-reload
sudo systemctl enable sg-monitoring.timer
sudo systemctl start sg-monitoring.timer
sudo systemctl status sg-monitoring.timer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;-- Verify Timer Schedule&lt;/p&gt;

&lt;p&gt;&lt;code&gt;systemctl list-timers&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;-- Now you can modify the security group and run the script. You will be able to get alert notifications in the Slack channel.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;python3 sg-monitoring.py&lt;/code&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>security</category>
      <category>monitoring</category>
      <category>devops</category>
    </item>
    <item>
      <title>Understanding AWS Global Accelerator: How It Routes Traffic Through a Private Network for Faster Performance</title>
      <dc:creator>Harshil Thummar</dc:creator>
      <pubDate>Tue, 06 May 2025 05:56:37 +0000</pubDate>
      <link>https://dev.to/harshil_thummar/understanding-aws-global-accelerator-how-it-routes-traffic-through-a-private-network-for-faster-5ej</link>
      <guid>https://dev.to/harshil_thummar/understanding-aws-global-accelerator-how-it-routes-traffic-through-a-private-network-for-faster-5ej</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4rneu811sbq7hfwtastu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4rneu811sbq7hfwtastu.png" alt="AWS Global Accelerator" width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In today's world of highly distributed applications, performance, reliability, and low latency are critical for providing a seamless user experience. For businesses operating globally, ensuring that their applications are fast and responsive no matter where their users are located is a major challenge. This is where AWS Global Accelerator comes into play.&lt;/p&gt;

&lt;p&gt;In this article, we'll explore how AWS Global Accelerator works, specifically how it routes traffic through AWS's private global network and how it helps you deliver faster and more reliable experiences for your users, even when they are located far from your application's origin.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is AWS Global Accelerator?
&lt;/h2&gt;

&lt;p&gt;AWS Global Accelerator is a service that improves the availability and performance of your global applications by routing traffic through AWS's vast network of edge locations. It works by directing user traffic to the optimal endpoint, typically based on the lowest latency, best network health, and other performance factors.&lt;/p&gt;

&lt;p&gt;Unlike traditional load balancers, which only distribute traffic within a specific region, AWS Global Accelerator is designed to operate on a global scale, ensuring that requests are routed to the best-performing AWS region or endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Role of Edge Locations and AWS's Private Network
&lt;/h2&gt;

&lt;p&gt;A key feature of AWS Global Accelerator is its use of AWS edge locations - the same infrastructure that powers AWS CloudFront, AWS's Content Delivery Network (CDN). These edge locations are spread across the globe, allowing users from virtually any location to access applications with minimal latency.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F472uxchx53oit3q38ch3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F472uxchx53oit3q38ch3.png" alt="Edge Locations" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When a user makes a request, the traffic doesn't just travel over the public internet to your origin server. Instead, AWS Global Accelerator leverages AWS's private global network to route the traffic. This private network is faster, more reliable, and more secure than the public internet, significantly improving performance and reducing the chances of packet loss or other network issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Global Accelerator Routes Traffic
&lt;/h2&gt;

&lt;p&gt;Let's consider a scenario to better understand how this routing works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your EC2 Instance is in Mumbai: Suppose you have an EC2 instance running in the Mumbai region (ap-south-1).&lt;/li&gt;
&lt;li&gt;A User is in US-East-1: A user in US-East-1 (N. Virginia) wants to access your application hosted on the Mumbai-based EC2 instance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without AWS Global Accelerator, the request from the user would have to traverse the public internet, which could involve multiple ISPs, resulting in higher latency, potential packet loss, and unpredictable network conditions.&lt;/p&gt;

&lt;p&gt;However, with Global Accelerator, things work a bit differently:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Request Sent to Edge Location: The user's request first travels to the nearest AWS edge location, which is likely located somewhere in the United States. This minimizes the time it takes for the request to reach the AWS network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Routing Through AWS's Private Network: Once the request arrives at the edge location, AWS Global Accelerator routes it over the private global network to your EC2 instance in Mumbai. This private network is far more optimized and reliable than public internet routing, meaning that the request is less likely to encounter network congestion or delays.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Optimal Path Selection: AWS Global Accelerator is constantly monitoring the health and performance of different AWS regions. If, for any reason, your Mumbai-based EC2 instance experiences issues (like high latency or downtime), Global Accelerator can dynamically reroute traffic to another healthy region (e.g., Singapore or the US-East region), ensuring that your application remains available with minimal disruption.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Response Sent Back to User: Once the EC2 instance processes the user's request, the response is sent back to the nearest edge location, which then returns the response to the user with the lowest possible latency.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why You Don't Need to Replicate Your EC2 Instances
&lt;/h2&gt;

&lt;p&gt;One of the key advantages of using AWS Global Accelerator is that it eliminates the need to replicate your EC2 instances across multiple regions or edge locations.&lt;/p&gt;

&lt;p&gt;Even though the user is located far from your origin server (in this case, in the US while your EC2 instance is in Mumbai), Global Accelerator still improves performance by routing the traffic through the AWS global network. This reduces latency, as traffic is handled by AWS's high-performance network instead of going through the public internet.&lt;/p&gt;

&lt;p&gt;Because Global Accelerator uses intelligent routing based on factors like health and performance, it can automatically route traffic to the best available region without you needing to worry about managing multiple copies of your infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of AWS Global Accelerator
&lt;/h2&gt;

&lt;p&gt;Here are some of the key benefits of using AWS Global Accelerator:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Improved Performance: By leveraging AWS's global network, Global Accelerator can reduce latency and improve throughput for your global users.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Increased Availability: If one endpoint or region experiences issues, Global Accelerator can automatically reroute traffic to healthy regions, ensuring that your application remains available and responsive.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Simplified Architecture: You don't need to replicate resources like EC2 instances across multiple regions. Global Accelerator takes care of intelligent routing, so you can focus on building your application rather than managing complex infrastructure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Global Reach: No matter where your users are located - in North America, Europe, Asia, or anywhere else - AWS Global Accelerator ensures they get the best performance when accessing your application.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Real-World Use Cases for Global Accelerator
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;E-Commerce Platforms: If you run an e-commerce site that serves users globally, you need to ensure that customers can browse products, make purchases, and complete transactions quickly, regardless of where they are located. AWS Global Accelerator can help ensure that product pages load faster and transactions are processed with minimal delay.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Gaming Applications: Online multiplayer games require low-latency connections for real-time interactions. With AWS Global Accelerator, you can ensure that players around the world connect to game servers with the least amount of delay, making for a smoother gaming experience.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Media Streaming: Streaming services that deliver video and audio content to a global audience rely on low-latency connections to provide buffer-free streaming experiences. AWS Global Accelerator can optimize routing for users across different regions to ensure consistent media delivery.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;AWS Global Accelerator is an invaluable tool for businesses looking to optimize the performance, availability, and reliability of their global applications. By leveraging AWS's private global network and edge locations, it helps ensure that users anywhere in the world can access your application with lower latency and higher availability - without the need for complex replication of infrastructure.&lt;/p&gt;

&lt;p&gt;Whether you're serving customers on a global scale or need to ensure that your applications are always available and responsive, AWS Global Accelerator is a powerful solution that helps take your applications to the next level.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>awscloud</category>
      <category>networking</category>
      <category>cloudcomputing</category>
    </item>
    <item>
      <title>How to Receive Phone Call 📞 Alerts Using AWS CloudWatch, Lambda &amp; Twilio</title>
      <dc:creator>Harshil Thummar</dc:creator>
      <pubDate>Tue, 29 Apr 2025 13:12:31 +0000</pubDate>
      <link>https://dev.to/harshil_thummar/how-to-receive-phone-call-alerts-using-aws-cloudwatch-lambda-twilio-3hlj</link>
      <guid>https://dev.to/harshil_thummar/how-to-receive-phone-call-alerts-using-aws-cloudwatch-lambda-twilio-3hlj</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fviz338odndxzdokr6trb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fviz338odndxzdokr6trb.png" alt="Alert Call" width="750" height="721"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagine this: Your EC2 instance's CPU is suddenly spiking, but you miss the CloudWatch email alert buried under dozens of other notifications. What if, instead, your phone rings with a voice message warning you of the spike?&lt;/p&gt;

&lt;p&gt;Welcome to a hands-on guide where we'll combine AWS Lambda, CloudWatch, and Twilio to send real-time phone call alerts whenever your EC2 instance breaches a certain threshold - no more missed alerts.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔧 What You'll Build
&lt;/h2&gt;

&lt;p&gt;By the end of this tutorial, you'll have a serverless system that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Detects high CPU usage using CloudWatch&lt;/li&gt;
&lt;li&gt;Sends an SNS notification&lt;/li&gt;
&lt;li&gt;Triggers an AWS Lambda function&lt;/li&gt;
&lt;li&gt;Uses Twilio to make a real phone call with a custom alert message&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's jump right in!&lt;/p&gt;

&lt;h2&gt;
  
  
  📦 Step 1: Create the Lambda Function
&lt;/h2&gt;

&lt;p&gt;Head over to the AWS Lambda Console and follow these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click "Create function."&lt;/li&gt;
&lt;li&gt;Choose "Author from scratch."&lt;/li&gt;
&lt;li&gt;Name it something like CallOnHighCPU&lt;/li&gt;
&lt;li&gt;Runtime: Python 3.9 (or higher)&lt;/li&gt;
&lt;li&gt;Click "Create function."&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📞 Step 2: Package Twilio with Your Lambda Code
&lt;/h2&gt;

&lt;p&gt;AWS Lambda doesn't include third-party packages by default. Let's package the Twilio SDK:&lt;/p&gt;

&lt;p&gt;👉 On your local machine, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir lambda_twilio &amp;amp;&amp;amp; cd lambda_twilio
pip install twilio -t .
zip -r9 ../lambda_function.zip .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, add your Lambda function code.&lt;br&gt;
Create a file called lambda_function.py inside lambda_twilio/:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import json
import os
from twilio.rest import Client

TWILIO_ACCOUNT_SID = os.environ['TWILIO_ACCOUNT_SID']
TWILIO_AUTH_TOKEN = os.environ['TWILIO_AUTH_TOKEN']
TWILIO_PHONE_NUMBER = os.environ['TWILIO_PHONE_NUMBER']
YOUR_PHONE_NUMBER = os.environ['YOUR_PHONE_NUMBER']

def lambda_handler(event, context):
    try:
        sns_message = event['Records'][0]['Sns']['Message']
        alarm_name = json.loads(sns_message).get("AlarmName", "Unknown Alert")
        metric_name = json.loads(sns_message).get("Trigger", {}).get("MetricName", "Unknown Metric")

        alert_message = f"Alert! {alarm_name} triggered due to high {metric_name} usage. Please check your server. Thanks!!"

        client = Client(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN)

        twiml_response = f"""
        &amp;lt;Response&amp;gt;
            &amp;lt;Say voice="man" language="en-US"&amp;gt;{alert_message}&amp;lt;/Say&amp;gt;
        &amp;lt;/Response&amp;gt;
        """

        call = client.calls.create(
            to=YOUR_PHONE_NUMBER,
            from_=TWILIO_PHONE_NUMBER,
            twiml=twiml_response
        )

        print(f"Call initiated with SID: {call.sid}")

        return {
            'statusCode': 200,
            'body': json.dumps(f'Call initiated for {alarm_name}')
        }

    except Exception as e:
        print(f"Error: {str(e)}")
        return {
            'statusCode': 500,
            'body': json.dumps(f"Error: {str(e)}")
        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, add it to your ZIP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;zip -g ../lambda_function.zip lambda_function.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This zip now contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your Lambda code&lt;/li&gt;
&lt;li&gt;The Twilio SDK&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ☁️ Step 3: Upload to Lambda
&lt;/h2&gt;

&lt;p&gt;Back in the AWS Lambda Console:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your CallOnHighCPU function&lt;/li&gt;
&lt;li&gt;Go to Code → Choose "Upload from" → "ZIP file"&lt;/li&gt;
&lt;li&gt;Upload your lambda_function.zip&lt;/li&gt;
&lt;li&gt;Click Deploy&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🔐 Step 4: Set Environment Variables
&lt;/h2&gt;

&lt;p&gt;Still in the Lambda console:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to Configuration → Environment Variables → Edit&lt;/li&gt;
&lt;li&gt;Add:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TWILIO_ACCOUNT_SID       = &amp;lt;your Twilio SID&amp;gt;
TWILIO_AUTH_TOKEN        = &amp;lt;your Twilio token&amp;gt;
TWILIO_PHONE_NUMBER      = +1234567890
YOUR_PHONE_NUMBER        = +9876543210
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save changes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;✨ If you don't have a Twilio account, create one. You'll get $15 free credit for testing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🧪 Step 5: Test the Lambda Function
&lt;/h2&gt;

&lt;p&gt;Click "Test" and create a new event:&lt;br&gt;
Test Event JSON (SNS format):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "Records": [
    {
      "Sns": {
        "Message": "{\"AlarmName\":\"HighCPUUsage\",\"Trigger\":{\"MetricName\":\"CPUUtilization\"}}"
      }
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the test. Your phone should ring with the alert message. Magic!&lt;/p&gt;

&lt;h2&gt;
  
  
  📣 Step 6: Connect Lambda to SNS
&lt;/h2&gt;

&lt;p&gt;Now, let's wire up SNS to trigger your function.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6.1: Create an SNS Topic&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to SNS Console&lt;/li&gt;
&lt;li&gt;Click Create Topic&lt;/li&gt;
&lt;li&gt;Type: Standard&lt;/li&gt;
&lt;li&gt;Name:HighCPUAlert&lt;/li&gt;
&lt;li&gt;Click Create Topic&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;6.2: Create a Subscription&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your HighCPUAlert topic&lt;/li&gt;
&lt;li&gt;Click Create Subscription&lt;/li&gt;
&lt;li&gt;Protocol: Lambda&lt;/li&gt;
&lt;li&gt;Endpoint: Select your CallOnHighCPU Lambda&lt;/li&gt;
&lt;li&gt;Click Create Subscription&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  📊 Step 7: Attach SNS to a CloudWatch Alarm
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Go to CloudWatch → Alarms → Create Alarm&lt;/li&gt;
&lt;li&gt;Choose EC2 → Per-Instance Metrics&lt;/li&gt;
&lt;li&gt;Select CPUUtilization for your instance&lt;/li&gt;
&lt;li&gt;Conditions:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Greater than 80%&lt;/li&gt;
&lt;li&gt;For 2 periods of 5 minutes&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;In actions, choose SNS topic → HighCPUAlert&lt;/li&gt;
&lt;li&gt;Click Create Alarm&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🔥 Bonus: Trigger the Alarm with a CPU Spike
&lt;/h2&gt;

&lt;p&gt;On your EC2 instance, simulate CPU load:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install stress
stress --cpu 2 --timeout 120s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Within minutes, CloudWatch will detect the spike, SNS will publish a message, Lambda will be triggered, and… your phone will ring.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎉 You're Done!
&lt;/h2&gt;

&lt;p&gt;You've successfully built a voice-based monitoring system using AWS Lambda, CloudWatch, SNS, and Twilio.&lt;br&gt;
This solution is&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real-time&lt;/li&gt;
&lt;li&gt;Reliable&lt;/li&gt;
&lt;li&gt;Easy to extend&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Need to alert a team? Add multiple Twilio calls. Want Slack integration instead? Swap Twilio with a Slack webhook.&lt;/p&gt;

&lt;h2&gt;
  
  
  🙌 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Email alerts are great, but voice alerts are immediate, hard to ignore, and potentially life-saving in production environments.&lt;/p&gt;

&lt;p&gt;With just a few lines of code and some AWS configuration, you now have an automated voice call alert system that keeps your infrastructure healthy and your response time sharp.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>lambda</category>
      <category>cloudskills</category>
      <category>security</category>
    </item>
  </channel>
</rss>
