Start with this mental model
An IAM policy is JSON that states permissions. It can allow or explicitly deny actions such as reading an S3 object, starting an EC2 instance, or using a KMS key. A policy does not sign in, run code or make a request by itself.
An IAM role is an AWS identity with a trust policy. A trusted principal—such as an EC2 instance, Lambda function, AWS service, federated employee, or another AWS account—can assume the role. AWS then issues temporary credentials for that role. Permission policies attached to the role determine what those credentials can do.
Example 1: EC2 application reading a private S3 bucket
A web application on EC2 must read product images from a private S3 bucket. The secure architecture is to create an IAM role for EC2, attach a least-privilege policy allowing s3:GetObject only on the required bucket path, and attach the role to the instance profile.
The application retrieves temporary credentials automatically. It does not need an access key written into source code, environment files or an AMI. In an exam question, “remove embedded credentials” or “give an EC2 workload S3 access” strongly points to an IAM role.
Example 2: Cross-account audit access
Account A owns application workloads. Account B owns the central audit team. Create an audit role in Account A with a trust policy allowing the audit principal from Account B to assume it. Attach a read-only policy to that role. The audit team assumes the role only when needed and gains temporary access.
This is preferable to sharing a long-lived IAM user credential across accounts. It also supports clear logging in CloudTrail and easy removal of access.
Example 3: Lambda writing to DynamoDB
A Lambda function must add records to one DynamoDB table. Attach a Lambda execution role with the minimum DynamoDB actions required, such as PutItem. The Lambda service assumes the role when it runs. The policy is the permission; the role is the identity used by the function.
Real-world scenario: “AccessDenied” after moving an app to EC2
Situation: A team moved a product catalogue application from a developer laptop to an EC2 instance. The app loaded, but image downloads from its private S3 bucket failed with AccessDenied.
The application had no AWS identity
The developer had used local credentials during testing. Copying those credentials onto EC2 would create a security risk.
Error: AccessDenied\nAction: s3:GetObject\nResource: arn:aws:s3:::catalog-images/*\nCause: no identity-based policy allows this actionUse an EC2 IAM role with least privilege
The team created an EC2 role, trusted the EC2 service, attached it through an instance profile, and granted read-only access to the one required bucket path.
{ "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::catalog-images/*" }Do not fix workload access by storing an access key on a server. Give the workload an IAM role, grant only the required actions and resources, and let AWS provide temporary credentials automatically.
Illustrative training scenario and console-style examples—not a customer screenshot or production account.SAA-C03 exam clues: when to choose a role
- Temporary access: Roles are designed for temporary credentials.
- AWS service access: EC2, Lambda, ECS tasks and other AWS services commonly use roles.
- Cross-account access: Use a role with a trust relationship instead of sharing credentials.
- Federated workforce: Users authenticated through an identity provider can assume roles.
- Least privilege: Attach only the policy actions and resources the workload needs.
Look carefully for the trusted principal. The trust policy answers “who can assume this role?” The attached permission policy answers “what can that assumed role do?”
Common mistakes to avoid
- Putting long-lived access keys in application code instead of using a workload role.
- Using an overly broad policy such as unrestricted administrator access for a single application.
- Confusing a role’s trust policy with its permission policy.
- Assuming an explicit allow can override an explicit deny. It cannot—explicit deny wins.
- Giving cross-account access by creating shared IAM users rather than an assumable role.
Quick answer rule
If the question asks who or what needs temporary AWS access, think role. If it asks which actions are allowed on which resources, think policy. Most real architectures use both together.
Frequently asked questions
What is the simplest difference between an IAM role and an IAM policy?
A policy is a permission document: it says what actions are allowed or denied. A role is an AWS identity that can be assumed temporarily. Attach policies to a role to give the assumed identity its permissions.
Can an IAM role have more than one policy?
Yes. A role can use AWS managed policies, customer managed policies and inline policies. The final effective permissions are evaluated together, with explicit denies taking priority.
When should an EC2 application use an IAM role?
Use an IAM role whenever the application needs AWS access. The instance receives temporary credentials through the role instead of storing an access key in code, configuration or a server.
Is an IAM role the same as an IAM user?
No. An IAM user normally represents a long-term person or workload identity. A role is assumed when needed and provides temporary credentials. For AWS services and cross-account access, roles are usually the safer choice.