Skip to content

Commit

Permalink
Split asset roles by asset type, added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
njlynch committed Jul 30, 2020
1 parent 0355d85 commit aec6d71
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 163 deletions.
26 changes: 17 additions & 9 deletions packages/@aws-cdk/pipelines/lib/pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,11 +242,11 @@ interface AssetPublishingProps {
*/
class AssetPublishing extends Construct {
private readonly publishers: Record<string, PublishAssetsAction> = {};
private readonly assetRoles: Record<string, iam.IRole> = {};
private readonly myCxAsmRoot: string;

private readonly stage: codepipeline.IStage;
private readonly pipeline: codepipeline.Pipeline;
private assetRole?: iam.IRole;
private _fileAssetCtr = 1;
private _dockerAssetCtr = 1;

Expand All @@ -272,8 +272,8 @@ class AssetPublishing extends Construct {
const relativePath = path.relative(this.myCxAsmRoot, command.assetManifestPath);

// Late-binding here (rather than in the constructor) to prevent creating the role in cases where no asset actions are created.
if (!this.assetRole) {
this.generateAssetRole();
if (!this.assetRoles[command.assetType]) {
this.generateAssetRole(command.assetType);
}

let action = this.publishers[command.assetId];
Expand All @@ -294,7 +294,7 @@ class AssetPublishing extends Construct {
cloudAssemblyInput: this.props.cloudAssemblyInput,
cdkCliVersion: this.props.cdkCliVersion,
assetType: command.assetType,
role: this.assetRole,
role: this.assetRoles[command.assetType],
});
this.stage.addAction(action);
}
Expand Down Expand Up @@ -322,9 +322,13 @@ class AssetPublishing extends Construct {
* This role is used by both the CodePipeline build action and related CodeBuild project. Consolidating these two
* roles into one, and re-using across all assets, saves significant size of the final synthesized output.
* Modeled after the CodePipeline role and 'CodePipelineActionRole' roles.
* Generates one role per asset type to separate file and Docker/image-based permissions.
*/
private generateAssetRole() {
const assetRole = new iam.Role(this, 'Role', {
private generateAssetRole(assetType: AssetType) {
if (this.assetRoles[assetType]) { return this.assetRoles[assetType]; }

const rolePrefix = assetType === AssetType.DOCKER_IMAGE ? 'Docker' : 'File';
const assetRole = new iam.Role(this, `${rolePrefix}Role`, {
roleName: PhysicalName.GENERATE_IF_NEEDED,
assumedBy: new iam.CompositePrincipal(new iam.ServicePrincipal('codebuild.amazonaws.com'), new iam.AccountPrincipal(Stack.of(this).account)),
});
Expand Down Expand Up @@ -368,15 +372,19 @@ class AssetPublishing extends Construct {
}));

// Publishing role access
const rolePattern = assetType === AssetType.DOCKER_IMAGE
? 'arn:*:iam::*:role/*-image-publishing-role-*'
: 'arn:*:iam::*:role/*-file-publishing-role-*';
assetRole.addToPolicy(new iam.PolicyStatement({
actions: ['sts:AssumeRole'],
resources: ['arn:*:iam::*:role/*-image-publishing-role-*', 'arn:*:iam::*:role/*-file-publishing-role-*'],
resources: [rolePattern],
}));

// Artifact access
this.pipeline.artifactBucket.grantRead(assetRole);

this.assetRole = assetRole.withoutPolicyUpdates();
return this.assetRole;
this.assetRoles[assetType] = assetRole.withoutPolicyUpdates();
return this.assetRoles[assetType];
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@
"Principal": {
"AWS": {
"Fn::GetAtt": [
"PipelineAssetsRole9B011B83",
"PipelineAssetsFileRole59943A77",
"Arn"
]
}
Expand All @@ -362,7 +362,7 @@
"Principal": {
"AWS": {
"Fn::GetAtt": [
"PipelineAssetsRole9B011B83",
"PipelineAssetsFileRole59943A77",
"Arn"
]
}
Expand Down Expand Up @@ -561,7 +561,7 @@
"Effect": "Allow",
"Resource": {
"Fn::GetAtt": [
"PipelineAssetsRole9B011B83",
"PipelineAssetsFileRole59943A77",
"Arn"
]
}
Expand Down Expand Up @@ -723,7 +723,7 @@
"Name": "FileAsset1",
"RoleArn": {
"Fn::GetAtt": [
"PipelineAssetsRole9B011B83",
"PipelineAssetsFileRole59943A77",
"Arn"
]
},
Expand All @@ -749,7 +749,7 @@
"Name": "FileAsset2",
"RoleArn": {
"Fn::GetAtt": [
"PipelineAssetsRole9B011B83",
"PipelineAssetsFileRole59943A77",
"Arn"
]
},
Expand Down Expand Up @@ -1413,7 +1413,7 @@
}
}
},
"PipelineAssetsRole9B011B83": {
"PipelineAssetsFileRole59943A77": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
Expand Down Expand Up @@ -1442,7 +1442,7 @@
}
}
},
"PipelineAssetsRoleDefaultPolicyB41726CA": {
"PipelineAssetsFileRoleDefaultPolicy14DB8755": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
Expand All @@ -1454,39 +1454,18 @@
"logs:PutLogEvents"
],
"Effect": "Allow",
"Resource": [
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":logs:test-region:12345678:log-group:/aws/codebuild/",
{
"Ref": "PipelineAssetsFileAsset185A67CB4"
}
]
]
},
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":logs:test-region:12345678:log-group:/aws/codebuild/",
{
"Ref": "PipelineAssetsFileAsset185A67CB4"
},
":*"
]
"Resource": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":logs:test-region:12345678:log-group:/aws/codebuild/*"
]
}
]
]
}
},
{
"Action": [
Expand All @@ -1504,33 +1483,24 @@
{
"Ref": "AWS::Partition"
},
":codebuild:test-region:12345678:report-group/",
{
"Ref": "PipelineAssetsFileAsset185A67CB4"
},
"-*"
":codebuild:test-region:12345678:report-group/*"
]
]
}
},
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Resource": "arn:*:iam::*:role/*-file-publishing-role-*"
},
{
"Action": [
"codebuild:BatchGetBuilds",
"codebuild:StartBuild",
"codebuild:StopBuild"
],
"Effect": "Allow",
"Resource": {
"Fn::GetAtt": [
"PipelineAssetsFileAsset185A67CB4",
"Arn"
]
}
"Resource": "*"
},
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Resource": "arn:*:iam::*:role/*-file-publishing-role-*"
},
{
"Action": [
Expand Down Expand Up @@ -1574,109 +1544,14 @@
"Arn"
]
}
},
{
"Action": [
"kms:Decrypt",
"kms:Encrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*"
],
"Effect": "Allow",
"Resource": {
"Fn::GetAtt": [
"PipelineArtifactsBucketEncryptionKeyF5BF0670",
"Arn"
]
}
},
{
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Effect": "Allow",
"Resource": [
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":logs:test-region:12345678:log-group:/aws/codebuild/",
{
"Ref": "PipelineAssetsFileAsset24D2D639B"
}
]
]
},
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":logs:test-region:12345678:log-group:/aws/codebuild/",
{
"Ref": "PipelineAssetsFileAsset24D2D639B"
},
":*"
]
]
}
]
},
{
"Action": [
"codebuild:CreateReportGroup",
"codebuild:CreateReport",
"codebuild:UpdateReport",
"codebuild:BatchPutTestCases"
],
"Effect": "Allow",
"Resource": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":codebuild:test-region:12345678:report-group/",
{
"Ref": "PipelineAssetsFileAsset24D2D639B"
},
"-*"
]
]
}
},
{
"Action": [
"codebuild:BatchGetBuilds",
"codebuild:StartBuild",
"codebuild:StopBuild"
],
"Effect": "Allow",
"Resource": {
"Fn::GetAtt": [
"PipelineAssetsFileAsset24D2D639B",
"Arn"
]
}
}
],
"Version": "2012-10-17"
},
"PolicyName": "PipelineAssetsRoleDefaultPolicyB41726CA",
"PolicyName": "PipelineAssetsFileRoleDefaultPolicy14DB8755",
"Roles": [
{
"Ref": "PipelineAssetsRole9B011B83"
"Ref": "PipelineAssetsFileRole59943A77"
}
]
}
Expand All @@ -1695,7 +1570,7 @@
},
"ServiceRole": {
"Fn::GetAtt": [
"PipelineAssetsRole9B011B83",
"PipelineAssetsFileRole59943A77",
"Arn"
]
},
Expand Down Expand Up @@ -1725,7 +1600,7 @@
},
"ServiceRole": {
"Fn::GetAtt": [
"PipelineAssetsRole9B011B83",
"PipelineAssetsFileRole59943A77",
"Arn"
]
},
Expand Down
Loading

0 comments on commit aec6d71

Please sign in to comment.