AWS Day 37: Managing EC2 Access with S3 Role-based Permissions | KodeKloud 100 Days of Cloud

"I'm a 3rd-year Computer Engineering student at Marwadi University with skills in C++, web development (MERN stack), and DevOps tools like Kubernetes. I contribute to open-source projects and share tech knowledge on GitHub and LinkedIn. I'm learning cloud technologies and app deployment. As an Internshala Student Partner, I help others find jobs and courses." now currently focusing on #90DaysOfDevops
On Day 37 of the KodeKloud 100 Days of Cloud Challenge, I explored one of the AWS security best practices—granting an EC2 instance access to Amazon S3 using IAM Roles instead of storing AWS credentials on the server.
In this lab, I created a private S3 bucket, configured an IAM policy with least-privilege permissions, created an IAM role, attached it to an EC2 instance, and verified secure access by uploading and listing files using the AWS CLI.
Why Use IAM Roles for EC2?
Instead of storing AWS Access Keys on an EC2 instance, AWS recommends using IAM Roles.
Benefits include:
No hardcoded AWS credentials
Automatic temporary credential rotation
Improved security
Least-privilege access
Easier permission management
Better compliance with AWS security best practices
When an IAM Role is attached to an EC2 instance, temporary credentials are automatically provided through the Instance Metadata Service (IMDS).
Lab Objective
The goal of this lab was to:
Generate SSH keys on the aws-client host
Enable password-less SSH access to the EC2 instance
Create a private S3 bucket
Create an IAM policy with S3 permissions
Create an IAM role
Attach the IAM role to the EC2 instance
Upload a file to Amazon S3 using the AWS CLI
Verify access by listing bucket contents
Architecture Overview
The completed architecture is shown below.
+----------------------+
| AWS S3 Bucket |
| devops-s3-959313683568 |
+----------▲-----------+
│
IAM Role Permissions
│
+----------▼-----------+
| EC2 Instance |
| devops-ec2 |
+----------▲-----------+
│
SSH Access
│
aws-client Host
The EC2 instance securely communicates with Amazon S3 using temporary credentials obtained from the attached IAM Role.
Step 1: Generate SSH Keys
The first task was generating a new SSH key pair on the aws-client host.
ssh-keygen
This generated:
/root/.ssh/id_rsa
/root/.ssh/id_rsa.pub
The public key was then copied to the EC2 instance.
cat ~/.ssh/id_rsa.pub
On the EC2 instance:
cat >> ~/.ssh/authorized_keys
This enabled password-less SSH authentication.
Step 2: Create a Private Amazon S3 Bucket
Next, I created a private Amazon S3 bucket.
Configuration:
| Setting | Value |
|---|---|
| Bucket Name | devops-s3-959313683568 |
| Bucket Type | General Purpose |
| Access | Private |
| Region | us-east-1 |
No public access was enabled, keeping the bucket secure.
Step 3: Create an IAM Policy
I created a custom IAM policy that grants only the required permissions for the S3 bucket.
Allowed Actions:
s3:ListBucket
s3:GetObject
s3:PutObject
The policy was restricted to:
devops-s3-959313683568
This follows the AWS Least Privilege Principle, allowing access only to the required bucket.
Step 4: Create an IAM Role
Next, I created an IAM Role for Amazon EC2.
Configuration:
| Setting | Value |
|---|---|
| Trusted Service | EC2 |
| Role Name | devops-role |
The custom S3 policy was attached to this role.
Step 5: Attach the IAM Role to EC2
The IAM Role was then attached to the existing EC2 instance.
Instance:
devops-ec2
Attached Role:
devops-role
Once attached, the EC2 instance automatically received temporary AWS credentials through the Instance Metadata Service (IMDS).
Step 6: Upload a File to Amazon S3
After connecting to the EC2 instance through SSH, I tested access by uploading a sample file.
aws s3 cp test.txt s3://devops-s3-959313683568/
The upload completed successfully without configuring any AWS Access Keys on the instance.
Step 7: Verify Bucket Access
Finally, I verified the upload by listing the bucket contents.
aws s3 ls s3://devops-s3-959313683568/
Output:
2026-07-08 17:49:04 13 test.txt
This confirmed that:
The IAM Role was attached correctly.
The IAM Policy permissions were working.
The EC2 instance successfully authenticated using temporary credentials.
File upload and listing operations were successful.
Conclusion
Day 37 focused on implementing secure access between Amazon EC2 and Amazon S3 using IAM Roles.
Instead of relying on long-term AWS credentials, I configured a private S3 bucket, created a least-privilege IAM policy, attached it to an EC2 IAM role, and successfully accessed the bucket using temporary credentials automatically provided by AWS.
This hands-on exercise demonstrated one of the most important AWS security best practices for granting service-to-service permissions in a scalable and secure way.




