{"id":18700,"date":"2024-07-09T16:23:36","date_gmt":"2024-07-09T10:53:36","guid":{"rendered":"https:\/\/opstree.com\/blog\/?p=18700"},"modified":"2024-07-09T18:29:11","modified_gmt":"2024-07-09T12:59:11","slug":"lambda-function-setup-guide-for-iam-event-notifications-in-slack","status":"publish","type":"post","link":"https:\/\/opstree.com\/blog\/2024\/07\/09\/lambda-function-setup-guide-for-iam-event-notifications-in-slack\/","title":{"rendered":"Lambda Function Setup Guide for IAM Event Notifications in Slack"},"content":{"rendered":"\r\n<h3 class=\"wp-block-heading\"><strong>Overview<\/strong><\/h3>\r\n\r\n\r\n\r\n<p>This document provides a step-by-step guide to creating a Lambda function that sends notifications to Slack when:<\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>A new IAM user is created.<\/li>\r\n\r\n\r\n\r\n<li>A permission (policy) is attached to an IAM user.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\"><strong>Prerequisites<\/strong><\/h3>\r\n\r\n\r\n\r\n<ol class=\"wp-block-list\">\r\n<li>AWS Account with necessary permissions to create and configure Lambda, IAM, CloudTrail, and CloudWatch Logs.<\/li>\r\n\r\n\r\n\r\n<li>Slack workspace with permissions to create a new app and generate an incoming webhook URL.<\/li>\r\n<\/ol>\r\n<p><!--more--><\/p>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\"><strong>Architecture<\/strong><\/h3>\r\n\r\n\r\n\r\n<p><em>\u00a0IAM event -&gt; CloudTrail -&gt; CloudWatch Logs -&gt; Lambda Function -&gt; Slack<\/em><\/p>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/docsz\/AD_4nXf5YH_fKSQy-ceXut9pDAw2PNXYulZ9j4Ywry5AmOLR1e94NxydzydzhCONTI8OpZ6swcrJH7f7S-Bb_7h6CUPSaIJZJAWrfT7MJAqkuWH9HJ-UewhLbZOsv-VMKmttv1PyHbCekH_zjAEh6ujOEIIs8LwG?key=18RgewjC-PeijjwThlOMSw\" alt=\"\" \/><\/figure>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\"><strong>Step 1: Setup CloudTrail<\/strong><\/h3>\r\n\r\n\r\n\r\n<ol class=\"wp-block-list\">\r\n<li><strong>Go to CloudTrail Console:<\/strong><\/li>\r\n<\/ol>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Navigate to the AWS Management Console.<\/li>\r\n\r\n\r\n\r\n<li>Go to the CloudTrail service.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<p>2. <strong>Create or Configure a Trail:<\/strong><\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Create a new trail or use an existing one.<\/li>\r\n\r\n\r\n\r\n<li>Ensure that the trail is configured to log management events.<\/li>\r\n\r\n\r\n\r\n<li>Enable the trail to send logs to CloudWatch Logs.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" class=\"wp-image-18643\" src=\"https:\/\/blog.opstree.com\/wp-content\/uploads\/2024\/07\/image-2-1024x453.png\" alt=\"\" \/><\/figure>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\"><strong>Step 2: Setup CloudWatch Logs<\/strong><\/h3>\r\n\r\n\r\n\r\n<ol class=\"wp-block-list\">\r\n<li><strong>Create Log Group:<\/strong><\/li>\r\n<\/ol>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Navigate to CloudWatch in the AWS Management Console.<\/li>\r\n\r\n\r\n\r\n<li>Create a new log group or use an existing one to receive CloudTrail logs<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" class=\"wp-image-18644\" src=\"https:\/\/blog.opstree.com\/wp-content\/uploads\/2024\/07\/image-3-1024x459.png\" alt=\"\" \/><\/figure>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\"><strong>Step 3: Create Lambda Function<\/strong><\/h3>\r\n\r\n\r\n\r\n<ol class=\"wp-block-list\">\r\n<li><strong>Create a Lambda Function:<\/strong><\/li>\r\n<\/ol>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Go to the AWS Lambda Console.<\/li>\r\n\r\n\r\n\r\n<li>Create a new Lambda function with a suitable name, runtime (Python 3.8+), and role with the necessary permissions.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/docsz\/AD_4nXc1eEN0m-YbLouaRDRltPKNY1jsCnUl4dhOPO4KrsJ8Mf85JyylhJ8T5ayU3ZWbZH7JuJ8DH4xaNs9X6yITnLb6Rc4w5vjl7PvgjFs7ZCivJXCQ2AwJd-87xkPypjKW83Yce0mPbmJlVJ1P4sMqqM8xf2R9?key=18RgewjC-PeijjwThlOMSw\" alt=\"\" \/><\/figure>\r\n\r\n\r\n\r\n<p>2. <strong>Add the Following Code:<\/strong><\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>import json\r\n\r\nimport os\r\n\r\nimport base64\r\n\r\nimport gzip\r\n\r\nimport urllib3\r\n\r\nwebhook_url = os.environ.get('WEBHOOK_URL')\r\n\r\ndef send_slack_message(message):\r\n\r\n\u00a0\u00a0\u00a0\u00a0http = urllib3.PoolManager()\r\n\r\n\u00a0\u00a0\u00a0\u00a0payload = {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"blocks\": message\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0encoded_payload = json.dumps(payload).encode('utf-8')\r\n\r\n\u00a0\u00a0\u00a0\u00a0response = http.request(\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'POST',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0webhook_url,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0body=encoded_payload,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0headers={'Content-Type': 'application\/json'},\r\n\r\n\u00a0\u00a0\u00a0\u00a0)\r\n\r\n\u00a0\u00a0\u00a0\u00a0return response.status\r\n\r\ndef create_slack_message(event_detail):\r\n\r\n\u00a0\u00a0\u00a0\u00a0event_name = event_detail['eventName']\r\n\r\n\u00a0\u00a0\u00a0\u00a0actor_name = event_detail['userIdentity']['userName']\r\n\r\n\u00a0\u00a0\u00a0\u00a0if event_name == 'CreateUser':\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0user_name = event_detail['requestParameters']['userName']\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0title = \"New IAM User Created\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0message = f\"A new IAM user `{user_name}` has been created by `{actor_name}`.\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0color = \"#36a64f\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0elif event_name in ['AttachUserPolicy', 'PutUserPolicy']:\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0user_name = event_detail['requestParameters']['userName']\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0policy_name = event_detail['requestParameters']['policyArn']\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0title = \"Policy Attached to IAM User\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0message = f\"Policy `{policy_name}` has been attached to user `{user_name}` by `{actor_name}`.\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0color = \"#FFA500\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0slack_message = [\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"type\": \"section\",\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"text\": {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"type\": \"mrkdwn\",\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"text\": f\":rotating_light: *{title}* :rotating_light:\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"type\": \"section\",\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"fields\": [\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"type\": \"mrkdwn\",\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"text\": f\"*Event Name:*\\n{event_name}\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"type\": \"mrkdwn\",\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"text\": f\"*User Name:*\\n{user_name}\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"type\": \"mrkdwn\",\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"text\": f\"*Performed By:*\\n{actor_name}\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0]\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"type\": \"section\",\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"text\": {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"type\": \"mrkdwn\",\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"text\": message\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"type\": \"divider\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0]\r\n\r\n\u00a0\u00a0\u00a0\u00a0return slack_message\r\n\r\ndef parse_event(event):\r\n\r\n\u00a0\u00a0\u00a0\u00a0if 'awslogs' in event:\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0log_data = event['awslogs']['data']\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0compressed_payload = base64.b64decode(log_data)\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0uncompressed_payload = gzip.decompress(compressed_payload)\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0log_events = json.loads(uncompressed_payload)['logEvents']\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0for log_event in log_events:\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0message = log_event['message']\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0log_entry = json.loads(message)\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if log_entry['eventName'] in ['CreateUser', 'AttachUserPolicy', 'PutUserPolicy']:\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0slack_message = create_slack_message(log_entry)\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0send_slack_message(slack_message)\r\n\r\ndef lambda_handler(event, context):\r\n\r\n\u00a0\u00a0\u00a0\u00a0try:\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0parse_event(event)\r\n\r\n\u00a0\u00a0\u00a0\u00a0except Exception as e:\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0print(f\"Error parsing event: {e}\")\r\n\r\n\u00a0\u00a0\u00a0\u00a0return {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'statusCode': 200,\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'body': json.dumps('Notification sent!')\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\r\n\r\n# Example test event\r\n\r\nif __name__ == \"__main__\":\r\n\r\n\u00a0\u00a0\u00a0\u00a0test_event = {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'awslogs': {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'data': base64.b64encode(gzip.compress(json.dumps({\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'logEvents': [\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\r\n\r\n\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({\r\n\r\n\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': 'CreateUser',\r\n\r\n\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'requestParameters': {\r\n\r\n\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'userName': 'NewTestUser'\r\n\r\n\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},\r\n\r\n\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': {\r\n\r\n\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'userName': 'AdminUser',\r\n\r\n\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}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0})\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0]\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}).encode())).decode()\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0lambda_handler(test_event, None)<\/code><\/pre>\r\n\r\n\r\n\r\n<p><strong>Set Environment variable<\/strong><\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Set the WEBHOOK_URL environment variable to the Slack webhook URL you created.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/docsz\/AD_4nXexT8GYpiapfz2yO7T0KWo3pS1AI0TbMGJ_MD1ZJNxBUhxFNneRFslQptSNzFKytKQIH08XmHFjxEjJNnJv3s5y8Kw9YsuvYJBwnR1Cx7l4eSmLDOO9zsJiSDhTR8S7B4BmB6D8aFX8341pMNZQX9CDPnms?key=18RgewjC-PeijjwThlOMSw\" alt=\"\" \/><\/figure>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\"><strong>Step 4: Configure CloudWatch Logs Filter Pattern<\/strong><\/h3>\r\n\r\n\r\n\r\n<ol class=\"wp-block-list\">\r\n<li><strong>Create Metric Filter:<\/strong><\/li>\r\n<\/ol>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Go to the CloudWatch Console.<\/li>\r\n\r\n\r\n\r\n<li>Select the log group that receives CloudTrail logs.<\/li>\r\n\r\n\r\n\r\n<li>Create a new metric filter with the following pattern:<\/li>\r\n\r\n\r\n\r\n<li>{ ($.eventName = &#8220;CreateUser&#8221;) || ($.eventName = &#8220;AttachUserPolicy&#8221;) || ($.eventName = &#8220;PutUserPolicy&#8221;) }<\/li>\r\n\r\n\r\n\r\n<li>Provide a name for the filter and configure it.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" class=\"wp-image-18647\" src=\"https:\/\/blog.opstree.com\/wp-content\/uploads\/2024\/07\/image-4-1024x470.png\" alt=\"\" \/><\/figure>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\"><strong>Step 5: Add CloudWatch Logs Trigger to Lambda<\/strong><\/h3>\r\n\r\n\r\n\r\n<ol class=\"wp-block-list\">\r\n<li><strong>Add Trigger:<\/strong><\/li>\r\n<\/ol>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Go to the Lambda Console.<\/li>\r\n\r\n\r\n\r\n<li>Select your Lambda function.<\/li>\r\n\r\n\r\n\r\n<li>In the \u201cFunction overview\u201d section, click \u201cAdd trigger\u201d.<\/li>\r\n\r\n\r\n\r\n<li>Select \u201cCloudWatch Logs\u201d as the trigger type.<\/li>\r\n\r\n\r\n\r\n<li>Choose the log group that contains the CloudTrail logs.<\/li>\r\n\r\n\r\n\r\n<li>Specify the filter pattern created earlier.<\/li>\r\n\r\n\r\n\r\n<li>Click \u201cAdd\u201d.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" class=\"wp-image-18641\" src=\"https:\/\/blog.opstree.com\/wp-content\/uploads\/2024\/07\/image-1-1024x475.png\" alt=\"\" \/><\/figure>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\"><strong>Step 6: Test the Setup<\/strong><\/h3>\r\n\r\n\r\n\r\n<ol class=\"wp-block-list\">\r\n<li><strong>Generate Test Events:<\/strong><\/li>\r\n<\/ol>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Create a new IAM user or attach a policy to an existing user to generate test events.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/docsz\/AD_4nXcTn1fuP-WkttWiZRdf995lw9OKV7HN-6-YLkgs1Ury2vjfWL8BysTRbQWcrnDuLNSjFBft1nzzlW0uQeBjaY_ssEbYyigHwK6eCeSxyyRzwMUsJ29bCqOn9KYdeifqoYpPgwwC0rOOtQOLztMJT99Vjp4e?key=18RgewjC-PeijjwThlOMSw\" alt=\"\" \/><\/figure>\r\n\r\n\r\n\r\n<p>2<strong>. Verify Slack Notifications:<\/strong><\/p>\r\n\r\n\r\n\r\n<ul class=\"wp-block-list\">\r\n<li>Check your Slack channel to ensure notifications are being received as expected.<\/li>\r\n<\/ul>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/docsz\/AD_4nXcH6ecYQpJ3g58NlE8W0eOdovdhBzqg0nr28nETGLKCjy8youeBsCGC5TEqn1P21o1aN3LbOBkHPWwgi9bv_koUAj4kUrCUh-yVH9YELUKnK4SX2v1400RhOV8yvHJlvp9xXyl-iiLWjWcDkHiyioPKloE?key=18RgewjC-PeijjwThlOMSw\" alt=\"\" \/><\/figure>\r\n\r\n\r\n\r\n<h3 class=\"wp-block-heading\"><strong>Conclusion<\/strong><\/h3>\r\n\r\n\r\n\r\n<p>By following these steps, you have successfully set up a Lambda function to send notifications to Slack for IAM user creation and policy attachment events. This setup enhances security monitoring and provides real-time alerts for critical IAM changes.<\/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> \r\n\r\n<\/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>\u00a0<\/div>\r\n<div class=\"ch bg ew ex ey ez\">\r\n\r\n\r\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\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<\/div>\r\n\r\n\r\n\r\n<p class=\"has-text-align-center\"><strong>Connect With Us<\/strong><\/p>\r\n<\/div>\r\n","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: Prerequisites<\/p>\n","protected":false},"author":244582674,"featured_media":18708,"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],"tags":[118966],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2024\/07\/Lambda-Function-Setup-Guide-for-IAM-Event-Notifications-in-Slack.png","jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pfDBOm-4RC","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/18700"}],"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=18700"}],"version-history":[{"count":4,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/18700\/revisions"}],"predecessor-version":[{"id":18709,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/18700\/revisions\/18709"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media\/18708"}],"wp:attachment":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media?parent=18700"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/categories?post=18700"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/tags?post=18700"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}