This chapter covers IAM Roles for AWS Services, a critical security mechanism that allows AWS services like EC2, Lambda, and ECS to securely access other AWS resources without using long-term credentials. For the CLF-C02 exam, this falls under Domain 2: Security and Compliance (Objective 2.2), which carries approximately 25% of the exam weight. Understanding how roles work, when to use them, and common misconfigurations is essential for passing the exam and building secure AWS architectures.
Jump to a section
Imagine you are the owner of a large office building. You have a master key that opens every door, but you don't want to give that key to the cleaning crew, the mail carrier, or the IT technician. Instead, you create special valet keys that only open specific doors during specific hours. For the cleaning crew, you create a key that opens the janitor closet and the break room from 6 PM to 10 PM. For the mail carrier, a key that opens the front door and the mailroom from 9 AM to 5 PM. These valet keys are not physical; they are digital permissions that you issue to each person based on their role. Now, think of AWS services like EC2 or Lambda as the people needing access to resources. Instead of hardcoding your master key (long-term credentials) into each service, you create a valet key (an IAM role) that grants exactly the permissions needed, for a limited time, and automatically rotates the key. The service assumes the role to get temporary credentials from AWS STS, just like the cleaning crew uses their valet key to enter only the allowed doors. If someone steals the valet key, it expires quickly, limiting damage. This is exactly how IAM roles for AWS services work: they provide temporary, scoped-down credentials for services to securely access other AWS resources without embedding long-lived access keys.
What is an IAM Role for AWS Services?
An IAM role is an AWS identity with permissions policies that determine what the role can do and what it cannot do. Unlike an IAM user, a role is not associated with a specific person or service permanently. Instead, trusted entities assume the role to obtain temporary security credentials from AWS Security Token Service (STS). When we talk about IAM roles for AWS services, we mean roles that are designed to be assumed by AWS services themselves, such as Amazon EC2, AWS Lambda, AWS CodeBuild, or Amazon ECS. This allows the service to perform actions on your behalf, like reading data from S3 or writing logs to CloudWatch.
The Problem IAM Roles Solve
Before IAM roles became popular, developers often embedded long-term access keys (Access Key ID and Secret Access Key) directly into application code, configuration files, or environment variables. This practice is dangerous because:
Keys can be accidentally exposed in code repositories or logs.
Keys never expire unless manually rotated.
If an attacker gains access to the keys, they have the permissions until the keys are revoked.
IAM roles solve this by providing temporary credentials that are automatically rotated and never stored in code. The service obtains credentials dynamically when needed, and they expire after a configurable duration (default 1 hour, max 12 hours for most services).
How It Works: The Mechanism
1. Create an IAM Role: You define a role with two types of policies:
- Trust Policy: Specifies which entities (services, accounts, or users) can assume the role. For an AWS service role, the trusted entity is the service principal (e.g., ec2.amazonaws.com).
- Permissions Policy: Defines what actions the role can perform on which resources (e.g., s3:GetObject on a specific bucket).
2. Attach the Role to the Service: Depending on the service, you attach the role at resource creation time or runtime: - EC2: You create an instance profile (a container for the role) and associate it with the EC2 instance at launch. - Lambda: You specify the execution role when creating the function. - ECS: You specify a task role for the ECS task definition.
Service Assumes the Role: When the service needs to make an API call, it calls the STS AssumeRole API (or a service-specific variant like AssumeRoleWithWebIdentity). The service sends its own credentials (e.g., the instance metadata service for EC2) to prove its identity.
Temporary Credentials: STS returns a set of temporary credentials: an Access Key ID, a Secret Access Key, and a Session Token. These credentials are valid for a limited time (default 1 hour, configurable). The service then uses these credentials to make AWS API calls.
Automatic Rotation: Before the credentials expire, the service can request new ones. The SDKs typically handle this automatically.
Types of IAM Roles for Services
AWS Service Role: A role that a service assumes to perform actions on your behalf. Example: an EC2 instance role that allows the instance to read from S3.
AWS Service Role for EC2: Specifically for EC2 instances, attached via an instance profile.
Service-Linked Role: A predefined role linked to a specific AWS service that includes all permissions the service needs to call other services on your behalf. These roles are created automatically by the service when you enable certain features (e.g., AWS Organization's AWSServiceRoleForOrganizations). You cannot delete a service-linked role until you delete the service resources that depend on it.
Key Configurations and Limits
Maximum session duration: For most roles, the session duration can be set between 15 minutes and 12 hours. The default is 1 hour.
Trust Policy: Must specify the service principal (e.g., ec2.amazonaws.com) or an AWS account ID. You can also add conditions like MFA.
Permissions Boundary: An advanced feature that sets the maximum permissions a role can have.
Instance Profile: For EC2, you must create an instance profile (a container for the role) and associate it with the instance. One instance can have only one instance profile, but an instance profile can contain only one role.
Comparison to On-Premises
In on-premises environments, applications often use service accounts with long-lived passwords or certificates. Managing these accounts is cumbersome: they need to be rotated, stored securely, and audited. In AWS, IAM roles eliminate these overheads by providing temporary, automatically rotated credentials. Additionally, roles are centrally managed in IAM, and all API calls made using the role are logged in AWS CloudTrail for auditing.
When to Use IAM Roles vs Alternatives
IAM Users: Use for human users or applications that need long-term credentials (e.g., a CI/CD tool running outside AWS). Avoid for services running inside AWS.
IAM Roles: Use for AWS services (EC2, Lambda, ECS, etc.) and for cross-account access. Also use for federated users (e.g., employees logging in via SAML).
Resource-Based Policies: Some services (like S3, SQS, SNS) allow you to attach policies directly to the resource, granting access to principals (users, roles, accounts). These are complementary to roles.
Service Control Policies (SCPs): Used in AWS Organizations to set permission guardrails across accounts. They do not grant permissions but can restrict what roles can do.
Best Practices
Least Privilege: Grant only the permissions required for the service to function. For example, if an EC2 instance only needs to read from a specific S3 bucket, do not grant s3:*.
Use Service-Linked Roles When Available: They contain the exact permissions the service needs and are maintained by AWS.
Rotate Roles: Although credentials are temporary, you should periodically review and update permissions policies.
Monitor with CloudTrail: Track who assumed the role and what actions were performed.
Common Exam Scenarios
The CLF-C02 exam often tests the difference between IAM users and roles, especially in the context of EC2 and Lambda. You may see a question like: "An application running on an EC2 instance needs to access an S3 bucket. What is the most secure way to provide credentials?" The answer is always "Create an IAM role with the necessary permissions and attach it to the EC2 instance via an instance profile." Wrong answers include "Store access keys in the application code" or "Use the root user credentials."
Create an IAM Role
Navigate to the IAM console in AWS. Click on 'Roles' and then 'Create role'. Select 'AWS service' as the trusted entity type. Choose the service that will use the role, e.g., EC2. This will automatically set the trust policy to allow the EC2 service principal to assume the role. Then, attach a permissions policy that grants the necessary actions. For example, attach the `AmazonS3ReadOnlyAccess` policy if the EC2 instance needs to read from S3. You can also create a custom policy. Click 'Next', give the role a name like 'EC2-S3-ReadRole', and create it. Behind the scenes, AWS creates a trust policy document that specifies `ec2.amazonaws.com` as the principal, and the permissions policy is attached. The role is now ready to be used.
Attach Role to EC2 Instance
To use the role with an EC2 instance, you need to create an instance profile. When you create the role via the console, AWS automatically creates an instance profile with the same name. When launching a new EC2 instance, you can select the instance profile under 'IAM role' in the 'Configure Instance Details' step. For existing instances, you can attach the instance profile by stopping the instance, modifying the IAM role, and starting it again. Note: You cannot attach a role to a running instance directly; you must stop it first. Once attached, the EC2 instance can retrieve temporary credentials from the instance metadata service at `http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name`. Any application running on the instance can use these credentials automatically via the AWS SDK.
Service Assumes the Role
When an application on the EC2 instance makes an AWS API call (e.g., `aws s3 ls`), the AWS SDK automatically contacts the instance metadata service to obtain temporary credentials. It calls `sts:AssumeRole` with the role's ARN. STS validates the request against the trust policy. If the service principal matches (ec2.amazonaws.com) and any conditions are met, STS returns a set of temporary credentials: an Access Key ID, a Secret Access Key, and a Session Token. These credentials are valid for the session duration (default 1 hour). The SDK then uses these credentials to sign the API call. The entire process is transparent to the developer; no keys are stored in the code.
Automatic Credential Refresh
Before the temporary credentials expire, the AWS SDK automatically requests new credentials. It monitors the expiration time (usually 5 minutes before expiry) and calls `AssumeRole` again to get a fresh set. This ensures continuous access without any manual intervention. The default session duration for EC2 roles is 1 hour, but you can configure it up to 12 hours. If the role is used in a Lambda function, the credentials are refreshed for each invocation, but the function execution context may reuse credentials across invocations. The SDK handles this seamlessly.
Audit with CloudTrail
All API calls made using the role are logged in AWS CloudTrail. You can view who assumed the role (the EC2 instance ID) and what actions were performed. For example, a CloudTrail log entry will show the `userIdentity` as the role ARN and the `sourceIPAddress` as the instance's private IP. This is crucial for security auditing and troubleshooting. You can also set up CloudWatch alarms on specific actions. Additionally, IAM Access Analyzer can help identify roles that grant overly permissive access.
Scenario 1: Web Application on EC2 Reading from S3
A company runs a web application on EC2 instances that serves user-uploaded images stored in an S3 bucket. To access the images, the application needs read-only permissions on the bucket. The security team mandates that no long-term credentials be stored on the instances. They create an IAM role with an S3 read-only policy and attach it to the EC2 instances via an instance profile. The application uses the AWS SDK, which automatically retrieves temporary credentials from the instance metadata service. This ensures that even if an instance is compromised, the attacker only gets temporary credentials that expire quickly. Cost is minimal as there is no additional charge for IAM roles. Misconfiguration could occur if the role is granted s3:* instead of s3:GetObject, allowing an attacker to delete or overwrite data. In production, the team also uses S3 bucket policies to restrict access to only the role's ARN, adding an extra layer of security.
Scenario 2: Lambda Function Processing Data from DynamoDB
A data processing pipeline uses AWS Lambda to read records from a DynamoDB table, transform them, and write results to another DynamoDB table. The Lambda function needs read/write access to both tables. Instead of hardcoding access keys, the developer creates an IAM role for Lambda (execution role) with policies that grant dynamodb:GetItem, dynamodb:PutItem, etc., on the specific table ARNs. The role is specified when creating the Lambda function. When the function is invoked, Lambda automatically assumes the role and provides temporary credentials. This pattern avoids credential exposure and simplifies key rotation. A common mistake is granting dynamodb:* to all tables, which violates least privilege. The team uses IAM policy conditions to restrict access based on table name. Cost is negligible; the only cost is the Lambda execution. Misconfiguration can lead to data leakage or unauthorized modifications.
Scenario 3: Cross-Account Access with Roles
A company has a centralized logging account and multiple application accounts. Applications running on EC2 in the app accounts need to write logs to an S3 bucket in the logging account. Instead of creating IAM users in the logging account, they create an IAM role in the logging account with a trust policy that allows the app account's EC2 role to assume it. The EC2 role in the app account has permissions to call sts:AssumeRole on the logging account role. The application then assumes the cross-account role to get credentials for writing to S3. This maintains security boundaries and avoids managing multiple sets of credentials. Misconfiguration often occurs when the trust policy is too open (e.g., allowing any role in the app account) or when the permissions policy grants write access to the entire bucket instead of a specific prefix. Cost is free for IAM roles, but cross-account API calls incur standard data transfer costs.
What CLF-C02 Tests
This objective (2.2) focuses on understanding IAM roles as a security best practice for granting permissions to AWS services. The exam expects you to know:
The difference between IAM users, groups, and roles.
When to use a role vs. an IAM user.
How roles provide temporary credentials via STS.
The concept of a trust policy and permissions policy.
How EC2 instances use instance profiles to assume roles.
The purpose of service-linked roles.
Common Wrong Answers and Why
"Store access keys in the EC2 instance user data." – Candidates choose this because they know user data can store configuration, but it's insecure. Correct answer is to use an IAM role.
"Create an IAM user and embed credentials in the application." – This is an old practice; the exam emphasizes roles as the secure alternative.
"Use the root user credentials." – Root credentials are powerful and should never be used for routine tasks. The exam tests that root user is for account management only.
"Attach a policy directly to the EC2 instance." – Policies are attached to IAM identities (users, groups, roles), not directly to resources like EC2. The correct approach is to use a role.
Specific Terms and Values
STS (Security Token Service): The service that issues temporary credentials.
Instance profile: A container for an IAM role used by EC2.
Service principal: A unique identifier for an AWS service (e.g., ec2.amazonaws.com).
Trust policy: JSON document defining who can assume the role.
Permissions policy: JSON document defining allowed actions.
Service-linked role: A predefined role for a specific service.
Tricky Distinctions
IAM role vs. IAM user: Roles are for services and federated users; users are for humans or applications with long-term needs.
Instance profile vs. role: The instance profile is the mechanism to attach a role to an EC2 instance; you cannot attach a role directly.
Service role vs. service-linked role: Service roles are created by you; service-linked roles are created by AWS and contain predefined permissions.
Decision Rule
For any question asking how to grant permissions to an AWS service (EC2, Lambda, ECS), the answer is almost always an IAM role. Eliminate options that mention storing keys, using root user, or attaching policies to the resource directly. If the question involves cross-account access, think about a role in the target account with a trust policy allowing the source account.
IAM roles provide temporary security credentials via AWS STS, eliminating the need for long-term access keys.
EC2 instances assume roles through instance profiles; you must stop the instance to change the role.
Service-linked roles are predefined by AWS and cannot be deleted until the dependent service resources are removed.
Trust policies define which entities (services, accounts) can assume the role; permissions policies define what actions are allowed.
The default session duration for an IAM role is 1 hour, but can be set between 15 minutes and 12 hours.
AWS SDKs automatically handle credential refresh when using roles, typically 5 minutes before expiry.
CloudTrail logs all API calls made using a role, enabling auditing and compliance.
Least privilege principle: grant only the necessary permissions to the role, avoiding wildcard actions like 's3:*'.
These come up on the exam all the time. Here's how to tell them apart.
IAM Role
Used by AWS services and federated users
Temporary credentials (via STS)
No long-term access keys
Attached to EC2 via instance profile
Best for automated workloads
IAM User
Used by humans, applications, or CLI
Long-term credentials (access key pair)
Access keys can be rotated manually
Cannot be attached to EC2 directly
Best for human users or external apps
Mistake
IAM roles are only for human users.
Correct
IAM roles are designed for both human users (federated access) and AWS services (EC2, Lambda, etc.). Services assume roles to get temporary credentials.
Mistake
You can attach an IAM role directly to an EC2 instance without an instance profile.
Correct
EC2 requires an instance profile as a container for the role. The console automatically creates one when you attach a role, but programmatically you must create it separately.
Mistake
Temporary credentials from STS never expire.
Correct
Temporary credentials have a configurable expiration (default 1 hour, max 12 hours). They must be refreshed before expiry.
Mistake
You can use the same IAM role across multiple AWS accounts without any configuration.
Correct
Roles are specific to an account. For cross-account access, you need a trust policy in the target account that allows the source account's role to assume it.
Mistake
Service-linked roles can be freely deleted like regular roles.
Correct
Service-linked roles are tied to a service and cannot be deleted until you delete the resources that depend on them.
An IAM user is a permanent identity with long-term credentials (password or access keys) typically used by humans or applications outside AWS. An IAM role is an identity that can be assumed by trusted entities (services or users) to obtain temporary credentials. Roles have no permanent credentials; they rely on STS to generate temporary keys. For the exam, remember that roles are preferred for granting permissions to AWS services like EC2 and Lambda because they avoid hardcoding keys.
You cannot attach a role to a running EC2 instance directly. You must first stop the instance, then modify the IAM role (instance profile) in the instance settings, and then start the instance again. Alternatively, you can use the AWS CLI or SDK to change the instance profile while the instance is stopped. The instance profile is the container that holds the role. Once attached, the instance can retrieve temporary credentials from the instance metadata service.
A service-linked role is a predefined IAM role that is linked directly to an AWS service. It includes all the permissions that the service requires to call other AWS services on your behalf. AWS creates the role automatically when you enable certain features (e.g., AWS Organizations, Amazon Redshift). You cannot delete a service-linked role until you delete the resources that depend on it. Use them because they simplify permissions management and are maintained by AWS.
Yes, but you need to configure cross-account access. In the target account, create a role with a trust policy that allows the source account's role (or user) to assume it. The source entity then calls `sts:AssumeRole` with the target role's ARN. This is a common pattern for centralized logging or cross-account backups. The exam tests this as a secure alternative to sharing access keys.
If the application is using an AWS SDK, the SDK automatically refreshes the credentials before they expire (typically 5 minutes before expiry). If the application is using static credentials (which is not recommended), the API call will fail with an 'ExpiredToken' error. For EC2 instances, the credentials are automatically refreshed by the instance metadata service. For Lambda, the execution context may reuse credentials across invocations, but they are refreshed as needed.
An instance profile is a container for an IAM role that is used by Amazon EC2 instances. When you attach a role to an EC2 instance, you actually attach an instance profile that contains the role. The instance profile is identified by its Amazon Resource Name (ARN). You can create an instance profile separately and then associate it with an instance. The console simplifies this by creating both the role and instance profile together.
AWS STS (Security Token Service) is a web service that enables you to request temporary, limited-privilege credentials for IAM users or federated users. When a service assumes a role, STS validates the trust policy and returns a set of temporary credentials: an Access Key ID, a Secret Access Key, and a Session Token. These credentials are valid for a specified duration (default 1 hour). The credentials are cryptographically signed and cannot be used after expiration.
You've just covered IAM Roles for AWS Services — now see how well it sticks with free CLF-C02 practice questions. Full explanations included, no account needed.
Done with this chapter?