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
- Replace the example instance IDs and process names in the
instances
dictionary with your actual values. - 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
- Update the
instances
andinstance_names
dictionaries with your actual instance IDs and desired server names. - Ensure the instance IDs in both dictionaries match correctly.
- 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.