Last updated: Jan 26, 2024
Reading timeยท4 min
IAM condition blocks let us set conditions that must be met for a policy to take effect.
In order to use conditions in AWS CDK, we have to set the conditions
prop
when instantiating the
PolicyStatement
class.
Let's look at an example where we create an IAM role and attach policies with conditions to it.
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 role const role1 = new iam.Role(this, 'iam-role-id-1', { assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), }); const policyWithConditions = new iam.PolicyStatement({ actions: ['ec2:CreateTags', 'ec2:DeleteTags'], resources: ['*'], // ๐ set condition conditions: { 'ForAllValues:StringEquals': { 'aws:TagKeys': ['my-tag-key', 'your-tag-key'], }, }, }); role1.addToPolicy(policyWithConditions); } }
Let's go over what we did in the code sample:
lambda
service
(principal).my-tag-key
or your-tag-key
Let's run the deploy command.
npx aws-cdk deploy
If we take a look at the policy that's attached to the role, we can see that the condition has been set.
aws:TagKeys
condition is equivalent to testing for AWS:TAGKEYS
.In order to add condition(s) to an IAM policy in AWS CDK, we have to use the addCondition or addConditions methods on an instance of the PolicyStatement class.
Let's take a look at an example, where we use both 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 single condition with `addCondition` policyWithConditions.addCondition('StringEquals', { 'ec2:AuthorizedService': 'lambda.amazonaws.com', }); // ๐ add multiple conditions with `addConditions` policyWithConditions.addConditions({ DateLessThan: { 'aws:CurrentTime': '2022-12-31T23:59:59Z', }, DateGreaterThan: { 'aws:CurrentTime': '2021-04-27T23:59:59Z', }, }); } }
Let's go over what we did in the code sample:
addCondition
method to add a condition to the
IAM policy. The condition is met and
the policy takes effect only if lambda
is the requester service.addConditions
method to add multiple conditions to the IAM
policy. The conditions are met and the policy takes effect only in the
specified time frame.Let's issue the deploy command.
npx aws-cdk deploy
After a successful deployment, the conditions we added are reflected in the IAM policy.
Let's look at another example. We are going to create a second role, which has conditions that restrict access based on the names of the objects in S3 buckets.
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 const role2 = new iam.Role(this, 'iam-role-id-2', { assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), description: 'grants permission to list all of the objects in all s3 buckets under a public prefix', inlinePolicies: { ListBucketObjectsPolicy: new iam.PolicyDocument({ statements: [ new iam.PolicyStatement({ resources: ['arn:aws:s3:::*'], actions: ['s3:ListBucket'], // ๐ limit the response of the ListBucket action conditions: { StringEquals: { 's3:prefix': 'public', }, }, }), new iam.PolicyStatement({ effect: iam.Effect.DENY, resources: ['arn:aws:s3:::*'], actions: ['s3:ListBucket'], // ๐ DENY all but objects with public prefix conditions: { StringNotEquals: { 's3:prefix': 'public', }, }, }), ], }), }, }); } }
Let's go over what we did in the code sample:
We created an IAM role and attached an inline policy to it.
The policy consists of 2 statements. The first statement allows the
s3:ListBucket
action under the condition that the requester specifies the
public
prefix. The second statement denies the s3:ListBucket
action
under the condition that the requester did not specify the public
prefix.
In other words, the condition restricts the requester to only be able to list
object keys with the public
prefix.
Let's run the deploy command.
npx aws-cdk deploy
If we take a look at the policy attached to the second role, we can see that the conditions have been set.
Check out my other article AWS CDK IAM Policy Example - Complete Guide, if you like to read more on creating IAM policies in AWS CDK.
To delete the provisioned resources, issue the destroy
command.
npx aws-cdk destroy
You can learn more about the related topics by checking out the following tutorials: