{"id":18733,"date":"2024-07-16T15:35:40","date_gmt":"2024-07-16T10:05:40","guid":{"rendered":"https:\/\/opstree.com\/blog\/?p=18733"},"modified":"2024-07-16T16:14:20","modified_gmt":"2024-07-16T10:44:20","slug":"lambda-function-setup-guide-for-security-group-event-notifications-in-slack","status":"publish","type":"post","link":"https:\/\/opstree.com\/blog\/2024\/07\/16\/lambda-function-setup-guide-for-security-group-event-notifications-in-slack\/","title":{"rendered":"Lambda Function Setup Guide for Security Group Event Notifications in Slack"},"content":{"rendered":"<h3><b>Overview<\/b><\/h3>\r\n<p><span style=\"font-weight: 400;\">This document provides a step-by-step guide to creating a Lambda function that sends notifications to Slack when a security group rule is modified in AWS.<\/span><\/p>\r\n<h3><b>Prerequisites<\/b><\/h3>\r\n<ol>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">AWS Account with necessary permissions to create and configure Lambda, IAM, CloudTrail, and CloudWatch Logs.<\/span><\/li>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Slack workspace with permissions to create a new app and generate an incoming webhook URL.<\/span><\/li>\r\n<\/ol>\r\n<h3><b>Architecture<\/b><\/h3>\r\n<p><i><span style=\"font-weight: 400;\">Security Group Rule Event -&gt; CloudTrail -&gt; CloudWatch Logs -&gt; Lambda Function -&gt; Slack<\/span><\/i> <!--more--><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-18735 size-full\" src=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-1.png\" alt=\"\" width=\"2500\" height=\"416\" srcset=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-1.png 2500w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-1-300x50.png 300w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-1-1024x170.png 1024w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-1-768x128.png 768w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-1-1536x256.png 1536w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-1-2048x341.png 2048w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-1-1200x200.png 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/p>\r\n<h3><b>Step 1: Setup CloudTrail<\/b><\/h3>\r\n<ol>\r\n<li style=\"font-weight: 400;\"><b>Go to CloudTrail Console:<\/b><\/li>\r\n<\/ol>\r\n<ul>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Navigate to the AWS Management Console.<\/span><\/li>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Go to the CloudTrail service.<\/span><\/li>\r\n<\/ul>\r\n<ol start=\"2\">\r\n<li><b>Create or Configure a Trail:<\/b><\/li>\r\n<\/ol>\r\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-18736 size-full\" src=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-2.png\" alt=\"\" width=\"2774\" height=\"1316\" srcset=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-2.png 2774w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-2-300x142.png 300w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-2-1024x486.png 1024w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-2-768x364.png 768w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-2-1536x729.png 1536w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-2-2048x972.png 2048w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-2-1200x569.png 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/p>\r\n<ul>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Create a new trail or use an existing one.<\/span><\/li>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Ensure that the trail is configured to log management events.<\/span><\/li>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Enable the trail to send logs to CloudWatch Logs.<\/span><\/li>\r\n<\/ul>\r\n<h3><b>Step 2: Setup CloudWatch Logs<\/b><\/h3>\r\n<ol>\r\n<li style=\"font-weight: 400;\"><b>Create Log Group:<\/b><\/li>\r\n<\/ol>\r\n<ul>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Navigate to CloudWatch in the AWS Management Console.<\/span><\/li>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Create a new log group or use an existing one to receive CloudTrail logs<\/span><\/li>\r\n<\/ul>\r\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-18737 size-full\" src=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.32.37\u202fPM.png\" alt=\"\" width=\"2284\" height=\"1230\" srcset=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.32.37\u202fPM.png 2284w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.32.37\u202fPM-300x162.png 300w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.32.37\u202fPM-1024x551.png 1024w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.32.37\u202fPM-768x414.png 768w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.32.37\u202fPM-1536x827.png 1536w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.32.37\u202fPM-2048x1103.png 2048w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.32.37\u202fPM-1200x646.png 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/p>\r\n<h3><b>Step 3: Create Lambda Function<\/b><\/h3>\r\n<ol>\r\n<li style=\"font-weight: 400;\"><b>Create a Lambda Function:<\/b><\/li>\r\n<\/ol>\r\n<ul>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Go to the AWS Lambda Console.<\/span><\/li>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Create a new Lambda function with a suitable name, runtime (Python 3.8+), and role with the necessary permissions.<\/span><\/li>\r\n<\/ul>\r\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-18738 size-full aligncenter\" src=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-3.12.14\u202fPM.png\" alt=\"\" width=\"2836\" height=\"1278\" srcset=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-3.12.14\u202fPM.png 2836w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-3.12.14\u202fPM-300x135.png 300w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-3.12.14\u202fPM-1024x461.png 1024w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-3.12.14\u202fPM-768x346.png 768w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-3.12.14\u202fPM-1536x692.png 1536w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-3.12.14\u202fPM-2048x923.png 2048w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-3.12.14\u202fPM-1200x541.png 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/p>\r\n<ol start=\"2\">\r\n<li><b>Add the Code mentioned below:<\/b><\/li>\r\n<\/ol>\r\n<pre>import boto3<br \/><br \/>import json<br \/><br \/>import os<br \/><br \/>import base64<br \/><br \/>import gzip<br \/><br \/>import subprocess<br \/><br \/>ec2_client = boto3.client('ec2', region_name='us-east-1')<br \/><br \/>webhook_url = os.environ.get('WEBHOOK_URL')<br \/><br \/>def slack_message(sg_id, username, port, cidr, action):<br \/><br \/>\u00a0\u00a0\u00a0\u00a0message = f\"\"\"<br \/><br \/>:siren: *Security Group Rules Alert* :siren:<br \/><br \/>&lt;!channel&gt; Hey team,<br \/><br \/>A security group rule has been modified. Here are the details:<br \/><br \/>\u00a0*Action:* `{action}`<br \/><br \/>\u00a0*Created By:* `{username}`<br \/><br \/>\u00a0*Security Group Id:* `{sg_id}`<br \/><br \/>\u00a0*Port Number:* `{port}`<br \/><br \/>\u00a0*CIDR:* `{cidr}`<br \/><br \/>\u00a0*Potential Impact:* Access rule change detected.<br \/><br \/>\u00a0*Actions Required:* Review the security group rules to ensure they meet your security requirements.<br \/><br \/>Thank you for your attention to this matter! :hammer_and_spanner:<br \/><br \/>\"\"\"<br \/><br \/>\u00a0\u00a0\u00a0\u00a0return message<br \/><br \/>def send_alert(sg_id, username, port, cidr, action):<br \/><br \/>\u00a0\u00a0\u00a0\u00a0message = slack_message(sg_id, username, port, cidr, action)<br \/><br \/>\u00a0\u00a0\u00a0\u00a0payload = {<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"channel\": \"\",<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"username\": \"Bot\",<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"text\": message,<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"icon_emoji\": \":alert:\"<br \/><br \/>\u00a0\u00a0\u00a0\u00a0}<br \/><br \/>\u00a0\u00a0\u00a0\u00a0json_payload = json.dumps(payload)<br \/><br \/>\u00a0\u00a0\u00a0\u00a0curl_command = ['curl', '-X', 'POST', '-H', 'Content-Type: application\/json', '-d', json_payload, webhook_url]<br \/><br \/>\u00a0\u00a0\u00a0\u00a0response = subprocess.run(curl_command, check=True, capture_output=True, text=True)<br \/><br \/>def parse_event(event):<br \/><br \/>\u00a0\u00a0\u00a0\u00a0if 'detail' in event:<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0action = event['detail']['eventName']<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0username = event['detail']['userIdentity']['principalId'].split(':')[-1]<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0sg_rule_sets = event['detail']['responseElements']['securityGroupRuleSet']<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0for sg_rule in sg_rule_sets['items']:<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0sg_id = sg_rule['groupId']<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0from_port = int(sg_rule['fromPort'])<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0to_port = int(sg_rule['toPort'])<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cidr = sg_rule.get('cidrIpv4', sg_rule.get('cidrIpv6', 'N\/A'))<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0send_alert(sg_id, username, to_port, cidr, action)<br \/><br \/>\u00a0\u00a0\u00a0\u00a0else:<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0# Log CloudWatch log events<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0log_data = event['awslogs']['data']<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0compressed_payload = base64.b64decode(log_data)<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0uncompressed_payload = gzip.decompress(compressed_payload)<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0log_events = json.loads(uncompressed_payload)['logEvents']<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0for log_event in log_events:<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0message = log_event['message']<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0log_entry = json.loads(message)<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0action = log_entry['eventName']<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0username = log_entry['userIdentity']['principalId'].split(':')[-1]<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0sg_rule_sets = log_entry['responseElements']['securityGroupRuleSet']<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0for sg_rule in sg_rule_sets['items']:<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0sg_id = sg_rule['groupId']<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0from_port = int(sg_rule['fromPort'])<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0to_port = int(sg_rule['toPort'])<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cidr = sg_rule.get('cidrIpv4', sg_rule.get('cidrIpv6', 'N\/A'))<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0send_alert(sg_id, username, to_port, cidr, action)<br \/><br \/>def lambda_handler(event, context):<br \/><br \/>\u00a0\u00a0\u00a0\u00a0try:<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0parse_event(event)<br \/><br \/>\u00a0\u00a0\u00a0\u00a0except KeyError as e:<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0print(f\"KeyError: {e}\")<br \/><br \/># Example event structure for testing<br \/><br \/>if __name__ == \"__main__\":<br \/><br \/>\u00a0\u00a0\u00a0\u00a0test_event = {<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'awslogs': {<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'data': base64.b64encode(gzip.compress(json.dumps({<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'logEvents': [<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'message': json.dumps({<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'eventName': 'AuthorizeSecurityGroupIngress',<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'userIdentity': {<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'principalId': 'AWS:TestUser',<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'responseElements': {<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'securityGroupRuleSet': {<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'items': [<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'groupId': 'sg-12345678',<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'fromPort': 22,<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'toPort': 22,<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'cidrIpv4': '0.0.0.0\/0',<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0]<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0})<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0]<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}).encode())).decode()<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<br \/><br \/>\u00a0\u00a0\u00a0\u00a0}<br \/><br \/>\u00a0\u00a0\u00a0\u00a0lambda_handler(test_event, None)<br \/><br \/><br \/><\/pre>\r\n<p><b>Set Environment Variable:<\/b> <img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-18739 size-full\" src=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.34.22\u202fPM.png\" alt=\"\" width=\"2696\" height=\"1126\" srcset=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.34.22\u202fPM.png 2696w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.34.22\u202fPM-300x125.png 300w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.34.22\u202fPM-1024x428.png 1024w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.34.22\u202fPM-768x321.png 768w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.34.22\u202fPM-1536x642.png 1536w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.34.22\u202fPM-2048x855.png 2048w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.34.22\u202fPM-1200x501.png 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/p>\r\n<ul>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Set the <\/span><span style=\"font-weight: 400;\">WEBHOOK_URL<\/span><span style=\"font-weight: 400;\"> environment variable to the Slack webhook URL you created.<\/span><\/li>\r\n<\/ul>\r\n<h3><b>Step 4: Configure CloudWatch Logs Filter Pattern<\/b><\/h3>\r\n<ol>\r\n<li style=\"font-weight: 400;\"><b>Create Metric Filter:<\/b><\/li>\r\n<\/ol>\r\n<ul>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Go to the CloudWatch Console.<\/span><\/li>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Select the log group that receives CloudTrail logs.<\/span><\/li>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Create a new metric filter with the following pattern:<\/span><\/li>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }<\/span><\/li>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Provide a name for the filter and configure it.<\/span><\/li>\r\n<\/ul>\r\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-18740 size-full\" src=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.40.29\u202fPM.png\" alt=\"\" width=\"2756\" height=\"1280\" srcset=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.40.29\u202fPM.png 2756w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.40.29\u202fPM-300x139.png 300w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.40.29\u202fPM-1024x476.png 1024w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.40.29\u202fPM-768x357.png 768w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.40.29\u202fPM-1536x713.png 1536w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.40.29\u202fPM-2048x951.png 2048w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.40.29\u202fPM-1200x557.png 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/> <b>Step 5: Add CloudWatch Logs Trigger to Lambda<\/b><\/p>\r\n<ol>\r\n<li style=\"font-weight: 400;\"><b>Add Trigger:<\/b><\/li>\r\n<\/ol>\r\n<ul>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Go to the Lambda Console.<\/span><\/li>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Select your Lambda function.<\/span><\/li>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">In the \u201cFunction overview\u201d section, click \u201cAdd trigger\u201d.<\/span><\/li>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Select \u201cCloudWatch Logs\u201d as the trigger type.<\/span><\/li>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Choose the log group that contains the CloudTrail logs.<\/span><\/li>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Specify the filter pattern created earlier.<\/span><\/li>\r\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Click \u201cAdd\u201d.<\/span><\/li>\r\n<\/ul>\r\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-18742 size-full\" src=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.37.36\u202fPM.png\" alt=\"\" width=\"2728\" height=\"1212\" srcset=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.37.36\u202fPM.png 2728w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.37.36\u202fPM-300x133.png 300w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.37.36\u202fPM-1024x455.png 1024w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.37.36\u202fPM-768x341.png 768w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.37.36\u202fPM-1536x682.png 1536w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.37.36\u202fPM-2048x910.png 2048w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-01-at-6.37.36\u202fPM-1200x533.png 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/> <b>Step 6: Test the Setup<\/b><\/p>\r\n<ol>\r\n<li style=\"font-weight: 400;\"><b>Generate Test Events<\/b><span style=\"font-weight: 400;\">:<\/span><\/li>\r\n<\/ol>\r\n<p><span style=\"font-weight: 400;\">Modify a security group rule (e.g., authorize or revoke an ingress or egress rule) to generate test events.<\/span><\/p>\r\n<ol>\r\n<li style=\"font-weight: 400;\"><b>Verify Slack Notifications<\/b><span style=\"font-weight: 400;\">:<\/span><\/li>\r\n<\/ol>\r\n<p><span style=\"font-weight: 400;\">Check your Slack channel to ensure notifications are being received as expected.<\/span> <span style=\"font-weight: 400;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-18743 size-full\" src=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-3.png\" alt=\"\" width=\"1950\" height=\"1112\" srcset=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-3.png 1950w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-3-300x171.png 300w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-3-1024x584.png 1024w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-3-768x438.png 768w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-3-1536x876.png 1536w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/image-3-1200x684.png 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/span><\/p>\r\n<h2><b>Conclusion<\/b><\/h2>\r\n<p><span style=\"font-weight: 400;\">Following these steps, you have successfully set up a Lambda function to send notifications to Slack for security group rule changes. This setup enhances security monitoring and provides real-time alerts to your AWS security groups for critical changes.<\/span><\/p>\r\n<div class=\"ch bg ew ex ey ez\"><strong>Blog Pundits:<\/strong> <strong><a href=\"https:\/\/opstree.com\/blog\/author\/sandeep7c51ad81ba\/\">Sandeep Rawat<\/a> <\/strong> <!-- \/wp:list -->\r\n\r\n<!-- wp:paragraph --><\/div>\r\n<div>\u00a0<\/div>\r\n<div class=\"ch bg ew ex ey ez\"><a href=\"https:\/\/www.opstree.com\/contact-us?utm_source=wordpress&amp;utm_campaign=AWS-Gateway-LoadBalancer-A-Load-Balancer-that-we-deserve&amp;utm_id=Blog\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>Opstree<\/strong> <\/a>is an End to End DevOps solution provider<\/div>\r\n<div>\u00a0<\/div>\r\n<div class=\"ch bg ew ex ey ez\"><!-- \/wp:paragraph -->\r\n\r\n<!-- wp:buttons -->\r\n<div class=\"wp-block-buttons\"><!-- wp:button {\"className\":\"is-style-fill\"} -->\r\n<div class=\"wp-block-button is-style-fill\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/www.opstree.com\/contact-us\" target=\"_blank\" rel=\"noreferrer noopener\">CONTACT US<\/a><\/div>\r\n<!-- \/wp:button --><\/div>\r\n<!-- \/wp:buttons -->\r\n\r\n<!-- wp:paragraph {\"align\":\"center\"} -->\r\n<p class=\"has-text-align-center\"><strong>Connect With Us<\/strong><\/p>\r\n<\/div>","protected":false},"excerpt":{"rendered":"<p>Overview This document provides a step-by-step guide to creating a Lambda function that sends notifications to Slack when a security group rule is modified in AWS. Prerequisites AWS Account with necessary permissions to create and configure Lambda, IAM, CloudTrail, and CloudWatch Logs. Slack workspace with permissions to create a new app and generate an incoming &hellip; <a href=\"https:\/\/opstree.com\/blog\/2024\/07\/16\/lambda-function-setup-guide-for-security-group-event-notifications-in-slack\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Lambda Function Setup Guide for Security Group Event Notifications in Slack&#8221;<\/span><\/a><\/p>\n","protected":false},"author":244582674,"featured_media":18744,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[28070474,111949],"tags":[768739359,768739360],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Lambda-Function-Setup-Guide-for-Security-Group-Event-Notifications-in-Slack-1.png","jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pfDBOm-4S9","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/18733"}],"collection":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/users\/244582674"}],"replies":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/comments?post=18733"}],"version-history":[{"count":9,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/18733\/revisions"}],"predecessor-version":[{"id":18753,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/18733\/revisions\/18753"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media\/18744"}],"wp:attachment":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media?parent=18733"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/categories?post=18733"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/tags?post=18733"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}