Create AWS access key and secret access key for an IAM user

Create long-term AWS IAM credentials for your CI/CD system or a legacy microservice, or anything that doesn’t support IAM Roles and STS credentials.

IAM is an essential part of how you interact with AWS and how AWS services interact with each other. When working solely with AWS services, good security practices dictate that you should create IAM roles and “assume” them.

However, this only works when AWS services interact with other AWS services. AWS services can assume IAM roles (granted you allow them to).

If we are talking about legacy apps that are running outside of AWS and want to communicate with AWS, IAM roles are not a possibility. You have to resort to generating IAM access key and secret access key and embed them within the application (e.g. as environment variables). The same is also true if you want “your computer” to communicate with the AWS account.

Luckily, AWS CDK makes it easy to programmatically generate such keys and rotate them as needed (which is useful from a security perspective – regular rotation of such keys is recommended).

Let’s start by creating an IAM user within the AWS account:

import {User} from '@aws-cdk/aws-iam'

const user = new User(this, 'User', {})

The next step is to create the access key and secret access key combination for this user:

const accessKey = new CfnAccessKey(this, 'CfnAccessKey', {
   userName: user.userName,

Since there is no L2 construct for this, we resort to using Cfn constructs, but that’s fine for such a trivial example.

Now, how do we get AWS CDK to provide us with these values? One option is to use Outputs:

new CfnOutput(this, 'accessKeyId', { value: accessKey.ref });
new CfnOutput(this, 'secretAccessKey', { value: accessKey.attrSecretAccessKey });

Happy coding!

Need consulting? Get in touch


    • This is the recommended practice, yes.

      However, there are use cases where this simply does not work – e.g. you are working with another part of the application that does not support assuming IAM roles (e.g. a legacy NodeJS Express app that’s running On Premises or GCP or Azure).

      Or an external CI/CD system that deploys stuff to AWS.

      Both of these examples require you to provision some sort of long-term IAM credentials, retrieve them and then provide them to these non-AWS tooling.

      Do you have a more elegant way to approach these scenarios?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.