Which user launched EC2 instance?
Assuming that you have configured CloudTrail already in your console (to monitor the right events) here's a possible solution to retrieve the username of who launched a certain EC2 instance, given the instance ID.
This solution uses the AWS CLI to retrieve information about which instances were launched, and jq for parsing.
When calling the aws cloudtrail lookup-events
function, we can specify:
- The name of the event. In this case, RunInstances.
- The date from which to start searching, start-date. This can be when the EC2 instance was launched.
- The date up to which to search, end-date. This can be just one minute after the instance was started.
First, let's define the instance id and the region variables:
$ instance_id="i-08dcc12c018737061"
$ region="us-east-1"
then, let's find out when the instance was launched:
$ instance_launch_date=$(aws ec2 describe-instances --instance-ids $instance_id --region $region | jq '.Reservations[].Instances[].LaunchTime')
$ echo $instance_launch_date
"2020-07-08T15:21:02.000Z"
now, let's sanitize the date so that it's in the right format for the CloudTrail API.
$ launch_date=$(sed -E 's/\"([0-9]{4})-([0-9]{2})-([0-9]{2}).([0-9]{2}):([0-9]{2}):([0-9]{2}).+/\2\/\3\/\1 \4:\5:\6/' <<< $instance_launch_date)
$ start_date=$(date -d "${launch_date}" +"%s")
$ echo $start_date
1594221662
now, let's define the end date as the date the instance was launched plus 1 minute:
$ end_date=$(date -d "${launch_date} 1 min" +"%s")
echo $end_date
1594221722
and now let's call the CloudTrail API, and filter the output with jq
:
aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=RunInstances --start-time $start_date --end-time $end_date --region $region | jq --arg INSTANCE_ID "$instance_id" '.Events[] | select(.CloudTrailEvent | fromjson | .responseElements.instancesSet.items[].instanceId | contains($INSTANCE_ID)) | .Username '
"paolo"
Unfortunately this information is not directly available via an API call - you currently have two options:
- depending on your needs, you could approximate your goal by using the DescribeInstances API action to look at the
key-name
used for starting that instance (if any, it's optional, though usually in place) - assuming you have followed security best practices and are using a dedicated EC2 key pair per IAM user (rather than sharing keys), the key should usually denote the user who started the instance ;)- that's most easily tested via the AWS Command Line Interface, specifically describe-instances
- nowadays you could activate AWS CloudTrail, which records AWS API calls for your account and delivers log files to you and provides exactly the information you are after:
The recorded information includes the identity of the API caller, the time of the API call, the source IP address of the API caller, the request parameters, and the response elements returned by the AWS service.
- most importantly, it isn't available in all regions yet, but AWS has just extended it to 3 more for a total of 5, see AWS CloudTrail Expands Again - More Locations and Services, thus quickly approaching coverage of their entire Global Infrastructure
- not all services are covered yet, but AWS hast just extended it to 7 more for a total of 15, see AWS CloudTrail Update - Seven New Services
- depending on your needs, you most likely want to have a Logging as a Service (LaaS) solution in place to ease digging through the vast amount of logs, and provide alerts etc. - several providers already offer dedicated CloudTrail integration (and usually a free tier sufficient for that as well)
- events are delivered within 15 minutes of the API call and the resulting logs to your S3 bucket approximately every 5 minutes, resulting in a maximum delay of 20 minutes, which is enough for post hoc and batch analysis, but not sufficient for near real-time alerting of course (see the AWS CloudTrail FAQ)