Check if switching AmazonEC2RoleforSSM to AmazonSSMManagedInstanceCore causes any issues

Check if switching AmazonEC2RoleforSSM to AmazonSSMManagedInstanceCore causes any issues

Are you considering switching the IAM role attached to EC2 from the deprecated policy "AmazonEC2RoleforSSM" to "AmazonSSMManagedInstanceCore"? Here is a summary of the permission differences and how to verify a safe migration.
2026.07.31

This page has been translated by machine translation. View original

Introduction

Hello everyone, this is Akaike.

Have you ever encountered a managed policy called AmazonEC2RoleforSSM in an IAM role attached to EC2?
I have.

This policy has been announced as deprecated, and replacing it with AmazonSSMManagedInstanceCore is recommended. However, when it actually comes time to switch, I found myself thinking, "This change reduces permissions, so I'm worried it might break something that's currently working..."

With that in mind, this time I've put together a summary of the permission differences between both policies, along with methods to verify whether switching from AmazonEC2RoleforSSM to AmazonSSMManagedInstanceCore is safe.

AmazonEC2RoleforSSM and AmazonSSMManagedInstanceCore

Before getting into the main topic, let me organize what the relationship between these two policies actually is.

Simply put, here is how they are positioned:

  • AmazonEC2RoleforSSM (old)
    • In addition to core Systems Manager features, includes a broad range of permissions such as Session Manager, domain joining, CloudWatch, and command output to S3
  • AmazonSSMManagedInstanceCore (new)
    • Contains only the minimum permissions necessary for core Systems Manager functionality

AWS announced the deprecation of AmazonEC2RoleforSSM as of 2019, and replacing it with the least-privilege AmazonSSMManagedInstanceCore is recommended.

https://dev.classmethod.jp/articles/not-recommended-amazonec2roleforssm/
https://dev.classmethod.jp/articles/check-amazonec2roleforssm-policy/
https://aws.amazon.com/blogs/mt/applying-managed-instance-policy-best-practices/

Of course, since it is merely deprecated, permissions for roles that already have it attached will not be immediately revoked. However, it is a good idea to proceed with replacing it with AmazonSSMManagedInstanceCore at times when you are recreating resources, such as when building new servers or rebuilding servers due to OS updates.

Permission differences between both policies

As mentioned above, AmazonSSMManagedInstanceCore only covers core functionality and Session Manager, so if you are using other features, additional policies will be required. This is the most important point when switching.

When comparing the actual policy JSON, the differences that arise from switching are as follows:

Permissions added in AmazonSSMManagedInstanceCore

ssm:GetParameter

Permissions removed in AmazonSSMManagedInstanceCore

cloudwatch:PutMetricData

ec2:DescribeInstanceStatus

ds:CreateComputer
ds:DescribeDirectories

logs:CreateLogGroup
logs:CreateLogStream
logs:DescribeLogGroups
logs:DescribeLogStreams
logs:PutLogEvents

s3:GetBucketLocation
s3:PutObject
s3:GetObject
s3:GetEncryptionConfiguration
s3:AbortMultipartUpload
s3:ListMultipartUploadParts
s3:ListBucket
s3:ListBucketMultipartUploads

The added ssm:GetParameter does not need to be a concern,
but the ones on the removed side can potentially cause issues, each corresponding to the following use cases:

  • ds:*
    • Seamless Domain Join (joining EC2 to an Active Directory domain)
  • cloudwatch:PutMetricData / logs:*
    • Sending metrics and logs via the CloudWatch agent, and outputting Session Manager and Run Command logs to CloudWatch Logs
  • s3:*
    • Outputting Session Manager session logs and Run Command execution results to an S3 bucket
  • ec2:DescribeInstanceStatus
    • Referencing instance status

If you are not using these permissions in your setup, switching to AmazonSSMManagedInstanceCore will have no impact.
Conversely, if you are using the above features, you will need to additionally attach the corresponding policies (AmazonSSMDirectoryServiceAccess, CloudWatchAgentServerPolicy, a custom policy for S3, etc.) at the same time as switching.

The contents of both policies are as follows:

Investigation methods

Now that we understand the differences, let's verify "whether switching is safe."

What to do is simple: confirm that the target role is not actually using the permissions being removed (ds:*, cloudwatch:PutMetricData, logs:*, s3:*, ec2:DescribeInstanceStatus).

There are two main approaches for verification:

  • Code base
    • Statically verify from the code base (IaC and configurations) that no features depending on the removed permissions are being used
  • API execution history
    • Verify from CloudTrail that the role has not actually called the relevant APIs

Since relying on only one approach can lead to oversights, it is recommended to combine both.

Code base

First, check from the code base and configurations that no features related to the removed permissions are being used.
Specifically, check from the following perspectives:

  • Is AmazonEC2RoleforSSM being directly referenced in IaC (CloudFormation, Terraform, etc.) or EC2 launch templates?
    • If so, updating the reference will also be necessary at the time of switching
  • Is the configuration set to output Session Manager session logs or Run Command execution results to an S3 bucket or CloudWatch Logs?
    • Check the Session Manager settings (Preferences) and the log output destination settings when executing Run Command
    • If outputting, s3:* and logs:* will be required
  • Is the CloudWatch agent installed?
    • If so, cloudwatch:PutMetricData and logs:* will be required
  • Is Active Directory domain joining (Seamless Domain Join) for EC2 being used?
    • If so, ds:* will be required

For any features identified as "in use" here, simply add the corresponding policies (CloudWatchAgentServerPolicy, AmazonSSMDirectoryServiceAccess, a custom policy for S3) at the same time as switching.

API execution history

Along with verification from the code base, it is reassuring to also cross-check with actual API execution history.

Here, use CloudTrail to verify from the event history that the target instance has not previously called APIs corresponding to the permissions being removed.

In the CloudTrail event history screen, it is easy to narrow down by specifying the role session name in Username or the API name in Event name.
When checking from the CLI, you can search the call history for specific APIs with commands like the following:

# Example: Search call history for ds:CreateComputer (domain join) (last 90 days, management events)
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=CreateComputer \
  --start-time "$(date -u -d '90 days ago' +%Y-%m-%dT%H:%M:%SZ)" \
  --query 'Events[].{Time:EventTime,User:Username,Event:EventName}' \
  --output table
# Example: Search for API calls from a specific EC2 (instance ID)
#     Since the instance ID is included in the session name for EC2 roles, narrow down by that
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=Username,AttributeValue=i-0123456789abcdef0 \
  --start-time "$(date -u -d '90 days ago' +%Y-%m-%dT%H:%M:%SZ)" \
  --query 'Events[].{Time:EventTime,User:Username,Event:EventName}' \
  --output table

If no calls to the relevant APIs are found, it can be judged that those permissions are likely not being used.

Notes

When checking with CloudTrail, please note the following two points:

  • S3 object operations (such as s3:PutObject) are classified as data events and are not recorded by default. For determining whether output to S3 is occurring, rely primarily on the code base verification.
  • aws cloudtrail lookup-events (event history) can only look back management events for the last 90 days. If you want to cover a longer period, consider using Trails or CloudTrail Lake.

For details, refer to CloudTrail management events and data events.

Supplement: Also leverage IAM Access Advisor

As a supplementary check, IAM last accessed information (Access Advisor) is also useful.

This is a feature that shows which services an IAM role last accessed, and if there is no access record to AWS services for the target role, it serves as a basis for judging that those permissions are not being used.

While it has service-level granularity rather than CloudTrail's detail, it can be checked immediately without any additional setup, making it well-suited for initial assessment.

From the detail screen of the policy attached to the target role, open the Last accessed tab to see a list of the last access date and time for each service permitted by that policy.

スクリーンショット 2026-07-31 22.22.56

The screen above is for AmazonEC2RoleforSSM. Services corresponding to permissions removed by the switch—such as CloudWatch, Directory Service, S3, and CloudWatch Logs—all show Not accessed during the tracking period, which serves as evidence that these features are not being used.

Furthermore, clicking on a service name allows you to drill down and check which roles (entities) accessed that service and when.

スクリーンショット 2026-07-31 22.23.54

This is the screen for opening Access by members for AWS Systems Manager.
Since the number of days since last access is displayed per role (343 days ago, 390 days ago, and 450 days ago in this example), you can individually understand which roles are actually being used.

Conclusion

That concludes the methods for verifying whether it is safe to switch from AmazonEC2RoleforSSM to AmazonSSMManagedInstanceCore.
I hope this serves as a helpful reference for those who will be proceeding with policy migration in the future.

Share this article

AWSのお困り事はクラスメソッドへ