Python

import boto3
import json

ssm_client = boto3.client('ssm')
sns_client = boto3.client('sns')

def lambda_handler(event, context):
    # Define instances and their corresponding processes
    instances = {
        'instance-id-1': ['process1', 'process2'],
        'instance-id-2': ['process3', 'process4', 'process5'],
        'instance-id-3': ['process6']
    }

    for instance_id, process_names in instances.items():
        for process_name in process_names:
            command = f'ps aux | grep {process_name} | grep -v grep'

            response = ssm_client.send_command(
                InstanceIds=[instance_id],
                DocumentName='AWS-RunShellScript',
                Parameters={'commands': [command]}
            )

            command_id = response['Command']['CommandId']

            waiter = ssm_client.get_waiter('command_executed')
            waiter.wait(CommandId=command_id, InstanceId=instance_id)

            output = ssm_client.get_command_invocation(
                CommandId=command_id,
                InstanceId=instance_id
            )

            if output['StandardOutputContent']:
                print(f'Process {process_name} is running on instance {instance_id}')
            else:
                print(f'Process {process_name} is NOT running on instance {instance_id}')
                sns_client.publish(
                    TopicArn='your-sns-topic-arn',
                    Message=f'Process {process_name} is NOT running on instance {instance_id}'
                )

    return {
        'statusCode': 200,
        'body': json.dumps('Process monitoring completed.')
    }

Changes made

  • An instances dictionary is introduced to store the instance IDs and their corresponding process lists.
  • The code iterates through this dictionary, executing the process check for each instance and its associated processes.

For SNS Implementation

  1. Replace the example instance IDs and process names in the instances dictionary with your actual values.
  2. The rest of the implementation steps remain the same.

This modified script now allows you to monitor different processes across multiple EC2 instances, providing a more flexible and scalable solution.

Python

import boto3
import json

ssm_client = boto3.client('ssm')
sns_client = boto3.client('sns')

def lambda_handler(event, context):
    # Define instances and their corresponding processes
    instances = {
        'instance-id-1': ['process1', 'process2'],  # Replace instance-id-1 with the actual instance ID
        'instance-id-2': ['process3', 'process4', 'process5']  # Replace instance-id-2 with the actual instance ID
    }

    # Define instance name mapping
    instance_names = {
        'instance-id-1': 'Server1',  # Replace instance-id-1 with the actual instance ID
        'instance-id-2': 'Server2'  # Replace instance-id-2 with the actual instance ID
    }

    for instance_id, process_names in instances.items():
        for process_name in process_names:
            command = f'ps aux | grep {process_name} | grep -v grep'

            response = ssm_client.send_command(
                InstanceIds=[instance_id],
                DocumentName='AWS-RunShellScript',
                Parameters={'commands': [command]}
            )

            command_id = response['Command']['CommandId']

            waiter = ssm_client.get_waiter('command_executed')
            waiter.wait(CommandId=command_id, InstanceId=instance_id)

            output = ssm_client.get_command_invocation(
                CommandId=command_id,
                InstanceId=instance_id
            )

            if output['StandardOutputContent']:
                print(f'Process {process_name} is running on instance {instance_id}')
            else:
                print(f'Process {process_name} is NOT running on instance {instance_id}')
                # Get server name from mapping
                server_name = instance_names.get(instance_id, instance_id)  # Use instance ID if not found in mapping
                sns_client.publish(
                    TopicArn='your-sns-topic-arn',
                    Message=f'Process {process_name} is NOT running on {server_name}'
                )

    return {
        'statusCode': 200,
        'body': json.dumps('Process monitoring completed.')
    }

Changes made

  • An instance_names dictionary maps instance IDs to their desired names (e.g., ‘Server1’, ‘Server2’).
  • When publishing to SNS, the code retrieves the server name from this mapping using instance_names.get(instance_id, instance_id). This allows it to use the friendly name if found, or fall back to the instance ID if not.

Implementation

  1. Update the instances and instance_names dictionaries with your actual instance IDs and desired server names.
  2. Ensure the instance IDs in both dictionaries match correctly.
  3. The rest of the implementation remains the same.

With this update, your SNS alerts will now use the more readable server names instead of raw instance IDs, making it easier to identify the affected server.

By DSD