Borislav Hadzhiev
Thu Apr 14 2022·4 min read
Photo by Linda Xu
Updated - Thu Apr 14 2022
In order to create an IAM User in AWS CDK we have to use the User construct.
To have a complete reference for how to create an IAM User, let's define a simple CDK stack, where we:
import * as iam from 'aws-cdk-lib/aws-iam'; import * as cdk from 'aws-cdk-lib'; export class CdkStarterStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); // 👇 Create group const group = new iam.Group(this, 'example-group', { managedPolicies: [ iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonEC2ReadOnlyAccess'), ], }); // 👇 Create Managed Policy const loggingManagedPolicy = iam.ManagedPolicy.fromAwsManagedPolicyName( 'CloudWatchReadOnlyAccess', ); // 👇 Create Permissions Boundary const permissionsBoundary = new iam.ManagedPolicy( this, 'example-permissions-boundary', { statements: [ new iam.PolicyStatement({ effect: iam.Effect.DENY, actions: ['sqs:*'], resources: ['*'], }), ], }, ); // 👇 Create User const user = new iam.User(this, 'example-user', { userName: 'example-user', managedPolicies: [loggingManagedPolicy], groups: [group], permissionsBoundary, }); } }
Let's go over what we did in the code snippet.
We created an IAM Group, using the Group construct. In this case, the group grants read only access to the EC2 service via an AWS managed policy.
We referenced a managed IAM Policy using the ManagedPolicy construct. In this case, the managed policy grants simple logging permissions.
We created a Permissions Boundary using the
PermissionsBoundary
class. In this example, the permissions boundary denies any sqs
related
actions on all resources.
We created an IAM User, using the User construct. Let's go over the props we passed to the User construct:
userName
- a name for the user. If we didn't specify one, CDK would
automatically generate a unique name for us. If we specify a userName
, we
can't perform updates that require resource replacement, so it's best to
omit this prop unless we really need it.managedPolicies
- a list of managed policies to associate with the user.groups
- a list of groups the user will be added to.permissionsBoundary
- use a permissions boundary to set the maximum
permissions that an IAM policy could grant the user.There is also a password
prop - the password for the IAM user. You only need
to set a password if the user will need to access the AWS Management console.
Let's run the deploy
command:
npx aws-cdk deploy
If we take a look at the User in the IAM console, we can see that the user has been created, added to a group and the policies and permissions boundary have all been set:
In order to add additional permissions to a user after creation, we have to use the methods on the user object, for example:
Let's look at an example that uses the addManagedPolicy
and
attachInlinePolicy
methods.
import * as iam from 'aws-cdk-lib/aws-iam'; import * as cdk from 'aws-cdk-lib'; export class CdkStarterStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props) // ...rest // 👇 add a managed policy to the user user.addManagedPolicy( iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonS3ReadOnlyAccess'), ); // 👇 create an inline policy const inlinePolicy = new iam.Policy(this, 'cloudwatch-logs-policy', { statements: [ new iam.PolicyStatement({ actions: ['logs:PutLogEvents'], resources: ['*'], }), ], }); // 👇 attach the inline policy to the user user.attachInlinePolicy(inlinePolicy); } }
Let's go over what we did in the code snippet.
addManagedPolicy
methodattachInlinePolicy
methodLet's deploy the changes:
npx aws-cdk deploy
If we take a look at the IAM console, we can see that the user now has 4 permission policies applied to it:
The same approach applies if we wanted to add the IAM user to a group. Then, we would create the group and use the addToGroup method on the user object.
When a CDK stack gets deleted, the IAM users provisioned by the stack also get
deleted. If you need to override this behavior, you can use the
applyRemovalPolicy
method and set the policy of the user to RETAIN
.
However, note that if the user references any resources created by the stack, i.e. groups, policies, permission boundaries, an attempt to delete these resources would fail.
For example, trying to delete a group that a user references results in an error:
To delete the resources we've provisioned, issue the destroy
command:
npx aws-cdk destroy