Skip to main content
This lesson demonstrates how to grant permissions to an Amazon EC2 instance so an application running on it can interact with other AWS services. The example app uses the AWS SDK for JavaScript v3 to programmatically create an Amazon S3 bucket. We show two approaches:
  • Provide long-lived credentials (AWS access key + secret) to the application.
  • Attach an IAM role (instance profile) to the EC2 instance so the SDK can authenticate automatically using temporary credentials.
All code shown here was copied to an EC2 instance in the demo.

Example application (cleaned up)

This Node.js example configures an S3 client and, if credentials are provided, sets them explicitly. The application reads the bucket name from the command line and attempts to create the bucket.
Run the app:

1) Running the app on EC2 with no credentials (expected failure)

If neither the code nor the environment provides credentials, the AWS SDK cannot sign requests. The resulting authentication error confirms that valid credentials are required:
This confirms the SDK needs credentials to authenticate requests.

2) Option A — Create an IAM user, generate access keys, and provide them to the app

One authentication method is to create an IAM user with the required permissions (for example, AmazonS3FullAccess), generate an access key pair, and place those values in the application or environment variables. In the demo we created an IAM user and attached the AmazonS3FullAccess policy.
A screenshot of the AWS Identity and Access Management (IAM) console showing a user's Summary and Security credentials pages. The Permissions tab is open and shows the AmazonS3FullAccess policy attached to the user.
When you create access keys, AWS shows several use-case options (CLI, local code, AWS compute service, third-party, etc.)—choose the one that matches how you’ll use the keys.
A screenshot of the AWS IAM "Create access key" page showing "Access key best practices & alternatives" and a list of selectable use-case options (CLI, local code, AWS compute service, third-party, etc.). The page includes navigation steps on the left and "Cancel" and "Next" buttons at the bottom.
Example: place the generated keys into the application (or export them as environment variables). Here’s a code snippet demonstrating credentials filled in directly (for demo purposes only):
Then run:
If the keys are valid and the IAM user has the required permissions, you’ll receive a 200 response and the bucket is created:
You can verify the bucket exists in the S3 console.
Hard-coding long-lived credentials in application source code is risky. Use environment variables, secrets managers, or better yet, IAM roles for compute resources to avoid credential leakage and manual rotation.
Note: Long-lived credentials work but are less secure and harder to manage at scale.

3) Remove the keys and verify the app fails (cleanup)

After deleting the bucket and removing the hard-coded credentials, running the app again demonstrates the same authentication failure because no valid credentials exist to sign the request:
This confirms authentication is required.
Recommended approach: create an IAM role with the necessary permissions (for example, attach AmazonS3FullAccess) and make the trusted entity the EC2 service principal. Then attach that role to your EC2 instance as an instance profile. The AWS SDK will automatically retrieve temporary credentials from the instance metadata service and sign requests — no hard-coded keys required. Example trust policy for a role trusted by EC2:
Create the role (for example, aws-sdk-s3), attach the AmazonS3FullAccess policy, then attach the role to your running instance:
  • Console: Instances → Security → Modify IAM role → select your role → Update IAM role
A screenshot of the AWS EC2 console on the "Modify IAM role" page showing an instance ID and a dropdown to attach the "aws-sdk-s3" IAM role. The page shows buttons to "Cancel" or "Update IAM role" along with the AWS header and footer.
Make sure your application no longer contains explicit access keys (leave them empty). The SDK will detect instance profile credentials automatically and use them to authenticate. Run the app again on the EC2 instance:
You should see the same successful 200 response and the bucket will be created. The SDK retrieved temporary credentials from the instance metadata service and authenticated through the attached role.
Using IAM roles attached to compute resources (EC2, Lambda, ECS tasks) is the recommended way to grant AWS permissions to applications. Roles remove the need for long-lived credentials and support automatic credential rotation.

Comparison: Credentials vs IAM Role


Summary
  • Providing access keys to applications works but is less secure and requires credential management.
  • Assigning an IAM role (instance profile) to an EC2 instance allows the AWS SDK for JavaScript to authenticate automatically with short-lived credentials — this is the recommended approach for EC2-hosted applications.
Links and references

Watch Video

Practice Lab