khinester
khinester

Reputation: 3530

create aws user with s3 permissions with aws cdk

I am trying to convert this CF template to AWS CDK:

Resources:
  S3User:
    Type: AWS::IAM::User
    Properties:
      Policies:
      - PolicyName: UserS3Access
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Sid: AllowUserToSeeBucketListInTheConsole
            Action:
            - s3:ListAllMyBuckets
            - s3:GetBucketLocation
            Effect: Allow
            Resource:
            - arn:aws:s3:::*
          - Sid: AllowRootAndUploadsBucket
            Action:
            - s3:ListBucket
            Effect: Allow
            Resource:
            - Fn::Join:
              - ''
              - - 'arn:aws:s3:::'
                - Ref: UploadBucket
            Condition:
              StringEquals:
                s3:prefix:
                - ''
                - uploads/
                s3:delimiter:
                - "/"
          - Sid: AllowListingOfUploadsFolder
            Action:
            - s3:ListBucket
            Effect: Allow
            Resource:
            - Fn::Join:
              - ''
              - - 'arn:aws:s3:::'
                - Ref: UploadBucket
            Condition:
              StringLike:
                s3:prefix:
                - uploads/*
          - Sid: AllowAllS3ActionsInUploadsFolder
            Effect: Allow
            Action:
            - s3:PutObject
            - s3:GetObject
            - s3:GetObjectVersion
            Resource:
            - Fn::Join:
              - ''
              - - 'arn:aws:s3:::'
                - Ref: UploadBucket
                - "/uploads"
                - "/*"
      Tags:
        - Key: CloudFormationArn
          Value: '#{AWS::StackId}'
  UserAccessKey:
    DependsOn: S3User
    Type: AWS::IAM::AccessKey
    Properties:
      UserName:
        Ref: S3User

Outputs:
  UserAccessKeyID:
    Description: The Access Key for S3 bucket access
    Value:
      Ref: UserAccessKey
  UserAccessKeySecret:
    Description: The Access Key Secret for S3 bucket access
    Value:
      Fn::GetAtt:
        - "UserAccessKey"
        - "SecretAccessKey"

Here is what I have so far:

import { Construct, Stack, StackProps, CfnOutput }  from '@aws-cdk/core';
import { Group, Policy, PolicyStatement, ManagedPolicy, User } from '@aws-cdk/aws-iam';
// import { Bucket } from '@aws-cdk/aws-s3';

const S3AccessGroup = 'S3AccessGroup';
const S3Users = [
  '[email protected]',
];

export class CdkIamStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);
    // const bucket = Bucket.fromBucketAttributes(this, 'ImportedBucket', {
    //   bucketArn: 'arn:aws:s3:::my-bucket'
    // });

    const AllowUserToSeeBucketListInTheConsole = new PolicyStatement({
      resources: ["arn:aws:s3:::*"],
      actions: [
        "s3:ListAllMyBuckets",
        "s3:GetBucketLocation"
        ],
    });
    const AllowRootAndUploadsBucket = new PolicyStatement({
      resources: ['arn:aws:s3:::my-bucket'],
      actions: [
        "s3:ListBucket"
        ],
      conditions: {'StringEquals': {
        's3:prefix': [
          'uploads',
          ],
        's3:delimiter': [
          '/',
          ]
        }
      }
    });
    const AllowListingOfUploadsFolder = new PolicyStatement({
      resources: ['arn:aws:s3:::my-bucket'],
      actions: [
        "s3:ListBucket"
        ],
      conditions: {'StringEquals': {
        's3:prefix': [
          'uploads/*',
          ]
        }
      }
    });
    const AllowAllS3ActionsInUploadsFolder = new PolicyStatement({
      resources: ['arn:aws:s3:::my-bucket/uploads/*'],
      actions: [
        "s3:PutObject",
        "s3:GetObject",
        "s3:GetObjectVersion"
        ],
    });

    const UserS3Access = new Policy(this, 'UserS3Access', { 
      policyName: "UserS3Access",
      statements: [
        AllowUserToSeeBucketListInTheConsole,
        AllowRootAndUploadsBucket,
        AllowListingOfUploadsFolder,
        AllowAllS3ActionsInUploadsFolder
      ],
    });

    const S3Group = new Group(this, S3AccessGroup, { groupName: S3AccessGroup });
    S3Group.attachInlinePolicy(UserS3Access);


    S3Users.forEach((S3User) => {
      const user = new User(this, S3User, {
        userName: S3User,
        groups: [S3Group]
      });
    });
    // new CfnOutput(this, 'accessKeyId', { value: accessKey.ref });
    // new CfnOutput(this, 'secretAccessKey', { value: accessKey.attrSecretAccessKey });
  }
}

How do I output the accessKeyId and secretAccessKey for each user created?

Is this the correct way to generate users using AWS CDK?

Any advice is much appreciated

Upvotes: 2

Views: 2037

Answers (2)

Shariq Anwar
Shariq Anwar

Reputation: 111

Your Users have been created and can be viewed in IAM console. Similar to how you generate your access keys in the console. You have to do the same in the CDK code. Following code snippets might help you:

AWS CDK v2(2.37.1)

S3Users.forEach((S3User) => {
    // create user
    const user = new User(this, S3User, {
      userName: S3User,
      groups: [S3Group]
    });
    
    // create access key
    const accessKey = new iam.AccessKey(this, 'AccessKey', { user });
    
    // display access key and secret access key
    new CfnOutput(this, `${S3User}AccessKeyId`, { value: accessKey.accessKeyId});
    new CfnOutput(this, `${S3User}SecretAccessKey`, { value: accessKey.secretAccessKey });
})

Upvotes: 0

Pedreiro
Pedreiro

Reputation: 1814

After creating the user, you need to create the key as well:

    S3Users.forEach((S3User) => {
      const user = new User(this, S3User, {
        userName: S3User,
        groups: [S3Group]
      });
      const accessKey = new CfnAccessKey(this, `${S3User}AccessKey`, {
        userName: user.userName,
      });
      new CfnOutput(this, `${S3User}AccessKeyId`, { value: accessKey.ref });
      new CfnOutput(this, `${S3User}SecretAccessKey`, { value: accessKey.attrSecretAccessKey });
    });

Upvotes: 3

Related Questions