diff --git a/README3.md b/README3.md new file mode 100644 index 0000000..45f76e1 --- /dev/null +++ b/README3.md @@ -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. diff --git a/automacticdashboard.yaml b/automacticdashboard.yaml new file mode 100644 index 0000000..93649a1 --- /dev/null +++ b/automacticdashboard.yaml @@ -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 + +