TL;DR
This guide shows you how to securely let AWS services talk to each other without hardcoding credentials, using IAM roles. We’ll focus on granting one service permission to access another.
Prerequisites
- An active AWS account
- Basic understanding of IAM (Identity and Access Management)
- Two AWS services you want to connect (e.g., EC2 instance and S3 bucket)
Step 1: Identify the Trust Relationship
The ‘trust relationship’ defines which service can assume an IAM role. We need to create a trust policy for the target service.
- Go to the IAM console and select Roles.
- Create a new role (or edit an existing one).
- Choose the service that will be assuming this role as the trusted entity. For example, if an EC2 instance needs access, choose ‘EC2’.
- In the advanced trust policy editor, you’ll need to specify the
PrincipalandAction. Here’s an example for EC2:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
Step 2: Define Permissions Policy
This policy dictates what the service can *do* once it assumes the role. It’s attached to the IAM role.
- Still within the IAM role creation/editing process, attach a permissions policy.
- You can use AWS managed policies (e.g.,
AmazonS3ReadOnlyAccess) or create a custom policy. For example, to allow read-only access to an S3 bucket:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::your-bucket-name", "arn:aws:s3:::your-bucket-name/*" ] } ] }
Step 3: Configure the Source Service
Now, tell your source service to use this IAM role. The method varies depending on the service.
- EC2 Instance: When launching an EC2 instance, assign the created IAM role in the ‘IAM role’ section of the launch wizard.
- Lambda Function: Configure the execution role for your Lambda function to be the created IAM role.
- ECS Task Definition: Specify the task role within the ECS task definition.
Step 4: Test the Connection
Verify that the source service can access the target service using the assumed role.
- From your source service (e.g., EC2 instance), use the AWS CLI or SDK to attempt an action on the target resource (e.g., list objects in the S3 bucket).
- If successful, you’ve configured service-to-service authentication correctly! If not, check the IAM role trust relationship and permissions policy for errors.
Step 5: Security Best Practices
- Principle of Least Privilege: Grant only the necessary permissions to each role. Avoid using wildcard (*) resources where possible.
- Regular Audits: Review IAM roles and policies periodically to ensure they remain appropriate.
- Monitor CloudTrail Logs: Track API calls made by your services to identify any unexpected activity.

