Streamlining Governance Notifications in AWS Organizations with Automation

In the ever-evolving world of AWS, maintaining the security and organization of your accounts is paramount. If you’re managing multiple AWS accounts within an AWS Organization, you might be concerned about tracking changes such as the movement of an account from one Organizational Unit (OU) to another.

Fortunately, AWS offers robust tools to help you keep tabs on these changes. In this blog post, we’ll explore how you can use a serverless Lambda function in conjunction with AWS CloudTrail and CloudWatch to be promptly notified whenever an account is moved from one OU to another.

Understanding the AWS Organization

AWS Organizations simplifies the management of multiple AWS accounts. It enables you to organize accounts into OUs, allowing you to better control access policies, billing, and resource sharing. However, with great power comes the need for oversight.

The Tools at Your Disposal

  1. AWS CloudTrail: CloudTrail records all API calls in your AWS account. By enabling it at the Organization level, you can track every change within the Organization, including account relocations.
  2. AWS CloudWatch Events: CloudWatch Events allow you to respond to changes in your AWS environment. By creating rules that trigger on specific CloudTrail events, you can respond in real-time.
  3. AWS Lambda: Lambda is a serverless compute service that allows you to run code without provisioning or managing servers. It’s the glue that ties everything together in our solution.

The Lambda Function

The first step in this process is to create a Lambda function that will be triggered by a CloudWatch Event. This function should be equipped to parse the event, extract relevant information, and send out notifications when an account is moved between OUs.

Here’s a high-level overview of the Lambda function’s steps:

  1. Receive the CloudTrail event.
  2. Parse the event to identify changes in OU memberships.
  3. If the event indicates an account relocation, send out a notification using your preferred method (e.g., email, SNS, Slack).
import json
import boto3

def get_ou_name(ou_id):
    org_client = boto3.client('organizations')
    response = org_client.describe_organizational_unit(OrganizationalUnitId=ou_id)
    return response['OrganizationalUnit']['Name']

# extract_user_domain function
def extract_user_domain(principal_id):
    parts = principal_id.split(':')
    if len(parts) == 2:
        return parts[1]
    return "Unknown"

def lambda_handler(event, context):
    
    sns_topic_arn = "arn:aws:sns:us-east-1:xxxx1234xxxx:notify_on_move_account_sns"

    #if event detail has MoveAccount, then grab source and destination ou and send email via sns
    if event['detail']['eventName'] == 'MoveAccount':
        # Parse the CloudTrail event details
        source_ou_id = event['detail']['requestParameters']['sourceParentId']
        destination_ou_id = event['detail']['requestParameters']['destinationParentId']
        account_id = event['detail']['requestParameters']['accountId']
        principal_id=event['detail']['userIdentity']['principalId']
        user_domain = extract_user_domain(principal_id)
        
        source_ou_name = get_ou_name(source_ou_id)
        destination_ou_name = get_ou_name(destination_ou_id)

        # Prepare the email notification message
        
        message = f"CloudTrail event occurred: MoveAccount\n"
        message += f"Account ID: {account_id}\n"
        message += f"Source OU: {source_ou_name} (ID: {source_ou_id})\n"
        message += f"Destination OU: {destination_ou_name} (ID: {destination_ou_id})\n"
        message += f"Account Moved By: {user_domain}" 
        # Send email notification
        sns_client = boto3.client("sns")
        sns_client.publish(TopicArn=sns_topic_arn, Message=message)

    return {
        "statusCode": 200,
        "body": json.dumps("Email sent successfully")
    }

Here, you define a function get_ou_name(ou_id) that retrieves the name of an Organizational Unit (OU) based on its ID using the AWS Organizations client. This function will help you translate OU IDs into human-readable OU names.

This function extract_user_domain(principal_id) is used to extract the user or domain from the “principalId” field in the CloudTrail event. It splits the “principalId” on the colon character and, if two parts exist, it returns the second part, which typically represents the user or domain. If there are not two parts, it returns “Unknown.”

In the lambda_handler function, you specify the ARN (Amazon Resource Name) of the AWS Simple Notification Service (SNS) topic that will be used for sending notifications. Make sure to replace "arn:aws:sns:us-east-1:xxxx1234xxxx:notify_on_move_account_sns" with the actual ARN of your SNS topic.

The IF condition, checks if the CloudTrail event’s “eventName” is equal to ‘MoveAccount’, which indicates that an AWS account is being moved within your AWS Organization. If true then the logic extract details from the CloudTrail event. It collects the source OU ID, destination OU ID, the AWS account ID that’s being moved, and the “principalId” field to identify the user responsible for the move. It also uses the get_ou_name function to convert OU IDs into OU names.


Setting Up CloudWatch Rules

With the Lambda function ready, you can create a CloudWatch Event rule. This rule specifies the conditions under which the Lambda function should be triggered. In this case, you’ll want to create a rule that captures events related to account movements within your AWS Organization.


Setting Up SNS

Configure an Amazon SNS (Simple Notification Service) topic and a subscription to roll out email notifications whenever an AWS account move is triggered by a Lambda function, follow these steps:

  1. Create an SNS Topic:
    • Log in to the AWS Management Console.
    • Navigate to the Amazon SNS service.
    1. Click on “Topics” in the SNS dashboard.
    2. Click the “Create topic” button.
    • Provide a name and a display name for your SNS topic.
    • Optionally, add any tags to help organize your topics.
    • Click “Create topic.”
  2. Create an Email Subscription:
    • After creating the SNS topic, select the topic you just created.
    1. Click the “Create subscription” button.
    2. Choose “Email” as the protocol.
    3. Enter the email addresses of the recipients you want to notify about account moves. You can add multiple email addresses, separating them with commas.
    4. Click “Create subscription.”
    • You will receive a confirmation email at the specified email addresses. Follow the link in the email to confirm the subscription.

TESTING

Test your Lambda function to ensure that it publishes messages to the SNS topic when an account move is triggered. You should receive email notifications at the specified email addresses.


Overall, automating AWS account move notifications is a value-add because it enhances operational efficiency, improves security, and ensures compliance, ultimately contributing to a well-managed and accountable AWS environment. It streamlines the communication process and allows organizations to respond more effectively to changes within their cloud infrastructure.

Leave a comment