Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(iam): cleanup of IAM library #2823

Merged
merged 15 commits into from
Jun 17, 2019
Original file line number Diff line number Diff line change
Expand Up @@ -222,17 +222,18 @@ export = nodeunit.testCase({
adminPermissions: false,
});
// we might need to add permissions
deployAction.addToDeploymentRolePolicy( new iam.PolicyStatement().
addActions(
deployAction.addToDeploymentRolePolicy(new iam.PolicyStatement({
actions: [
'ec2:AuthorizeSecurityGroupEgress',
'ec2:AuthorizeSecurityGroupIngress',
'ec2:DeleteSecurityGroup',
'ec2:DescribeSecurityGroups',
'ec2:CreateSecurityGroup',
'ec2:RevokeSecurityGroupEgress',
'ec2:RevokeSecurityGroupIngress'
).
addAllResources());
],
resources: ['*']
}));

// THEN //
// there should be 3 policies 1. CodePipeline, 2. Codebuild, 3.
Expand Down
11 changes: 6 additions & 5 deletions packages/@aws-cdk/assets-docker/lib/adopted-repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,16 @@ export class AdoptedRepository extends ecr.RepositoryBase {
timeout: 300
});

fn.addToRolePolicy(new iam.PolicyStatement()
.addResource(ecr.Repository.arnForLocalRepository(props.repositoryName, this))
.addActions(
fn.addToRolePolicy(new iam.PolicyStatement({
resources: [ecr.Repository.arnForLocalRepository(props.repositoryName, this)],
actions: [
'ecr:GetRepositoryPolicy',
'ecr:SetRepositoryPolicy',
'ecr:DeleteRepository',
'ecr:ListImages',
'ecr:BatchDeleteImage'
));
],
}));

const adopter = new cfn.CustomResource(this, 'Resource', {
resourceType: 'Custom::ECRAdoptedRepository',
Expand Down Expand Up @@ -88,6 +89,6 @@ export class AdoptedRepository extends ecr.RepositoryBase {
* use the custom resource to modify the ECR resource policy if needed.
*/
public addToResourcePolicy(statement: iam.PolicyStatement) {
this.policyDocument.addStatement(statement);
this.policyDocument.addStatements(statement);
}
}
7 changes: 4 additions & 3 deletions packages/@aws-cdk/assets-docker/test/test.image-asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,10 @@ export = {
});

// WHEN
asset.repository.addToResourcePolicy(new iam.PolicyStatement()
.addAction('BOOM')
.addPrincipal(new iam.ServicePrincipal('test.service')));
asset.repository.addToResourcePolicy(new iam.PolicyStatement({
actions: ['BOOM'],
principals: [new iam.ServicePrincipal('test.service')]
}));

// THEN
expect(stack).to(haveResource('Custom::ECRAdoptedRepository', {
Expand Down
9 changes: 1 addition & 8 deletions packages/@aws-cdk/aws-apigateway/lib/restapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,14 +343,7 @@ export class RestApi extends Resource implements IRestApi {
private configureCloudWatchRole(apiResource: CfnRestApi) {
const role = new iam.Role(this, 'CloudWatchRole', {
assumedBy: new iam.ServicePrincipal('apigateway.amazonaws.com'),
managedPolicyArns: [ Stack.of(this).formatArn({
service: 'iam',
region: '',
account: 'aws',
resource: 'policy',
sep: '/',
resourceName: 'service-role/AmazonAPIGatewayPushToCloudWatchLogs'
}) ]
managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AmazonAPIGatewayPushToCloudWatchLogs')],
});

const resource = new CfnAccount(this, 'Account', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,10 @@ export = {
vpc
});

fleet.addToRolePolicy(new iam.PolicyStatement()
.addAction('test:SpecialName')
.addAllResources());
fleet.addToRolePolicy(new iam.PolicyStatement({
actions: ['test:SpecialName'],
resources: ['*']
}));

expect(stack).to(haveResource('AWS::IAM::Policy', {
PolicyDocument: {
Expand Down
7 changes: 4 additions & 3 deletions packages/@aws-cdk/aws-autoscaling/test/test.lifecyclehooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,10 @@ export = {

class FakeNotificationTarget implements autoscaling.ILifecycleHookTarget {
public bind(_scope: Construct, lifecycleHook: autoscaling.ILifecycleHook): autoscaling.LifecycleHookTargetConfig {
lifecycleHook.role.addToPolicy(new iam.PolicyStatement()
.addAction('action:Work')
.addAllResources());
lifecycleHook.role.addToPolicy(new iam.PolicyStatement({
actions: ['action:Work'],
resources: ['*']
}));
return { notificationTargetArn: 'target:arn', };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,18 @@ export class DnsValidatedCertificate extends cdk.Resource implements ICertificat
runtime: lambda.Runtime.Nodejs810,
timeout: 15 * 60 // 15 minutes
});
requestorFunction.addToRolePolicy(
new iam.PolicyStatement()
.addActions('acm:RequestCertificate', 'acm:DescribeCertificate', 'acm:DeleteCertificate')
.addResource('*')
);
requestorFunction.addToRolePolicy(
new iam.PolicyStatement()
.addActions('route53:GetChange')
.addResource('*')
);
requestorFunction.addToRolePolicy(
new iam.PolicyStatement()
.addActions('route53:changeResourceRecordSets')
.addResource(`arn:aws:route53:::hostedzone/${this.hostedZoneId}`)
);
requestorFunction.addToRolePolicy(new iam.PolicyStatement({
actions: ['acm:RequestCertificate', 'acm:DescribeCertificate', 'acm:DeleteCertificate'],
resources: ['*'],
}));
requestorFunction.addToRolePolicy(new iam.PolicyStatement({
actions: ['route53:GetChange'],
resources: ['*'],
}));
requestorFunction.addToRolePolicy(new iam.PolicyStatement({
actions: ['route53:changeResourceRecordSets'],
resources: [`arn:aws:route53:::hostedzone/${this.hostedZoneId}`],
}));

const certificate = new cfn.CustomResource(this, 'CertificateRequestorResource', {
provider: cfn.CustomResourceProvider.lambda(requestorFunction),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,10 @@ export class AwsCustomResource extends cdk.Construct {
} else { // Derive statements from AWS SDK calls
for (const call of [props.onCreate, props.onUpdate, props.onDelete]) {
if (call) {
provider.addToRolePolicy(
new iam.PolicyStatement()
.addAction(awsSdkToIamAction(call.service, call.action))
.addAllResources()
);
provider.addToRolePolicy(new iam.PolicyStatement({
actions: [awsSdkToIamAction(call.service, call.action)],
resources: ['*']
}));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,10 @@ export = {
physicalResourceIdPath: 'ETag'
},
policyStatements: [
new iam.PolicyStatement()
.addAction('s3:PutObject')
.addResource('arn:aws:s3:::my-bucket/my-key')
new iam.PolicyStatement({
actions: ['s3:PutObject'],
resources: ['arn:aws:s3:::my-bucket/my-key']
})
]
});

Expand Down
10 changes: 5 additions & 5 deletions packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-s3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ const dist = new cloudfront.CloudFrontWebDistribution(stack, 'Distribution', {
},
}]
});
bucket.addToResourcePolicy(new iam.PolicyStatement()
.allow()
.addActions('s3:Get*', 's3:List*')
.addResources(bucket.bucketArn, bucket.arnForObjects('*'))
.addCanonicalUserPrincipal(oai.cloudFrontOriginAccessIdentityS3CanonicalUserId));
bucket.addToResourcePolicy(new iam.PolicyStatement({
actions: ['s3:Get*', 's3:List*'],
resources: [bucket.bucketArn, bucket.arnForObjects('*')],
principals: [new iam.CanonicalUserPrincipal(oai.cloudFrontOriginAccessIdentityS3CanonicalUserId)]
}));

new cdk.CfnOutput(stack, 'DistributionDomainName', { value: dist.domainName });
37 changes: 21 additions & 16 deletions packages/@aws-cdk/aws-cloudtrail/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,18 +128,22 @@ export class Trail extends Resource {
super(scope, id);

const s3bucket = new s3.Bucket(this, 'S3', {encryption: s3.BucketEncryption.Unencrypted});
const cloudTrailPrincipal = "cloudtrail.amazonaws.com";

s3bucket.addToResourcePolicy(new iam.PolicyStatement()
.addResource(s3bucket.bucketArn)
.addActions('s3:GetBucketAcl')
.addServicePrincipal(cloudTrailPrincipal));

s3bucket.addToResourcePolicy(new iam.PolicyStatement()
.addResource(s3bucket.arnForObjects(`AWSLogs/${Stack.of(this).account}/*`))
.addActions("s3:PutObject")
.addServicePrincipal(cloudTrailPrincipal)
.setCondition("StringEquals", {'s3:x-amz-acl': "bucket-owner-full-control"}));
const cloudTrailPrincipal = new iam.ServicePrincipal("cloudtrail.amazonaws.com");

s3bucket.addToResourcePolicy(new iam.PolicyStatement({
resources: [s3bucket.bucketArn],
actions: ['s3:GetBucketAcl'],
principals: [cloudTrailPrincipal],
}));

s3bucket.addToResourcePolicy(new iam.PolicyStatement({
resources: [s3bucket.arnForObjects(`AWSLogs/${Stack.of(this).account}/*`)],
actions: ["s3:PutObject"],
principals: [cloudTrailPrincipal],
conditions: {
StringEquals: {'s3:x-amz-acl': "bucket-owner-full-control"}
}
}));

let logGroup: logs.CfnLogGroup | undefined;
let logsRole: iam.IRole | undefined;
Expand All @@ -148,11 +152,12 @@ export class Trail extends Resource {
retentionInDays: props.cloudWatchLogsRetentionTimeDays || logs.RetentionDays.OneYear
});

logsRole = new iam.Role(this, 'LogsRole', { assumedBy: new iam.ServicePrincipal(cloudTrailPrincipal) });
logsRole = new iam.Role(this, 'LogsRole', { assumedBy: cloudTrailPrincipal });

logsRole.addToPolicy(new iam.PolicyStatement()
.addActions("logs:PutLogEvents", "logs:CreateLogStream")
.addResource(logGroup.logGroupArn));
logsRole.addToPolicy(new iam.PolicyStatement({
actions: ["logs:PutLogEvents", "logs:CreateLogStream"],
resources: [logGroup.logGroupArn],
}));
}
if (props.managementEvents) {
const managementEvent = {
Expand Down
71 changes: 32 additions & 39 deletions packages/@aws-cdk/aws-codebuild/lib/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ export class Project extends ProjectBase {

constructor(s: Construct, i: string) {
super(s, i);
this.grantPrincipal = new iam.ImportedResourcePrincipal({ resource: this });
this.grantPrincipal = new iam.UnknownPrincipal({ resource: this });
}
}

Expand Down Expand Up @@ -585,7 +585,7 @@ export class Project extends ProjectBase {
resourceName: projectName,
});

this.grantPrincipal = new iam.ImportedResourcePrincipal({ resource: this });
this.grantPrincipal = new iam.UnknownPrincipal({ resource: this });
this.projectName = projectName;
}
}
Expand Down Expand Up @@ -808,15 +808,10 @@ export class Project extends ProjectBase {

const logGroupStarArn = `${logGroupArn}:*`;

const p = new iam.PolicyStatement();
p.allow();
p.addResource(logGroupArn);
p.addResource(logGroupStarArn);
p.addAction('logs:CreateLogGroup');
p.addAction('logs:CreateLogStream');
p.addAction('logs:PutLogEvents');

return p;
return new iam.PolicyStatement({
resources: [logGroupArn, logGroupStarArn],
actions: ['logs:CreateLogGroup', 'logs:CreateLogStream', 'logs:PutLogEvents'],
});
}

private renderEnvironment(env: BuildEnvironment = {},
Expand Down Expand Up @@ -893,26 +888,26 @@ export class Project extends ProjectBase {
});
this._securityGroups = [securityGroup];
}
this.addToRoleInlinePolicy(new iam.PolicyStatement()
.addAllResources()
.addActions(
'ec2:CreateNetworkInterface',
'ec2:DescribeNetworkInterfaces',
'ec2:DeleteNetworkInterface',
'ec2:DescribeSubnets',
'ec2:DescribeSecurityGroups',
'ec2:DescribeDhcpOptions',
'ec2:DescribeVpcs'
));
this.addToRolePolicy(new iam.PolicyStatement()
.addResource(`arn:aws:ec2:${Aws.region}:${Aws.accountId}:network-interface/*`)
.addCondition('StringEquals', {
"ec2:Subnet": props.vpc
.selectSubnets(props.subnetSelection).subnetIds
.map(si => `arn:aws:ec2:${Aws.region}:${Aws.accountId}:subnet/${si}`),
"ec2:AuthorizedService": "codebuild.amazonaws.com"
})
.addAction('ec2:CreateNetworkInterfacePermission'));
this.addToRoleInlinePolicy(new iam.PolicyStatement({
resources: ['*'],
actions: [
'ec2:CreateNetworkInterface', 'ec2:DescribeNetworkInterfaces',
'ec2:DeleteNetworkInterface', 'ec2:DescribeSubnets',
'ec2:DescribeSecurityGroups', 'ec2:DescribeDhcpOptions',
'ec2:DescribeVpcs']
}));
this.addToRolePolicy(new iam.PolicyStatement({
resources: [`arn:aws:ec2:${Aws.region}:${Aws.accountId}:network-interface/*`],
actions: ['ec2:CreateNetworkInterfacePermission'],
conditions: {
StringEquals: {
"ec2:Subnet": props.vpc
.selectSubnets(props.subnetSelection).subnetIds
.map(si => `arn:aws:ec2:${Aws.region}:${Aws.accountId}:subnet/${si}`),
"ec2:AuthorizedService": "codebuild.amazonaws.com"
}
}
}));
return {
vpcId: props.vpc.vpcId,
subnets: props.vpc.selectSubnets(props.subnetSelection).subnetIds,
Expand Down Expand Up @@ -1267,12 +1262,10 @@ export enum BuildEnvironmentVariableType {
}

function ecrAccessForCodeBuildService(): iam.PolicyStatement {
return new iam.PolicyStatement()
.describe('CodeBuild')
.addServicePrincipal('codebuild.amazonaws.com')
.addActions(
'ecr:GetDownloadUrlForLayer',
'ecr:BatchGetImage',
'ecr:BatchCheckLayerAvailability'
);
const s = new iam.PolicyStatement({
principals: [new iam.ServicePrincipal('codebuild.amazonaws.com')],
actions: ['ecr:GetDownloadUrlForLayer', 'ecr:BatchGetImage', 'ecr:BatchCheckLayerAvailability'],
});
s.sid = 'CodeBuild';
return s;
}
7 changes: 4 additions & 3 deletions packages/@aws-cdk/aws-codebuild/lib/source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -466,9 +466,10 @@ export class CodeCommitSource extends GitBuildSource {
*/
public _bind(project: Project) {
// https://docs.aws.amazon.com/codebuild/latest/userguide/setting-up.html
project.addToRolePolicy(new iam.PolicyStatement()
.addAction('codecommit:GitPull')
.addResource(this.repo.repositoryArn));
project.addToRolePolicy(new iam.PolicyStatement({
actions: ['codecommit:GitPull'],
resources: [this.repo.repositoryArn]
}));
}

protected toSourceProperty(): any {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ export class LambdaDeploymentGroup extends cdk.Resource implements ILambdaDeploy
assumedBy: new iam.ServicePrincipal('codedeploy.amazonaws.com')
});

this.role.attachManagedPolicy('arn:aws:iam::aws:policy/service-role/AWSCodeDeployRoleForLambda');
this.role.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSCodeDeployRoleForLambda'));

const resource = new CfnDeploymentGroup(this, 'Resource', {
applicationName: this.application.applicationName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupBase {

this.role = props.role || new iam.Role(this, 'Role', {
assumedBy: new iam.ServicePrincipal('codedeploy.amazonaws.com'),
managedPolicyArns: ['arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole'],
managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSCodeDeployRole')],
});

this._autoScalingGroups = props.autoScalingGroups || [];
Expand Down
Loading