Ashish Mishra
Ashish Mishra

Reputation: 421

Determining EC2 instance public IP from SNS in lambda

I have a lambda function which SSH ec2 instance and run some commands. This lambda function is triggered from SNS topic. SNS topic is integrated with a cloudwatch alarm. I am using python 2.7 in lambda function followed this thread https://aws.amazon.com/blogs/compute/scheduling-ssh-jobs-using-aws-lambda/. is it possible to get EC2 public IP address which actually triggered alarm?

Upvotes: 0

Views: 3805

Answers (1)

Girolamo Piccinni
Girolamo Piccinni

Reputation: 146

It depends on the CloudWatch Alarm you are using to trigger the SNS publish. My suggestion is to print out the entire event dictionary in your function and check if there is any mention about EC2 instance ID.

In case of CloudWatch EC2 alarm (eg. CPU usage) you'll find the instance ID in the metric Dimension.

# Python example
import json
message = json.loads(event['Records'][0]['Sns']['Message'])
instance_id = message['Trigger']['Dimensions'][0]

If you have the instance ID you can easily retrieve the instance public IP using boto3 as follows:

# Python example
import boto3
instance_id = 'xxxx' # This is the instance ID from the event
ec2 = boto3.client('ec2')
instances = ec2.describe_instances(InstanceIds=[instance_id])
public_ip = instances[0]['Reservations'][0]['Instances'][0]['PublicIpAddress']

Finally, as you are performing SSH from Lambda function to your EC2 instance keep in mind that Lambda Functions out of VPC get a dynamic public IP therefore it is impossible to restrict your EC2 instance security group for SSH. Leaving SSH opened to the entire world is not a good practice from a security perspective.

I suggest to run both EC2 and Lambda function in VPC restricting SSH access to your EC2 instances from Lambda vpc security group only. In that case you'll need to retrieve the private Ip address rather than the public one to be able to ssh your instance (the python logic is the same as above, the only difference is that you use 'PrivateIpAddress' instead of 'PublicIpAddress') . This is way more secure than using public internet.

I hope this helps.

G

Upvotes: 4

Related Questions