How to create an IAM role for EC2
Topic: Accounts access
Summary
Create an IAM role that EC2 instances can assume via an instance profile: set the trust policy to ec2.amazonaws.com, attach least-privilege policies, and attach the instance profile to the instance. Use this so applications on EC2 access AWS APIs without access keys.
Intent: How-to
Quick answer
- Create an IAM role with trust policy Principal Service ec2.amazonaws.com; IAM creates an instance profile with the same name by default in the console.
- Attach managed or custom policies that grant only the actions your app needs (e.g. S3 read, Secrets Manager); avoid granting full admin to the instance role.
- Attach the instance profile to the EC2 instance at launch or later; the instance receives temporary credentials via the metadata service with no keys on disk.
Prerequisites
Steps
-
Create the role with EC2 trust policy
In IAM → Roles → Create role, choose AWS service → EC2; the trust policy will allow ec2.amazonaws.com to assume the role. Name the role (e.g. app-prod-ec2-role).
-
Attach permission policies
Attach policies for the workload (e.g. AmazonS3ReadOnlyAccess, or a custom policy for specific buckets and Secrets Manager); use least privilege per instance type or app.
-
Create or use the instance profile
In the console, the instance profile is created with the same name as the role when you choose EC2; via CLI create the role then create-instance-profile and add-role-to-instance-profile.
-
Attach profile to the instance
At launch, select the instance profile in the instance configuration; for an existing instance, associate the instance profile (replace any existing) so the instance gets the role credentials.
Summary
You will create an IAM role for EC2 with a trust policy for the EC2 service, attach least-privilege permissions, and attach the role via an instance profile to the instance. Use this so applications on EC2 call AWS APIs without storing access keys on the instance.
Prerequisites
- IAM permissions to create roles, instance profiles, and attach policies (iam:CreateRole, iam:CreateInstanceProfile, iam:AddRoleToInstanceProfile, iam:AttachRolePolicy).
- EC2 instances (or launch templates) you can modify to use the instance profile.
Steps
Step 1: Create the role with EC2 trust policy
Console: IAM → Roles → Create role. Under Trusted entity type choose AWS service, then EC2. Click Next; the trust policy will look like:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}
CLI:
aws iam create-role --role-name app-prod-ec2-role \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}'
Step 2: Attach permission policies
Attach only the policies the application needs:
aws iam attach-role-policy --role-name app-prod-ec2-role \
--policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
For custom scope (e.g. one bucket, Secrets Manager), create a custom policy and attach it. Avoid AdministratorAccess unless required.
Step 3: Create or use the instance profile
Console: When you create the role and choose EC2, the wizard creates an instance profile with the same name as the role and adds the role to it.
CLI (if you created the role separately):
aws iam create-instance-profile --instance-profile-name app-prod-ec2-role
aws iam add-role-to-instance-profile --instance-profile-name app-prod-ec2-role --role-name app-prod-ec2-role
Step 4: Attach profile to the instance
Console: EC2 → Instances → Select instance → Actions → Security → Modify IAM role → Select the role (instance profile) → Update. For new instances, choose the IAM role in the launch wizard.
CLI (existing instance):
aws ec2 associate-iam-instance-profile --instance-id i-xxxxx --iam-instance-profile Name=app-prod-ec2-role
To replace an existing profile, use replace-iam-instance-profile-association. After attachment, the instance receives temporary credentials via the instance metadata service (IMDS) at http://169.254.169.254/latest/meta-data/iam/security-credentials/.
Verification
- From the EC2 instance:
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/returns the role name. Runningaws sts get-caller-identity(with default credential chain) should return the role ARN. - The application can call the AWS APIs allowed by the role (e.g. S3 list/get) without any access keys in config or environment.
Troubleshooting
No credentials available on instance — Ensure the instance profile is attached (EC2 → instance → Security tab → IAM role). It can take a short time after attach; ensure IMDS is available (IMDSv2 may require token). Restart the app so it picks up the new credentials.
Access denied when calling AWS APIs — The role’s policies may not grant the action or resource. Add the required permission to the role; check for SCP or permission boundaries. Simulate the role’s permissions with the policy simulator.
Instance profile name differs from role name — The instance profile name is what you attach to the instance; the profile must contain the role. List with aws iam get-instance-profile --instance-profile-name NAME to confirm the role is included.