Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions README3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# EC2 Instance Monitoring Automation

This repository contains CloudFormation and Terraform scripts to automate the provisioning of resources for monitoring newly deployed EC2 instances using AWS Lambda, Amazon SNS, and CloudWatch Events. This setup eliminates the need for manual intervention and enables seamless monitoring of EC2 instances.

## Features

- Automatically provision Lambda function, SNS topic, and CloudWatch Event Rule.
- Monitor newly deployed EC2 instances using CloudWatch Events.
- Integrate with AWS CodeDeploy or Auto Scaling Group for dynamic monitoring.
- Utilize CloudWatch agent metrics for enhanced monitoring capabilities.

## Prerequisites

Before deploying the scripts, ensure that you have the following prerequisites set up:

- AWS account with appropriate permissions to create and manage resources.
- AWS CLI configured with access keys or IAM role.
- Basic knowledge of AWS services like Lambda, SNS, CloudWatch, and EC2.

## Usage

### CloudFormation

The CloudFormation script (`automacticdashboard.yml`) automates the provisioning of resources:

1. Navigate to the AWS CloudFormation console.
2. Click on "Create Stack" and choose "With new resources (standard)".
3. Upload the `automacticdashboard.yml` file.
4. Follow the on-screen instructions, providing necessary parameters like stack name, Lambda function code location, etc.
5. Click "Create Stack" to initiate the provisioning process.


## Resources Provisioned

Both CloudFormation and Terraform scripts provision the following resources:

- Lambda function: Responsible for processing events triggered by CloudWatch Events.
- SNS topic: Used for sending notifications related to EC2 instance events.
- CloudWatch Event Rule: Triggers the Lambda function when EC2 instance state changes occur.

## Monitoring EC2 Instances

Once the resources are provisioned, EC2 instances can be monitored automatically:

1. Any new EC2 instance launches or state changes will trigger the Lambda function.
2. The Lambda function can perform actions like sending notifications via SNS, updating CloudWatch Dashboards, or executing custom logic based on the event.
3. Utilize CloudWatch agent metrics for deeper insights into EC2 instance performance and health.

## Contributing

Contributions to improve and enhance the automation scripts are welcome! Feel free to submit pull requests or open issues for any suggestions or improvements.
213 changes: 213 additions & 0 deletions automacticdashboard.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
AWSTemplateFormatVersion: '2010-09-09'
Description: Lambda function to update CloudWatch dashboard

Parameters:
Name:
Type: String
Description: Name for your resource
DashboardName:
Type: String
Description: Name of the CloudWatch dashboard to update
SNSTopicName:
Type: String
Description: Name of the SNS topic to subscribe to
Email:
Type: String
Description: Email address to send notifications to

Resources:
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub "${Name}-Role"
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: !Sub "${Name}-Policy"
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- "cloudwatch:PutDashboard"
- "cloudwatch:GetDashboard"
- "ec2:Describe*"
- "ec2:Get*"
- "ec2:List*"
- "sns:*"
- "cloudwatch:*"
Resource: "*"
SNSTopic:
Type: AWS::SNS::Topic
Properties:
DisplayName: !Ref SNSTopicName
Subscription:
- Endpoint: !Ref Email
Protocol: email

SNSTopicPolicy:
Type: AWS::SNS::TopicPolicy
Properties:
Topics:
- !Ref SNSTopic
PolicyDocument:
Statement:
- Effect: Allow
Principal: "*"
Action: sns:Publish
Resource: !Ref SNSTopic
Condition:
StringEquals:
AWS:SourceOwner: !Ref "AWS::AccountId"

LambdaFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: !Sub "${Name}-Lambda"
Handler: lambda_function.lambda_handler
Role: !GetAtt LambdaExecutionRole.Arn
Code:
ZipFile: |
import json
import boto3
import datetime

def lambda_handler(event, context):
# Extract instance id from the event
instance_id = event['detail']['instance-id']
# Calculate the start time and end time
start_time = datetime.datetime.utcnow() - datetime.timedelta(hours=1) # Example: 1 hour ago
end_time = datetime.datetime.utcnow()

# Create a CloudWatch client
cloudwatch = boto3.client('cloudwatch')

# Get the EC2 instance's CPU utilization metrics
response = cloudwatch.get_metric_statistics(
Namespace='AWS/EC2',
MetricName='CPUUtilization',
Dimensions=[
{
'Name': 'InstanceId',
'Value': instance_id
},
],
StartTime=start_time,
EndTime=end_time,
Period=300,
Statistics=['Average'],
Unit='Percent'
)

# Extracting the average CPU utilization value
if 'Datapoints' in response and len(response['Datapoints']) > 0:
cpu_utilization = response['Datapoints'][0]['Average']
else:
cpu_utilization = "No data available"

# Print CPU utilization
print("CPU Utilization:", cpu_utilization)

# Update the CloudWatch Dashboard
update_dashboard(instance_id, cpu_utilization)

return {
'statusCode': 200,
'body': json.dumps('Successfully retrieved CPU utilization and updated CloudWatch Dashboard!')
}

def update_dashboard(instance_id, cpu_utilization):
# Define the JSON layout of the dashboard
dashboard_body = {
"widgets": [
{
"type": "metric",
"x": 0,
"y": 0,
"width": 12,
"height": 6,
"properties": {
"metrics": [
["AWS/EC2", "CPUUtilization", "InstanceId", instance_id]
],
"period": 300,
"stat": "Average",
"region": "ap-south-1",#change region here
"title": "EC2 Instance CPU Utilization"
}
}
]
}

# Create a CloudWatch client
cloudwatch = boto3.client('cloudwatch')

# Update the CloudWatch Dashboard
response = cloudwatch.put_dashboard(
DashboardName= ["${DashboardName}"],
DashboardBody=json.dumps(dashboard_body)
)

print("Dashboard update response:", response)

# Add CloudWatch Alarms
alarm_cpu = cloudwatch.put_metric_alarm(
AlarmName='CPUUtilizationAlarm',
ComparisonOperator='GreaterThanOrEqualToThreshold',
EvaluationPeriods=1,
MetricName='CPUUtilization',
Namespace='AWS/EC2',
Period=300,
Statistic='Average',
Threshold=75,
ActionsEnabled=True,
AlarmActions=["${SNSTopic}"],
Dimensions=[
{
'Name': 'InstanceId',
'Value': instance_id
}
]
)

Runtime: python3.8
Timeout: 800
Environment:
Variables:
DashboardName:
Ref: DashboardName
SNSTopic:
!Ref SNSTopic


EC2StateChangeRule:
Type: AWS::Events::Rule
Properties:
Name: !Sub "${Name}-EC2StateChange"
Targets:
- Arn: !GetAtt LambdaFunction.Arn
Id: "TargetFunctionV1"
EventPattern:
source:
- "aws.ec2"
detail-type:
- "EC2 Instance State-change Notification"
detail:
state:
- "running"
State: ENABLED

LambdaInvokePermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref LambdaFunction
Principal: events.amazonaws.com
SourceArn: !GetAtt EC2StateChangeRule.Arn