From e4a89f4ca715101264f2620ea9408e7b4b7286de Mon Sep 17 00:00:00 2001 From: Adam Ruka Date: Mon, 24 Jun 2019 17:19:16 -0700 Subject: [PATCH] feat(codepipeline): generate a Role for every AWS-owned Action used in a Pipeline. --- .../test/integ.cicd.expected.json | 288 ++++++-- .../test/test.pipeline-deploy-stack-action.ts | 5 +- .../lib/cloudformation/pipeline-actions.ts | 26 +- .../lib/codebuild/build-action.ts | 2 +- .../lib/codecommit/source-action.ts | 6 +- .../lib/codedeploy/server-deploy-action.ts | 5 +- .../lib/ecr/source-action.ts | 5 +- .../lib/ecs/deploy-action.ts | 6 +- .../lib/lambda/invoke-action.ts | 2 +- .../lib/manual-approval-action.ts | 2 +- .../lib/s3/deploy-action.ts | 7 +- .../lib/s3/source-action.ts | 7 +- .../cloudformation/test.pipeline-actions.ts | 20 +- ...g.cfn-template-from-repo.lit.expected.json | 490 +++++++++++-- ...yed-through-codepipeline.lit.expected.json | 689 +++++++++++++++--- .../test/integ.lambda-pipeline.expected.json | 270 ++++++- .../integ.pipeline-alexa-deploy.expected.json | 217 ++++-- ...eg.pipeline-cfn-cross-region.expected.json | 316 ++++++-- ...peline-cfn-with-action-role.expected.json} | 240 ++++-- ...=> integ.pipeline-cfn-with-action-role.ts} | 0 .../test/integ.pipeline-cfn.expected.json | 549 ++++++++++++-- ...uild-multiple-inputs-outputs.expected.json | 68 +- ...line-code-build-multiple-inputs-outputs.ts | 5 + ...g.pipeline-code-commit-build.expected.json | 514 +++++++++---- .../integ.pipeline-code-commit.expected.json | 191 ++++- .../integ.pipeline-code-deploy.expected.json | 354 ++++++--- .../integ.pipeline-ecr-source.expected.json | 158 +++- .../integ.pipeline-ecs-deploy.expected.json | 368 ++++++++-- .../test/integ.pipeline-events.expected.json | 225 +++++- .../test/integ.pipeline-jenkins.expected.json | 158 +++- ...teg.pipeline-manual-approval.expected.json | 216 +++++- .../integ.pipeline-s3-deploy.expected.json | 402 ++++++++-- .../@aws-cdk/aws-codepipeline/lib/action.ts | 18 + .../@aws-cdk/aws-codepipeline/lib/pipeline.ts | 40 +- .../@aws-cdk/aws-codepipeline/package.json | 3 +- .../test/fake-build-action.ts | 5 + .../aws-codepipeline/test/test.action.ts | 38 + .../integ.pipeline-event-target.expected.json | 96 +++ .../test/__snapshots__/synth.test.js.snap | 396 ++++++++-- 39 files changed, 5375 insertions(+), 1032 deletions(-) rename packages/@aws-cdk/aws-codepipeline-actions/test/{integ.pipeline-cfn-wtih-action-role.expected.json => integ.pipeline-cfn-with-action-role.expected.json} (72%) rename packages/@aws-cdk/aws-codepipeline-actions/test/{integ.pipeline-cfn-wtih-action-role.ts => integ.pipeline-cfn-with-action-role.ts} (100%) diff --git a/packages/@aws-cdk/app-delivery/test/integ.cicd.expected.json b/packages/@aws-cdk/app-delivery/test/integ.cicd.expected.json index 8d3452ccb316c..21344b4d43d45 100644 --- a/packages/@aws-cdk/app-delivery/test/integ.cicd.expected.json +++ b/packages/@aws-cdk/app-delivery/test/integ.cicd.expected.json @@ -1,8 +1,8 @@ { "Resources": { "ArtifactBucket7410C9EF": { - "DeletionPolicy": "Delete", - "Type": "AWS::S3::Bucket" + "Type": "AWS::S3::Bucket", + "DeletionPolicy": "Delete" }, "CodePipelineRoleB3A660B4": { "Type": "AWS::IAM::Role", @@ -70,75 +70,22 @@ ] }, { - "Action": "iam:PassRole", + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "CodePipelineDeployChangeSetRoleF9F2B343", + "CodePipelineDeployExecuteCodePipelineActionRoleAE36AF49", "Arn" ] } }, { - "Action": [ - "cloudformation:CreateChangeSet", - "cloudformation:DeleteChangeSet", - "cloudformation:DescribeChangeSet", - "cloudformation:DescribeStacks" - ], - "Condition": { - "StringEqualsIfExists": { - "cloudformation:ChangeSetName": "CICD-ChangeSet" - } - }, - "Effect": "Allow", - "Resource": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":cloudformation:", - { - "Ref": "AWS::Region" - }, - ":", - { - "Ref": "AWS::AccountId" - }, - ":stack/CICD/*" - ] - ] - } - }, - { - "Action": "cloudformation:ExecuteChangeSet", - "Condition": { - "StringEquals": { - "cloudformation:ChangeSetName": "CICD-ChangeSet" - } - }, + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":cloudformation:", - { - "Ref": "AWS::Region" - }, - ":", - { - "Ref": "AWS::AccountId" - }, - ":stack/CICD/*" - ] + "Fn::GetAtt": [ + "CodePipelineDeployChangeSetCodePipelineActionRoleB3BCDD8A", + "Arn" ] } } @@ -202,15 +149,15 @@ }, "Configuration": { "StackName": "CICD", - "ActionMode": "CHANGE_SET_REPLACE", - "ChangeSetName": "CICD-ChangeSet", - "TemplatePath": "Artifact_CICDGitHubF8BA7ADD::CICD.template.yaml", "RoleArn": { "Fn::GetAtt": [ "CodePipelineDeployChangeSetRoleF9F2B343", "Arn" ] - } + }, + "ActionMode": "CHANGE_SET_REPLACE", + "ChangeSetName": "CICD-ChangeSet", + "TemplatePath": "Artifact_CICDGitHubF8BA7ADD::CICD.template.yaml" }, "InputArtifacts": [ { @@ -219,6 +166,12 @@ ], "Name": "ChangeSet", "OutputArtifacts": [], + "RoleArn": { + "Fn::GetAtt": [ + "CodePipelineDeployChangeSetCodePipelineActionRoleB3BCDD8A", + "Arn" + ] + }, "RunOrder": 10 }, { @@ -236,6 +189,12 @@ "InputArtifacts": [], "Name": "Execute", "OutputArtifacts": [], + "RoleArn": { + "Fn::GetAtt": [ + "CodePipelineDeployExecuteCodePipelineActionRoleAE36AF49", + "Arn" + ] + }, "RunOrder": 999 } ], @@ -254,6 +213,205 @@ "CodePipelineRoleB3A660B4" ] }, + "CodePipelineDeployExecuteCodePipelineActionRoleAE36AF49": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "CodePipelineDeployExecuteCodePipelineActionRoleDefaultPolicy2B66E78C": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "cloudformation:ExecuteChangeSet", + "Condition": { + "StringEquals": { + "cloudformation:ChangeSetName": "CICD-ChangeSet" + } + }, + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":cloudformation:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":stack/CICD/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "CodePipelineDeployExecuteCodePipelineActionRoleDefaultPolicy2B66E78C", + "Roles": [ + { + "Ref": "CodePipelineDeployExecuteCodePipelineActionRoleAE36AF49" + } + ] + } + }, + "CodePipelineDeployChangeSetCodePipelineActionRoleB3BCDD8A": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "CodePipelineDeployChangeSetCodePipelineActionRoleDefaultPolicy87FA0C1E": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "iam:PassRole", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "CodePipelineDeployChangeSetRoleF9F2B343", + "Arn" + ] + } + }, + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "ArtifactBucket7410C9EF", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "ArtifactBucket7410C9EF", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "cloudformation:CreateChangeSet", + "cloudformation:DeleteChangeSet", + "cloudformation:DescribeChangeSet", + "cloudformation:DescribeStacks" + ], + "Condition": { + "StringEqualsIfExists": { + "cloudformation:ChangeSetName": "CICD-ChangeSet" + } + }, + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":cloudformation:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":stack/CICD/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "CodePipelineDeployChangeSetCodePipelineActionRoleDefaultPolicy87FA0C1E", + "Roles": [ + { + "Ref": "CodePipelineDeployChangeSetCodePipelineActionRoleB3BCDD8A" + } + ] + } + }, "CodePipelineDeployChangeSetRoleF9F2B343": { "Type": "AWS::IAM::Role", "Properties": { diff --git a/packages/@aws-cdk/app-delivery/test/test.pipeline-deploy-stack-action.ts b/packages/@aws-cdk/app-delivery/test/test.pipeline-deploy-stack-action.ts index 99f4091e5f743..98eaceb07669d 100644 --- a/packages/@aws-cdk/app-delivery/test/test.pipeline-deploy-stack-action.ts +++ b/packages/@aws-cdk/app-delivery/test/test.pipeline-deploy-stack-action.ts @@ -1,4 +1,4 @@ -import { countResources, expect, haveResource, isSuperObject } from '@aws-cdk/assert'; +import { expect, haveResource, isSuperObject } from '@aws-cdk/assert'; import cfn = require('@aws-cdk/aws-cloudformation'); import codebuild = require('@aws-cdk/aws-codebuild'); import codepipeline = require('@aws-cdk/aws-codepipeline'); @@ -268,9 +268,6 @@ export = nodeunit.testCase({ })); // THEN // - // there should be 3 policies 1. CodePipeline, 2. Codebuild, 3. - // ChangeSetDeploy Action - expect(pipelineStack).to(countResources('AWS::IAM::Policy', 3)); expect(pipelineStack).to(haveResource('AWS::IAM::Policy', { PolicyDocument: { Version: '2012-10-17', diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/cloudformation/pipeline-actions.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/cloudformation/pipeline-actions.ts index b5226c3f132b7..00a0a7313a255 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/cloudformation/pipeline-actions.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/cloudformation/pipeline-actions.ts @@ -9,7 +9,7 @@ import { Action } from '../action'; /** * Properties common to all CloudFormation actions */ -interface CloudFormationActionProps extends codepipeline.CommonActionProps { +interface CloudFormationActionProps extends codepipeline.CommonAwsActionProps { /** * The name of the stack to apply this action to */ @@ -47,15 +47,6 @@ interface CloudFormationActionProps extends codepipeline.CommonActionProps { * @default the Action resides in the same region as the Pipeline */ readonly region?: string; - - /** - * The service role that is assumed during execution of action. - * This role is not mandatory, however more advanced configuration - * may require specifying it. - * - * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codepipeline-pipeline-stages-actions.html - */ - readonly role?: iam.IRole; } /** @@ -84,8 +75,16 @@ abstract class CloudFormationAction extends Action { this.props = props; } - protected bound(_scope: cdk.Construct, _stage: codepipeline.IStage, _options: codepipeline.ActionBindOptions): + protected bound(_scope: cdk.Construct, stage: codepipeline.IStage, options: codepipeline.ActionBindOptions): codepipeline.ActionConfig { + const singletonPolicy = SingletonPolicy.forRole(options.role); + + if ((this.actionProperties.outputs || []).length > 0) { + stage.pipeline.artifactBucket.grantReadWrite(singletonPolicy); + } else if ((this.actionProperties.inputs || []).length > 0) { + stage.pipeline.artifactBucket.grantRead(singletonPolicy); + } + return { configuration: { StackName: this.props.stackName, @@ -471,7 +470,7 @@ export class CloudFormationDeleteStackAction extends CloudFormationDeployAction * Statements created outside of this class are not considered when adding new * permissions. */ -class SingletonPolicy extends cdk.Construct { +class SingletonPolicy extends cdk.Construct implements iam.IGrantable { /** * Obtain a SingletonPolicy for a given role. * @param role the Role this policy is bound to. @@ -484,10 +483,13 @@ class SingletonPolicy extends cdk.Construct { private static readonly UUID = '8389e75f-0810-4838-bf64-d6f85a95cf83'; + public readonly grantPrincipal: iam.IPrincipal; + private statements: { [key: string]: iam.PolicyStatement } = {}; private constructor(private readonly role: iam.IRole) { super(role as unknown as cdk.Construct, SingletonPolicy.UUID); + this.grantPrincipal = role; } public grantExecuteChangeSet(props: { stackName: string, changeSetName: string, region?: string }): void { diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/codebuild/build-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/codebuild/build-action.ts index c666beea98ea5..521d972cc05e3 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/codebuild/build-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/codebuild/build-action.ts @@ -25,7 +25,7 @@ export enum CodeBuildActionType { /** * Construction properties of the {@link CodeBuildAction CodeBuild build CodePipeline action}. */ -export interface CodeBuildActionProps extends codepipeline.CommonActionProps { +export interface CodeBuildActionProps extends codepipeline.CommonAwsActionProps { /** * The source to use as input for this action. */ diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/codecommit/source-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/codecommit/source-action.ts index 7613c6bb7bb56..74afd97c2c3c9 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/codecommit/source-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/codecommit/source-action.ts @@ -32,7 +32,7 @@ export enum CodeCommitTrigger { /** * Construction properties of the {@link CodeCommitSourceAction CodeCommit source CodePipeline Action}. */ -export interface CodeCommitSourceActionProps extends codepipeline.CommonActionProps { +export interface CodeCommitSourceActionProps extends codepipeline.CommonAwsActionProps { /** * */ @@ -89,6 +89,10 @@ export class CodeCommitSourceAction extends Action { }); } + // the Action will write the contents of the Git repository to the Bucket, + // so its Role needs write permissions to the Pipeline Bucket + stage.pipeline.artifactBucket.grantWrite(options.role); + // https://docs.aws.amazon.com/codecommit/latest/userguide/auth-and-access-control-permissions-reference.html#aa-acp options.role.addToPolicy(new iam.PolicyStatement({ resources: [this.props.repository.repositoryArn], diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/codedeploy/server-deploy-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/codedeploy/server-deploy-action.ts index c5e3f9e732a62..8b3cc864c1e24 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/codedeploy/server-deploy-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/codedeploy/server-deploy-action.ts @@ -8,7 +8,7 @@ import { deployArtifactBounds } from '../common'; /** * Construction properties of the {@link CodeDeployServerDeployAction CodeDeploy server deploy CodePipeline Action}. */ -export interface CodeDeployServerDeployActionProps extends codepipeline.CommonActionProps { +export interface CodeDeployServerDeployActionProps extends codepipeline.CommonAwsActionProps { /** * The source to use as input for deployment. */ @@ -60,6 +60,9 @@ export class CodeDeployServerDeployAction extends Action { stage.pipeline.artifactBucket.grantRead(asg.role); } + // the Action's Role needs to read from the Bucket to get artifacts + stage.pipeline.artifactBucket.grantRead(options.role); + return { configuration: { ApplicationName: this.deploymentGroup.application.applicationName, diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/ecr/source-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/ecr/source-action.ts index 5a739a3528228..ae41f8b3bbc47 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/ecr/source-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/ecr/source-action.ts @@ -9,7 +9,7 @@ import { sourceArtifactBounds } from '../common'; /** * Construction properties of {@link EcrSourceAction}. */ -export interface EcrSourceActionProps extends codepipeline.CommonActionProps { +export interface EcrSourceActionProps extends codepipeline.CommonAwsActionProps { /** * The image tag that will be checked for changes. * @@ -62,6 +62,9 @@ export class EcrSourceAction extends Action { imageTag: this.props.imageTag }); + // the Action Role also needs to write to the Pipeline's bucket + stage.pipeline.artifactBucket.grantWrite(options.role); + return { configuration: { RepositoryName: this.props.repository.repositoryName, diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/ecs/deploy-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/ecs/deploy-action.ts index 70d4133af48f8..b750a27c2499d 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/ecs/deploy-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/ecs/deploy-action.ts @@ -8,7 +8,7 @@ import { deployArtifactBounds } from '../common'; /** * Construction properties of {@link EcsDeployAction}. */ -export interface EcsDeployActionProps extends codepipeline.CommonActionProps { +export interface EcsDeployActionProps extends codepipeline.CommonAwsActionProps { /** * The input artifact that contains the JSON image definitions file to use for deployments. * The JSON file is a list of objects, @@ -61,7 +61,7 @@ export class EcsDeployAction extends Action { this.props = props; } - protected bound(_scope: Construct, _stage: codepipeline.IStage, options: codepipeline.ActionBindOptions): + protected bound(_scope: Construct, stage: codepipeline.IStage, options: codepipeline.ActionBindOptions): codepipeline.ActionConfig { // permissions based on CodePipeline documentation: // https://docs.aws.amazon.com/codepipeline/latest/userguide/how-to-custom-role.html#how-to-update-role-new-services @@ -90,6 +90,8 @@ export class EcsDeployAction extends Action { } })); + stage.pipeline.artifactBucket.grantRead(options.role); + return { configuration: { ClusterName: this.props.service.cluster.clusterName, diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/lambda/invoke-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/lambda/invoke-action.ts index 9349d7ca42926..f9053aed6fd3c 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/lambda/invoke-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/lambda/invoke-action.ts @@ -7,7 +7,7 @@ import { Action } from '../action'; /** * Construction properties of the {@link LambdaInvokeAction Lambda invoke CodePipeline Action}. */ -export interface LambdaInvokeActionProps extends codepipeline.CommonActionProps { +export interface LambdaInvokeActionProps extends codepipeline.CommonAwsActionProps { // because of @see links // tslint:disable:max-line-length diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/manual-approval-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/manual-approval-action.ts index 246c1f3b24d26..ce3caa081b2d4 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/manual-approval-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/manual-approval-action.ts @@ -7,7 +7,7 @@ import { Action } from './action'; /** * Construction properties of the {@link ManualApprovalAction}. */ -export interface ManualApprovalActionProps extends codepipeline.CommonActionProps { +export interface ManualApprovalActionProps extends codepipeline.CommonAwsActionProps { /** * Optional SNS topic to send notifications to when an approval is pending. */ diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/s3/deploy-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/s3/deploy-action.ts index de49e45088035..75c1ab12781b2 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/s3/deploy-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/s3/deploy-action.ts @@ -7,7 +7,7 @@ import { deployArtifactBounds } from '../common'; /** * Construction properties of the {@link S3DeployAction S3 deploy Action}. */ -export interface S3DeployActionProps extends codepipeline.CommonActionProps { +export interface S3DeployActionProps extends codepipeline.CommonAwsActionProps { /** * Should the deploy action extract the artifact before deploying to Amazon S3. * @@ -49,11 +49,14 @@ export class S3DeployAction extends Action { this.props = props; } - protected bound(_scope: Construct, _stage: codepipeline.IStage, options: codepipeline.ActionBindOptions): + protected bound(_scope: Construct, stage: codepipeline.IStage, options: codepipeline.ActionBindOptions): codepipeline.ActionConfig { // pipeline needs permissions to write to the S3 bucket this.props.bucket.grantWrite(options.role); + // the Action Role also needs to read from the Pipeline's bucket + stage.pipeline.artifactBucket.grantRead(options.role); + return { configuration: { BucketName: this.props.bucket.bucketName, diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/s3/source-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/s3/source-action.ts index 6c875cba6b1c2..f4242dc40294d 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/s3/source-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/s3/source-action.ts @@ -33,7 +33,7 @@ export enum S3Trigger { /** * Construction properties of the {@link S3SourceAction S3 source Action}. */ -export interface S3SourceActionProps extends codepipeline.CommonActionProps { +export interface S3SourceActionProps extends codepipeline.CommonAwsActionProps { /** * */ @@ -92,9 +92,12 @@ export class S3SourceAction extends Action { }); } - // pipeline needs permissions to read from the S3 bucket + // we need to read from the source bucket... this.props.bucket.grantRead(options.role); + // ...and write to the Pipeline bucket + stage.pipeline.artifactBucket.grantWrite(options.role); + return { configuration: { S3Bucket: this.props.bucket.bucketName, diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/cloudformation/test.pipeline-actions.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/cloudformation/test.pipeline-actions.ts index a817699b795bd..c3a18465f371f 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/cloudformation/test.pipeline-actions.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/cloudformation/test.pipeline-actions.ts @@ -308,16 +308,14 @@ class PipelineDouble extends cdk.Resource implements codepipeline.IPipeline { public readonly pipelineName: string; public readonly pipelineArn: string; public readonly role: iam.Role; + public readonly artifactBucket: s3.IBucket; constructor(scope: cdk.Construct, id: string, { pipelineName, role }: { pipelineName?: string, role: iam.Role }) { super(scope, id); this.pipelineName = pipelineName || 'TestPipeline'; this.pipelineArn = Stack.of(this).formatArn({ service: 'codepipeline', resource: 'pipeline', resourceName: this.pipelineName }); this.role = role; - } - - public get artifactBucket(): s3.IBucket { - throw new Error('artifactBucket is unsupported in PipelineDouble'); + this.artifactBucket = new BucketDouble(scope, 'BucketDouble'); } public onEvent(_id: string, _options: events.OnEventOptions): events.Rule { @@ -383,6 +381,20 @@ class RoleDouble extends iam.Role { } } +class BucketDouble extends s3.Bucket { + public grantRead(identity: iam.IGrantable, _objectsKeyPattern: any = '*'): iam.Grant { + return iam.Grant.drop(identity, ''); + } + + public grantWrite(identity: iam.IGrantable, _objectsKeyPattern: any = '*'): iam.Grant { + return iam.Grant.drop(identity, ''); + } + + public grantReadWrite(identity: iam.IGrantable, _objectsKeyPattern: any = '*'): iam.Grant { + return iam.Grant.drop(identity, ''); + } +} + function resolve(x: any): any { return new cdk.Stack().resolve(x); } diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.expected.json b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.expected.json index f80827ddacf12..a10e73ff2e813 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.expected.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.expected.json @@ -66,6 +66,39 @@ } }, "Resource": "*" + }, + { + "Action": [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "PipelineSourceCodePipelineActionRoleC6F9E7F5", + "Arn" + ] + } + }, + "Resource": "*" + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "PipelineDeployPrepareChangesCodePipelineActionRole41931444", + "Arn" + ] + } + }, + "Resource": "*" } ], "Version": "2012-10-17" @@ -176,91 +209,42 @@ } }, { - "Action": [ - "codecommit:GetBranch", - "codecommit:GetCommit", - "codecommit:UploadArchive", - "codecommit:GetUploadArchiveStatus", - "codecommit:CancelUploadArchive" - ], + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "TemplateRepo2326F199", + "PipelineSourceCodePipelineActionRoleC6F9E7F5", "Arn" ] } }, { - "Action": "iam:PassRole", + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "PipelineDeployPrepareChangesRoleD28C853C", + "PipelineDeployPrepareChangesCodePipelineActionRole41931444", "Arn" ] } }, { - "Action": [ - "cloudformation:CreateChangeSet", - "cloudformation:DeleteChangeSet", - "cloudformation:DescribeChangeSet", - "cloudformation:DescribeStacks" - ], - "Condition": { - "StringEqualsIfExists": { - "cloudformation:ChangeSetName": "StagedChangeSet" - } - }, + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":cloudformation:", - { - "Ref": "AWS::Region" - }, - ":", - { - "Ref": "AWS::AccountId" - }, - ":stack/OurStack/*" - ] + "Fn::GetAtt": [ + "PipelineDeployApproveChangesCodePipelineActionRole5AA6E21B", + "Arn" ] } }, { - "Action": "cloudformation:ExecuteChangeSet", - "Condition": { - "StringEquals": { - "cloudformation:ChangeSetName": "StagedChangeSet" - } - }, + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":cloudformation:", - { - "Ref": "AWS::Region" - }, - ":", - { - "Ref": "AWS::AccountId" - }, - ":stack/OurStack/*" - ] + "Fn::GetAtt": [ + "PipelineDeployExecuteChangesCodePipelineActionRole6AA2756F", + "Arn" ] } } @@ -311,6 +295,12 @@ "Name": "SourceArtifact" } ], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineSourceCodePipelineActionRoleC6F9E7F5", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -327,16 +317,16 @@ }, "Configuration": { "StackName": "OurStack", - "ActionMode": "CHANGE_SET_REPLACE", - "ChangeSetName": "StagedChangeSet", - "TemplatePath": "SourceArtifact::template.yaml", "Capabilities": "CAPABILITY_NAMED_IAM", "RoleArn": { "Fn::GetAtt": [ "PipelineDeployPrepareChangesRoleD28C853C", "Arn" ] - } + }, + "ActionMode": "CHANGE_SET_REPLACE", + "ChangeSetName": "StagedChangeSet", + "TemplatePath": "SourceArtifact::template.yaml" }, "InputArtifacts": [ { @@ -345,6 +335,12 @@ ], "Name": "PrepareChanges", "OutputArtifacts": [], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineDeployPrepareChangesCodePipelineActionRole41931444", + "Arn" + ] + }, "RunOrder": 1 }, { @@ -357,6 +353,12 @@ "InputArtifacts": [], "Name": "ApproveChanges", "OutputArtifacts": [], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineDeployApproveChangesCodePipelineActionRole5AA6E21B", + "Arn" + ] + }, "RunOrder": 2 }, { @@ -374,6 +376,12 @@ "InputArtifacts": [], "Name": "ExecuteChanges", "OutputArtifacts": [], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineDeployExecuteChangesCodePipelineActionRole6AA2756F", + "Arn" + ] + }, "RunOrder": 3 } ], @@ -401,6 +409,249 @@ "PipelineRoleD68726F7" ] }, + "PipelineSourceCodePipelineActionRoleC6F9E7F5": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineSourceCodePipelineActionRoleDefaultPolicy2D565925": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + }, + { + "Action": [ + "codecommit:GetBranch", + "codecommit:GetCommit", + "codecommit:UploadArchive", + "codecommit:GetUploadArchiveStatus", + "codecommit:CancelUploadArchive" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "TemplateRepo2326F199", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineSourceCodePipelineActionRoleDefaultPolicy2D565925", + "Roles": [ + { + "Ref": "PipelineSourceCodePipelineActionRoleC6F9E7F5" + } + ] + } + }, + "PipelineDeployPrepareChangesCodePipelineActionRole41931444": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineDeployPrepareChangesCodePipelineActionRoleDefaultPolicyAD3C24A3": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "iam:PassRole", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineDeployPrepareChangesRoleD28C853C", + "Arn" + ] + } + }, + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + }, + { + "Action": [ + "cloudformation:CreateChangeSet", + "cloudformation:DeleteChangeSet", + "cloudformation:DescribeChangeSet", + "cloudformation:DescribeStacks" + ], + "Condition": { + "StringEqualsIfExists": { + "cloudformation:ChangeSetName": "StagedChangeSet" + } + }, + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":cloudformation:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":stack/OurStack/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineDeployPrepareChangesCodePipelineActionRoleDefaultPolicyAD3C24A3", + "Roles": [ + { + "Ref": "PipelineDeployPrepareChangesCodePipelineActionRole41931444" + } + ] + } + }, "PipelineDeployPrepareChangesRoleD28C853C": { "Type": "AWS::IAM::Role", "Properties": { @@ -448,6 +699,115 @@ } ] } + }, + "PipelineDeployApproveChangesCodePipelineActionRole5AA6E21B": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineDeployExecuteChangesCodePipelineActionRole6AA2756F": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineDeployExecuteChangesCodePipelineActionRoleDefaultPolicy70764525": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "cloudformation:ExecuteChangeSet", + "Condition": { + "StringEquals": { + "cloudformation:ChangeSetName": "StagedChangeSet" + } + }, + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":cloudformation:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":stack/OurStack/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineDeployExecuteChangesCodePipelineActionRoleDefaultPolicy70764525", + "Roles": [ + { + "Ref": "PipelineDeployExecuteChangesCodePipelineActionRole6AA2756F" + } + ] + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.expected.json b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.expected.json index bb1f382803b72..341eafcf03554 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.expected.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.expected.json @@ -60,6 +60,40 @@ }, "Resource": "*" }, + { + "Action": [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "PipelineSourceCdkCodeSourceCodePipelineActionRole237947B8", + "Arn" + ] + } + }, + "Resource": "*" + }, + { + "Action": [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "PipelineSourceLambdaCodeSourceCodePipelineActionRole4E89EF60", + "Arn" + ] + } + }, + "Resource": "*" + }, { "Action": [ "kms:Decrypt", @@ -97,6 +131,22 @@ } }, "Resource": "*" + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "PipelineDeployLambdaCFNDeployCodePipelineActionRoleF8A74488", + "Arn" + ] + } + }, + "Resource": "*" } ], "Version": "2012-10-17" @@ -207,106 +257,54 @@ } }, { - "Action": [ - "codecommit:GetBranch", - "codecommit:GetCommit", - "codecommit:UploadArchive", - "codecommit:GetUploadArchiveStatus", - "codecommit:CancelUploadArchive" - ], + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "CdkCodeRepo7D2EC742", + "PipelineSourceCdkCodeSourceCodePipelineActionRole237947B8", "Arn" ] } }, { - "Action": [ - "codecommit:GetBranch", - "codecommit:GetCommit", - "codecommit:UploadArchive", - "codecommit:GetUploadArchiveStatus", - "codecommit:CancelUploadArchive" - ], + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "LambdaCodeRepoE08DD409", + "PipelineSourceLambdaCodeSourceCodePipelineActionRole4E89EF60", "Arn" ] } }, { - "Action": [ - "codebuild:BatchGetBuilds", - "codebuild:StartBuild", - "codebuild:StopBuild" - ], + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "CdkBuildProject9382C38D", + "PipelineBuildCDKBuildCodePipelineActionRole15F4B424", "Arn" ] } }, { - "Action": [ - "codebuild:BatchGetBuilds", - "codebuild:StartBuild", - "codebuild:StopBuild" - ], + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "LambdaBuildProject7E2DAB11", + "PipelineBuildLambdaBuildCodePipelineActionRole2DAE39E9", "Arn" ] } }, { - "Action": "iam:PassRole", + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "PipelineDeployLambdaCFNDeployRole89CA1043", + "PipelineDeployLambdaCFNDeployCodePipelineActionRoleF8A74488", "Arn" ] } - }, - { - "Action": [ - "cloudformation:CreateStack", - "cloudformation:DescribeStack*", - "cloudformation:GetStackPolicy", - "cloudformation:GetTemplate*", - "cloudformation:SetStackPolicy", - "cloudformation:UpdateStack", - "cloudformation:ValidateTemplate" - ], - "Effect": "Allow", - "Resource": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":cloudformation:", - { - "Ref": "AWS::Region" - }, - ":", - { - "Ref": "AWS::AccountId" - }, - ":stack/LambdaStackDeployedName/*" - ] - ] - } } ], "Version": "2012-10-17" @@ -355,6 +353,12 @@ "Name": "Artifact_Source_CdkCode_Source" } ], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineSourceCdkCodeSourceCodePipelineActionRole237947B8", + "Arn" + ] + }, "RunOrder": 1 }, { @@ -381,6 +385,12 @@ "Name": "Artifact_Source_LambdaCode_Source" } ], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineSourceLambdaCodeSourceCodePipelineActionRole4E89EF60", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -411,6 +421,12 @@ "Name": "Artifact_Build_CDK_Build" } ], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineBuildCDKBuildCodePipelineActionRole15F4B424", + "Arn" + ] + }, "RunOrder": 1 }, { @@ -436,6 +452,12 @@ "Name": "Artifact_Build_Lambda_Build" } ], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineBuildLambdaBuildCodePipelineActionRole2DAE39E9", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -452,8 +474,6 @@ }, "Configuration": { "StackName": "LambdaStackDeployedName", - "ActionMode": "CREATE_UPDATE", - "TemplatePath": "Artifact_Build_CDK_Build::LambdaStack.template.yaml", "Capabilities": "CAPABILITY_NAMED_IAM", "RoleArn": { "Fn::GetAtt": [ @@ -461,7 +481,9 @@ "Arn" ] }, - "ParameterOverrides": "{\"LambdaLambdaSourceBucketNameParameter159473FC\":{\"Fn::GetArtifactAtt\":[\"Artifact_Build_Lambda_Build\",\"BucketName\"]},\"LambdaLambdaSourceObjectKeyParameter06573F1D\":{\"Fn::GetArtifactAtt\":[\"Artifact_Build_Lambda_Build\",\"ObjectKey\"]}}" + "ParameterOverrides": "{\"LambdaLambdaSourceBucketNameParameter159473FC\":{\"Fn::GetArtifactAtt\":[\"Artifact_Build_Lambda_Build\",\"BucketName\"]},\"LambdaLambdaSourceObjectKeyParameter06573F1D\":{\"Fn::GetArtifactAtt\":[\"Artifact_Build_Lambda_Build\",\"ObjectKey\"]}}", + "ActionMode": "CREATE_UPDATE", + "TemplatePath": "Artifact_Build_CDK_Build::LambdaStack.template.yaml" }, "InputArtifacts": [ { @@ -473,6 +495,12 @@ ], "Name": "Lambda_CFN_Deploy", "OutputArtifacts": [], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineDeployLambdaCFNDeployCodePipelineActionRoleF8A74488", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -500,7 +528,7 @@ "PipelineRoleD68726F7" ] }, - "PipelineEventsRole46BEEA7C": { + "PipelineSourceCdkCodeSourceCodePipelineActionRole237947B8": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { @@ -509,14 +537,19 @@ "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { - "Service": { + "AWS": { "Fn::Join": [ "", [ - "events.", + "arn:", { - "Ref": "AWS::URLSuffix" - } + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" ] ] } @@ -527,45 +560,513 @@ } } }, - "PipelineEventsRoleDefaultPolicyFF4FCCE0": { + "PipelineSourceCdkCodeSourceCodePipelineActionRoleDefaultPolicy219D4917": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyDocument": { "Statement": [ { - "Action": "codepipeline:StartPipelineExecution", + "Action": [ + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*" + ], "Effect": "Allow", - "Resource": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":codepipeline:", - { - "Ref": "AWS::Region" - }, - ":", - { - "Ref": "AWS::AccountId" - }, - ":", - { - "Ref": "PipelineC660917D" - } + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + "/*" + ] ] + } + ] + }, + { + "Action": [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + }, + { + "Action": [ + "codecommit:GetBranch", + "codecommit:GetCommit", + "codecommit:UploadArchive", + "codecommit:GetUploadArchiveStatus", + "codecommit:CancelUploadArchive" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "CdkCodeRepo7D2EC742", + "Arn" ] } } ], "Version": "2012-10-17" }, - "PolicyName": "PipelineEventsRoleDefaultPolicyFF4FCCE0", + "PolicyName": "PipelineSourceCdkCodeSourceCodePipelineActionRoleDefaultPolicy219D4917", "Roles": [ { - "Ref": "PipelineEventsRole46BEEA7C" + "Ref": "PipelineSourceCdkCodeSourceCodePipelineActionRole237947B8" + } + ] + } + }, + "PipelineSourceLambdaCodeSourceCodePipelineActionRole4E89EF60": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineSourceLambdaCodeSourceCodePipelineActionRoleDefaultPolicyAD234A91": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + }, + { + "Action": [ + "codecommit:GetBranch", + "codecommit:GetCommit", + "codecommit:UploadArchive", + "codecommit:GetUploadArchiveStatus", + "codecommit:CancelUploadArchive" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "LambdaCodeRepoE08DD409", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineSourceLambdaCodeSourceCodePipelineActionRoleDefaultPolicyAD234A91", + "Roles": [ + { + "Ref": "PipelineSourceLambdaCodeSourceCodePipelineActionRole4E89EF60" + } + ] + } + }, + "PipelineEventsRole46BEEA7C": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": { + "Fn::Join": [ + "", + [ + "events.", + { + "Ref": "AWS::URLSuffix" + } + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineEventsRoleDefaultPolicyFF4FCCE0": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "codepipeline:StartPipelineExecution", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":codepipeline:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":", + { + "Ref": "PipelineC660917D" + } + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineEventsRoleDefaultPolicyFF4FCCE0", + "Roles": [ + { + "Ref": "PipelineEventsRole46BEEA7C" + } + ] + } + }, + "PipelineBuildCDKBuildCodePipelineActionRole15F4B424": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineBuildCDKBuildCodePipelineActionRoleDefaultPolicyE350F3F9": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "codebuild:BatchGetBuilds", + "codebuild:StartBuild", + "codebuild:StopBuild" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "CdkBuildProject9382C38D", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineBuildCDKBuildCodePipelineActionRoleDefaultPolicyE350F3F9", + "Roles": [ + { + "Ref": "PipelineBuildCDKBuildCodePipelineActionRole15F4B424" + } + ] + } + }, + "PipelineBuildLambdaBuildCodePipelineActionRole2DAE39E9": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineBuildLambdaBuildCodePipelineActionRoleDefaultPolicy3CA005F2": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "codebuild:BatchGetBuilds", + "codebuild:StartBuild", + "codebuild:StopBuild" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "LambdaBuildProject7E2DAB11", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineBuildLambdaBuildCodePipelineActionRoleDefaultPolicy3CA005F2", + "Roles": [ + { + "Ref": "PipelineBuildLambdaBuildCodePipelineActionRole2DAE39E9" + } + ] + } + }, + "PipelineDeployLambdaCFNDeployCodePipelineActionRoleF8A74488": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineDeployLambdaCFNDeployCodePipelineActionRoleDefaultPolicy54A1AB67": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "iam:PassRole", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineDeployLambdaCFNDeployRole89CA1043", + "Arn" + ] + } + }, + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + }, + { + "Action": [ + "cloudformation:CreateStack", + "cloudformation:DescribeStack*", + "cloudformation:GetStackPolicy", + "cloudformation:GetTemplate*", + "cloudformation:SetStackPolicy", + "cloudformation:UpdateStack", + "cloudformation:ValidateTemplate" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":cloudformation:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":stack/LambdaStackDeployedName/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineDeployLambdaCFNDeployCodePipelineActionRoleDefaultPolicy54A1AB67", + "Roles": [ + { + "Ref": "PipelineDeployLambdaCFNDeployCodePipelineActionRoleF8A74488" } ] } diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-pipeline.expected.json b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-pipeline.expected.json index 58afdf9cc9518..d0169c49a5d88 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-pipeline.expected.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-pipeline.expected.json @@ -59,6 +59,23 @@ } }, "Resource": "*" + }, + { + "Action": [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "PipelineSourceCodePipelineActionRoleC6F9E7F5", + "Arn" + ] + } + }, + "Resource": "*" } ], "Version": "2012-10-17" @@ -169,46 +186,21 @@ } }, { - "Action": [ - "s3:GetObject*", - "s3:GetBucket*", - "s3:List*" - ], - "Effect": "Allow", - "Resource": [ - { - "Fn::GetAtt": [ - "PipelineBucketB967BD35", - "Arn" - ] - }, - { - "Fn::Join": [ - "", - [ - { - "Fn::GetAtt": [ - "PipelineBucketB967BD35", - "Arn" - ] - }, - "/*" - ] - ] - } - ] - }, - { - "Action": "lambda:ListFunctions", + "Action": "sts:AssumeRole", "Effect": "Allow", - "Resource": "*" + "Resource": { + "Fn::GetAtt": [ + "PipelineSourceCodePipelineActionRoleC6F9E7F5", + "Arn" + ] + } }, { - "Action": "lambda:InvokeFunction", + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "LambdaFun98622869", + "PipelineLambdaCodePipelineActionRoleC6032822", "Arn" ] } @@ -257,6 +249,12 @@ "Name": "SourceArtifact" } ], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineSourceCodePipelineActionRoleC6F9E7F5", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -279,6 +277,12 @@ "InputArtifacts": [], "Name": "Lambda", "OutputArtifacts": [], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineLambdaCodePipelineActionRoleC6032822", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -306,6 +310,129 @@ "PipelineRoleD68726F7" ] }, + "PipelineSourceCodePipelineActionRoleC6F9E7F5": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineSourceCodePipelineActionRoleDefaultPolicy2D565925": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineBucketB967BD35", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineBucketB967BD35", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + + { + "Action": [ + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineSourceCodePipelineActionRoleDefaultPolicy2D565925", + "Roles": [ + { + "Ref": "PipelineSourceCodePipelineActionRoleC6F9E7F5" + } + ] + } + }, "PipelineEventsRole46BEEA7C": { "Type": "AWS::IAM::Role", "Properties": { @@ -376,14 +503,77 @@ ] } }, + "PipelineLambdaCodePipelineActionRoleC6032822": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineLambdaCodePipelineActionRoleDefaultPolicyFEE90F93": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "lambda:ListFunctions", + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": "lambda:InvokeFunction", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "LambdaFun98622869", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineLambdaCodePipelineActionRoleDefaultPolicyFEE90F93", + "Roles": [ + { + "Ref": "PipelineLambdaCodePipelineActionRoleC6032822" + } + ] + } + }, "PipelineBucketB967BD35": { "Type": "AWS::S3::Bucket", - "DeletionPolicy": "Delete", "Properties": { "VersioningConfiguration": { "Status": "Enabled" } - } + }, + "DeletionPolicy": "Delete" }, "PipelineBucketawscdkcodepipelinelambdaPipeline87A4B3D3SourceEventRuleCE4D4505": { "Type": "AWS::Events::Rule", @@ -396,9 +586,6 @@ "AWS API Call via CloudTrail" ], "detail": { - "eventName": [ - "PutObject" - ], "resources": { "ARN": [ { @@ -416,7 +603,10 @@ ] } ] - } + }, + "eventName": [ + "PutObject" + ] } }, "State": "ENABLED", diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-alexa-deploy.expected.json b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-alexa-deploy.expected.json index 2b65b738ce939..7a6003eaa502b 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-alexa-deploy.expected.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-alexa-deploy.expected.json @@ -1,8 +1,16 @@ { "Resources": { - "PipelineArtifactsBucketEncryptionKey01D58D69" : { + "PipelineBucketB967BD35": { + "Type": "AWS::S3::Bucket", + "Properties": { + "VersioningConfiguration": { + "Status": "Enabled" + } + }, + "DeletionPolicy": "Delete" + }, + "PipelineArtifactsBucketEncryptionKey01D58D69": { "Type": "AWS::KMS::Key", - "DeletionPolicy": "Retain", "Properties": { "KeyPolicy": { "Statement": [ @@ -60,24 +68,32 @@ } }, "Resource": "*" + }, + { + "Action": [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "PipelineSourceCodePipelineActionRoleC6F9E7F5", + "Arn" + ] + } + }, + "Resource": "*" } ], "Version": "2012-10-17" } - } - }, - "PipelineBucketB967BD35": { - "Type": "AWS::S3::Bucket", - "DeletionPolicy": "Delete", - "Properties": { - "VersioningConfiguration": { - "Status": "Enabled" - } - } + }, + "DeletionPolicy": "Retain" }, "PipelineArtifactsBucket22248F97": { "Type": "AWS::S3::Bucket", - "DeletionPolicy": "Retain", "Properties": { "BucketEncryption": { "ServerSideEncryptionConfiguration": [ @@ -94,7 +110,8 @@ } ] } - } + }, + "DeletionPolicy": "Retain" }, "PipelineRoleD68726F7": { "Type": "AWS::IAM::Role", @@ -178,34 +195,14 @@ } }, { - "Action": [ - "s3:GetObject*", - "s3:GetBucket*", - "s3:List*" - ], + "Action": "sts:AssumeRole", "Effect": "Allow", - "Resource": [ - { - "Fn::GetAtt": [ - "PipelineBucketB967BD35", - "Arn" - ] - }, - { - "Fn::Join": [ - "", - [ - { - "Fn::GetAtt": [ - "PipelineBucketB967BD35", - "Arn" - ] - }, - "/*" - ] - ] - } - ] + "Resource": { + "Fn::GetAtt": [ + "PipelineSourceCodePipelineActionRoleC6F9E7F5", + "Arn" + ] + } } ], "Version": "2012-10-17" @@ -250,6 +247,12 @@ "Name": "SourceArtifact" } ], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineSourceCodePipelineActionRoleC6F9E7F5", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -284,10 +287,6 @@ } ], "ArtifactStore": { - "Location": { - "Ref": "PipelineArtifactsBucket22248F97" - }, - "Type": "S3", "EncryptionKey": { "Id": { "Fn::GetAtt": [ @@ -296,13 +295,139 @@ ] }, "Type": "KMS" - } + }, + "Location": { + "Ref": "PipelineArtifactsBucket22248F97" + }, + "Type": "S3" } }, "DependsOn": [ "PipelineRoleDefaultPolicyC7A05455", "PipelineRoleD68726F7" ] + }, + "PipelineSourceCodePipelineActionRoleC6F9E7F5": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineSourceCodePipelineActionRoleDefaultPolicy2D565925": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineBucketB967BD35", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineBucketB967BD35", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineSourceCodePipelineActionRoleDefaultPolicy2D565925", + "Roles": [ + { + "Ref": "PipelineSourceCodePipelineActionRoleC6F9E7F5" + } + ] + } } } } diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn-cross-region.expected.json b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn-cross-region.expected.json index 7d1c7317d9df9..2d539da7db911 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn-cross-region.expected.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn-cross-region.expected.json @@ -2,12 +2,12 @@ "Resources": { "MyBucketF68F3FF0": { "Type": "AWS::S3::Bucket", - "DeletionPolicy": "Delete", "Properties": { "VersioningConfiguration": { "Status": "Enabled" } - } + }, + "DeletionPolicy": "Delete" }, "MyPipelineRoleC0D47CA4": { "Type": "AWS::IAM::Role", @@ -75,70 +75,22 @@ ] }, { - "Action": [ - "s3:GetObject*", - "s3:GetBucket*", - "s3:List*" - ], - "Effect": "Allow", - "Resource": [ - { - "Fn::GetAtt": [ - "MyBucketF68F3FF0", - "Arn" - ] - }, - { - "Fn::Join": [ - "", - [ - { - "Fn::GetAtt": [ - "MyBucketF68F3FF0", - "Arn" - ] - }, - "/*" - ] - ] - } - ] - }, - { - "Action": "iam:PassRole", + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "MyPipelineCFNCFNDeployRole9CC99B3F", + "MyPipelineSourceS3CodePipelineActionRole9F003087", "Arn" ] } }, { - "Action": [ - "cloudformation:CreateStack", - "cloudformation:DescribeStack*", - "cloudformation:GetStackPolicy", - "cloudformation:GetTemplate*", - "cloudformation:SetStackPolicy", - "cloudformation:UpdateStack", - "cloudformation:ValidateTemplate" - ], + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":cloudformation:us-west-2:", - { - "Ref": "AWS::AccountId" - }, - ":stack/aws-cdk-codepipeline-cross-region-deploy-stack/*" - ] + "Fn::GetAtt": [ + "MyPipelineCFNCFNDeployCodePipelineActionRole31B1904C", + "Arn" ] } } @@ -185,6 +137,12 @@ "Name": "Artifact_Source_S3" } ], + "RoleArn": { + "Fn::GetAtt": [ + "MyPipelineSourceS3CodePipelineActionRole9F003087", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -201,14 +159,14 @@ }, "Configuration": { "StackName": "aws-cdk-codepipeline-cross-region-deploy-stack", - "ActionMode": "CREATE_UPDATE", - "TemplatePath": "Artifact_Source_S3::template.yml", "RoleArn": { "Fn::GetAtt": [ "MyPipelineCFNCFNDeployRole9CC99B3F", "Arn" ] - } + }, + "ActionMode": "CREATE_UPDATE", + "TemplatePath": "Artifact_Source_S3::template.yml" }, "InputArtifacts": [ { @@ -217,8 +175,14 @@ ], "Name": "CFN_Deploy", "OutputArtifacts": [], - "RunOrder": 1, - "Region": "us-west-2" + "Region": "us-west-2", + "RoleArn": { + "Fn::GetAtt": [ + "MyPipelineCFNCFNDeployCodePipelineActionRole31B1904C", + "Arn" + ] + }, + "RunOrder": 1 } ], "Name": "CFN" @@ -226,13 +190,13 @@ ], "ArtifactStores": [ { - "Region": "us-west-2", "ArtifactStore": { "Location": { "Ref": "MyBucketF68F3FF0" }, "Type": "S3" - } + }, + "Region": "us-west-2" } ] }, @@ -241,6 +205,230 @@ "MyPipelineRoleC0D47CA4" ] }, + "MyPipelineSourceS3CodePipelineActionRole9F003087": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "MyPipelineSourceS3CodePipelineActionRoleDefaultPolicyF838EE0B": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyPipelineSourceS3CodePipelineActionRoleDefaultPolicyF838EE0B", + "Roles": [ + { + "Ref": "MyPipelineSourceS3CodePipelineActionRole9F003087" + } + ] + } + }, + "MyPipelineCFNCFNDeployCodePipelineActionRole31B1904C": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "MyPipelineCFNCFNDeployCodePipelineActionRoleDefaultPolicyD67537CB": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "iam:PassRole", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "MyPipelineCFNCFNDeployRole9CC99B3F", + "Arn" + ] + } + }, + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "cloudformation:CreateStack", + "cloudformation:DescribeStack*", + "cloudformation:GetStackPolicy", + "cloudformation:GetTemplate*", + "cloudformation:SetStackPolicy", + "cloudformation:UpdateStack", + "cloudformation:ValidateTemplate" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":cloudformation:us-west-2:", + { + "Ref": "AWS::AccountId" + }, + ":stack/aws-cdk-codepipeline-cross-region-deploy-stack/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyPipelineCFNCFNDeployCodePipelineActionRoleDefaultPolicyD67537CB", + "Roles": [ + { + "Ref": "MyPipelineCFNCFNDeployCodePipelineActionRole31B1904C" + } + ] + } + }, "MyPipelineCFNCFNDeployRole9CC99B3F": { "Type": "AWS::IAM::Role", "Properties": { @@ -269,4 +457,4 @@ } } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn-wtih-action-role.expected.json b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn-with-action-role.expected.json similarity index 72% rename from packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn-wtih-action-role.expected.json rename to packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn-with-action-role.expected.json index 58d74f95354c6..fe61459a8cab7 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn-wtih-action-role.expected.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn-with-action-role.expected.json @@ -2,14 +2,14 @@ "Resources": { "MyBucketF68F3FF0": { "Type": "AWS::S3::Bucket", - "DeletionPolicy": "Delete", "Properties": { "VersioningConfiguration": { "Status": "Enabled" } - } + }, + "DeletionPolicy": "Delete" }, - "MyPipelineRoleC0D47CA4": { + "ActionRole60B0EDF7": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { @@ -18,14 +18,19 @@ "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { - "Service": { + "AWS": { "Fn::Join": [ "", [ - "codepipeline.", + "arn:", { - "Ref": "AWS::URLSuffix" - } + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" ] ] } @@ -36,19 +41,31 @@ } } }, - "MyPipelineRoleDefaultPolicy34F09EFA": { + "ActionRoleDefaultPolicyCA33BE56": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyDocument": { "Statement": [ + { + "Action": "sqs:*", + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": "iam:PassRole", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "MyPipelineCFNCFNDeployRole9CC99B3F", + "Arn" + ] + } + }, { "Action": [ "s3:GetObject*", "s3:GetBucket*", - "s3:List*", - "s3:DeleteObject*", - "s3:PutObject*", - "s3:Abort*" + "s3:List*" ], "Effect": "Allow", "Resource": [ @@ -74,11 +91,89 @@ } ] }, + { + "Action": [ + "cloudformation:CreateStack", + "cloudformation:DescribeStack*", + "cloudformation:GetStackPolicy", + "cloudformation:GetTemplate*", + "cloudformation:SetStackPolicy", + "cloudformation:UpdateStack", + "cloudformation:ValidateTemplate" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":cloudformation:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":stack/aws-cdk-codepipeline-cross-region-deploy-stack/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "ActionRoleDefaultPolicyCA33BE56", + "Roles": [ + { + "Ref": "ActionRole60B0EDF7" + } + ] + } + }, + "MyPipelineRoleC0D47CA4": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": { + "Fn::Join": [ + "", + [ + "codepipeline.", + { + "Ref": "AWS::URLSuffix" + } + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "MyPipelineRoleDefaultPolicy34F09EFA": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ { "Action": [ "s3:GetObject*", "s3:GetBucket*", - "s3:List*" + "s3:List*", + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*" ], "Effect": "Allow", "Resource": [ @@ -104,6 +199,16 @@ } ] }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "MyPipelineSourceS3CodePipelineActionRole9F003087", + "Arn" + ] + } + }, { "Action": "sts:AssumeRole", "Effect": "Allow", @@ -157,6 +262,12 @@ "Name": "Artifact_Source_S3" } ], + "RoleArn": { + "Fn::GetAtt": [ + "MyPipelineSourceS3CodePipelineActionRole9F003087", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -173,14 +284,14 @@ }, "Configuration": { "StackName": "aws-cdk-codepipeline-cross-region-deploy-stack", - "ActionMode": "CREATE_UPDATE", - "TemplatePath": "Artifact_Source_S3::template.yml", "RoleArn": { "Fn::GetAtt": [ "MyPipelineCFNCFNDeployRole9CC99B3F", "Arn" ] - } + }, + "ActionMode": "CREATE_UPDATE", + "TemplatePath": "Artifact_Source_S3::template.yml" }, "InputArtifacts": [ { @@ -213,7 +324,7 @@ "MyPipelineRoleC0D47CA4" ] }, - "ActionRole60B0EDF7": { + "MyPipelineSourceS3CodePipelineActionRole9F003087": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { @@ -245,65 +356,78 @@ } } }, - "ActionRoleDefaultPolicyCA33BE56": { + "MyPipelineSourceS3CodePipelineActionRoleDefaultPolicyF838EE0B": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyDocument": { "Statement": [ { - "Action": "sqs:*", - "Effect": "Allow", - "Resource": "*" - }, - { - "Action": "iam:PassRole", + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], "Effect": "Allow", - "Resource": { - "Fn::GetAtt": [ - "MyPipelineCFNCFNDeployRole9CC99B3F", - "Arn" - ] - } + "Resource": [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + "/*" + ] + ] + } + ] }, { "Action": [ - "cloudformation:CreateStack", - "cloudformation:DescribeStack*", - "cloudformation:GetStackPolicy", - "cloudformation:GetTemplate*", - "cloudformation:SetStackPolicy", - "cloudformation:UpdateStack", - "cloudformation:ValidateTemplate" + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*" ], "Effect": "Allow", - "Resource": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":cloudformation:", - { - "Ref": "AWS::Region" - }, - ":", - { - "Ref": "AWS::AccountId" - }, - ":stack/aws-cdk-codepipeline-cross-region-deploy-stack/*" + "Resource": [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" ] - ] - } + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + "/*" + ] + ] + } + ] } ], "Version": "2012-10-17" }, - "PolicyName": "ActionRoleDefaultPolicyCA33BE56", + "PolicyName": "MyPipelineSourceS3CodePipelineActionRoleDefaultPolicyF838EE0B", "Roles": [ { - "Ref": "ActionRole60B0EDF7" + "Ref": "MyPipelineSourceS3CodePipelineActionRole9F003087" } ] } diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn-wtih-action-role.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn-with-action-role.ts similarity index 100% rename from packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn-wtih-action-role.ts rename to packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn-with-action-role.ts diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn.expected.json b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn.expected.json index 1817ed56039c6..acc964ed1da64 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn.expected.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn.expected.json @@ -1,8 +1,7 @@ { "Resources": { - "PipelineArtifactsBucketEncryptionKey01D58D69" : { + "PipelineArtifactsBucketEncryptionKey01D58D69": { "Type": "AWS::KMS::Key", - "DeletionPolicy": "Retain", "Properties": { "KeyPolicy": { "Statement": [ @@ -60,15 +59,65 @@ } }, "Resource": "*" + }, + { + "Action": [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "PipelineSourceCodePipelineActionRoleC6F9E7F5", + "Arn" + ] + } + }, + "Resource": "*" + }, + { + "Action": [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "PipelineSourceAdditionalSourceCodePipelineActionRole0897461A", + "Arn" + ] + } + }, + "Resource": "*" + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "PipelineCFNDeployCFNCodePipelineActionRole444CF5DD", + "Arn" + ] + } + }, + "Resource": "*" } ], "Version": "2012-10-17" } - } + }, + "DeletionPolicy": "Retain" }, "PipelineArtifactsBucket22248F97": { "Type": "AWS::S3::Bucket", - "DeletionPolicy": "Retain", "Properties": { "BucketEncryption": { "ServerSideEncryptionConfiguration": [ @@ -85,7 +134,8 @@ } ] } - } + }, + "DeletionPolicy": "Retain" }, "PipelineRoleD68726F7": { "Type": "AWS::IAM::Role", @@ -169,76 +219,32 @@ } }, { - "Action": [ - "s3:GetObject*", - "s3:GetBucket*", - "s3:List*" - ], + "Action": "sts:AssumeRole", "Effect": "Allow", - "Resource": [ - { - "Fn::GetAtt": [ - "PipelineBucketB967BD35", - "Arn" - ] - }, - { - "Fn::Join": [ - "", - [ - { - "Fn::GetAtt": [ - "PipelineBucketB967BD35", - "Arn" - ] - }, - "/*" - ] - ] - } - ] + "Resource": { + "Fn::GetAtt": [ + "PipelineSourceCodePipelineActionRoleC6F9E7F5", + "Arn" + ] + } }, { - "Action": "iam:PassRole", + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "CfnChangeSetRole6F05F6FC", + "PipelineSourceAdditionalSourceCodePipelineActionRole0897461A", "Arn" ] } }, { - "Action": [ - "cloudformation:CreateChangeSet", - "cloudformation:DeleteChangeSet", - "cloudformation:DescribeChangeSet", - "cloudformation:DescribeStacks" - ], - "Condition": { - "StringEqualsIfExists": { - "cloudformation:ChangeSetName": "ChangeSetIntegTest" - } - }, + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":cloudformation:", - { - "Ref": "AWS::Region" - }, - ":", - { - "Ref": "AWS::AccountId" - }, - ":stack/IntegTest-TestActionStack/*" - ] + "Fn::GetAtt": [ + "PipelineCFNDeployCFNCodePipelineActionRole444CF5DD", + "Arn" ] } } @@ -285,6 +291,12 @@ "Name": "SourceArtifact" } ], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineSourceCodePipelineActionRoleC6F9E7F5", + "Arn" + ] + }, "RunOrder": 1 }, { @@ -307,6 +319,12 @@ "Name": "AdditionalArtifact" } ], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineSourceAdditionalSourceCodePipelineActionRole0897461A", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -323,16 +341,16 @@ }, "Configuration": { "StackName": "IntegTest-TestActionStack", - "ActionMode": "CHANGE_SET_REPLACE", - "ChangeSetName": "ChangeSetIntegTest", - "TemplatePath": "SourceArtifact::test.yaml", "RoleArn": { "Fn::GetAtt": [ "CfnChangeSetRole6F05F6FC", "Arn" ] }, - "ParameterOverrides": "{\"BucketName\":{\"Fn::GetArtifactAtt\":[\"SourceArtifact\",\"BucketName\"]},\"ObjectKey\":{\"Fn::GetArtifactAtt\":[\"SourceArtifact\",\"ObjectKey\"]},\"Url\":{\"Fn::GetArtifactAtt\":[\"AdditionalArtifact\",\"URL\"]},\"OtherParam\":{\"Fn::GetParam\":[\"SourceArtifact\",\"params.json\",\"OtherParam\"]}}" + "ParameterOverrides": "{\"BucketName\":{\"Fn::GetArtifactAtt\":[\"SourceArtifact\",\"BucketName\"]},\"ObjectKey\":{\"Fn::GetArtifactAtt\":[\"SourceArtifact\",\"ObjectKey\"]},\"Url\":{\"Fn::GetArtifactAtt\":[\"AdditionalArtifact\",\"URL\"]},\"OtherParam\":{\"Fn::GetParam\":[\"SourceArtifact\",\"params.json\",\"OtherParam\"]}}", + "ActionMode": "CHANGE_SET_REPLACE", + "ChangeSetName": "ChangeSetIntegTest", + "TemplatePath": "SourceArtifact::test.yaml" }, "InputArtifacts": [ { @@ -344,6 +362,12 @@ ], "Name": "DeployCFN", "OutputArtifacts": [], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineCFNDeployCFNCodePipelineActionRole444CF5DD", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -351,10 +375,6 @@ } ], "ArtifactStore": { - "Location": { - "Ref": "PipelineArtifactsBucket22248F97" - }, - "Type": "S3", "EncryptionKey": { "Id": { "Fn::GetAtt": [ @@ -363,7 +383,11 @@ ] }, "Type": "KMS" - } + }, + "Location": { + "Ref": "PipelineArtifactsBucket22248F97" + }, + "Type": "S3" } }, "DependsOn": [ @@ -371,14 +395,393 @@ "PipelineRoleD68726F7" ] }, + "PipelineSourceCodePipelineActionRoleC6F9E7F5": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineSourceCodePipelineActionRoleDefaultPolicy2D565925": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineBucketB967BD35", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineBucketB967BD35", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineSourceCodePipelineActionRoleDefaultPolicy2D565925", + "Roles": [ + { + "Ref": "PipelineSourceCodePipelineActionRoleC6F9E7F5" + } + ] + } + }, + "PipelineSourceAdditionalSourceCodePipelineActionRole0897461A": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineSourceAdditionalSourceCodePipelineActionRoleDefaultPolicy9B326CCB": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineBucketB967BD35", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineBucketB967BD35", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineSourceAdditionalSourceCodePipelineActionRoleDefaultPolicy9B326CCB", + "Roles": [ + { + "Ref": "PipelineSourceAdditionalSourceCodePipelineActionRole0897461A" + } + ] + } + }, + "PipelineCFNDeployCFNCodePipelineActionRole444CF5DD": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineCFNDeployCFNCodePipelineActionRoleDefaultPolicy9C068517": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "iam:PassRole", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "CfnChangeSetRole6F05F6FC", + "Arn" + ] + } + }, + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + }, + { + "Action": [ + "cloudformation:CreateChangeSet", + "cloudformation:DeleteChangeSet", + "cloudformation:DescribeChangeSet", + "cloudformation:DescribeStacks" + ], + "Condition": { + "StringEqualsIfExists": { + "cloudformation:ChangeSetName": "ChangeSetIntegTest" + } + }, + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":cloudformation:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":stack/IntegTest-TestActionStack/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineCFNDeployCFNCodePipelineActionRoleDefaultPolicy9C068517", + "Roles": [ + { + "Ref": "PipelineCFNDeployCFNCodePipelineActionRole444CF5DD" + } + ] + } + }, "PipelineBucketB967BD35": { "Type": "AWS::S3::Bucket", - "DeletionPolicy": "Delete", "Properties": { "VersioningConfiguration": { "Status": "Enabled" } - } + }, + "DeletionPolicy": "Delete" }, "CfnChangeSetRole6F05F6FC": { "Type": "AWS::IAM::Role", diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.expected.json b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.expected.json index 90f288eb9f8f9..ac65273faee7c 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.expected.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.expected.json @@ -74,12 +74,12 @@ }, "MyBucketF68F3FF0": { "Type": "AWS::S3::Bucket", - "DeletionPolicy": "Delete", "Properties": { "VersioningConfiguration": { "Status": "Enabled" } - } + }, + "DeletionPolicy": "Delete" }, "PipelineRoleD68726F7": { "Type": "AWS::IAM::Role", @@ -146,6 +146,46 @@ } ] }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineRoleD68726F7", + "Arn" + ] + } + }, + { + "Action": [ + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, { "Action": [ "codecommit:GetBranch", @@ -253,6 +293,12 @@ "Name": "Artifact_Source_Source1" } ], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineRoleD68726F7", + "Arn" + ] + }, "RunOrder": 1 }, { @@ -275,6 +321,12 @@ "Name": "Artifact_Source_Source2" } ], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineRoleD68726F7", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -312,6 +364,12 @@ "Name": "Artifact_Build_Build1_2" } ], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineRoleD68726F7", + "Arn" + ] + }, "RunOrder": 1 }, { @@ -341,6 +399,12 @@ "Name": "CustomOutput2" } ], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineRoleD68726F7", + "Arn" + ] + }, "RunOrder": 1 } ], diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.ts index 9d2d79f458d37..b2ac00792d832 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.ts @@ -20,12 +20,14 @@ const bucket = new s3.Bucket(stack, 'MyBucket', { const pipeline = new codepipeline.Pipeline(stack, 'Pipeline', { artifactBucket: bucket, }); +const pipelineRole = pipeline.role; const source1Output = new codepipeline.Artifact(); const sourceAction1 = new cpactions.CodeCommitSourceAction({ actionName: 'Source1', repository, output: source1Output, + role: pipelineRole, }); const source2Output = new codepipeline.Artifact(); const sourceAction2 = new cpactions.S3SourceAction({ @@ -33,6 +35,7 @@ const sourceAction2 = new cpactions.S3SourceAction({ bucketKey: 'some/path', bucket, output: source2Output, + role: pipelineRole, }); pipeline.addStage({ stageName: 'Source', @@ -54,6 +57,7 @@ const buildAction = new cpactions.CodeBuildAction({ new codepipeline.Artifact(), new codepipeline.Artifact(), ], + role: pipelineRole, }); const testAction = new cpactions.CodeBuildAction({ type: cpactions.CodeBuildActionType.TEST, @@ -66,6 +70,7 @@ const testAction = new cpactions.CodeBuildAction({ outputs: [ new codepipeline.Artifact('CustomOutput2'), ], + role: pipelineRole, }); pipeline.addStage({ stageName: 'Build', diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.expected.json b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.expected.json index 7472a51f700cc..92bc958303174 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.expected.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.expected.json @@ -1,106 +1,5 @@ { "Resources": { - "PipelineArtifactsBucketEncryptionKey01D58D69" : { - "Type": "AWS::KMS::Key", - "DeletionPolicy": "Retain", - "Properties": { - "KeyPolicy": { - "Statement": [ - { - "Action": [ - "kms:Create*", - "kms:Describe*", - "kms:Enable*", - "kms:List*", - "kms:Put*", - "kms:Update*", - "kms:Revoke*", - "kms:Disable*", - "kms:Get*", - "kms:Delete*", - "kms:ScheduleKeyDeletion", - "kms:CancelKeyDeletion" - ], - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::", - { - "Ref": "AWS::AccountId" - }, - ":root" - ] - ] - } - }, - "Resource": "*" - }, - { - "Action": [ - "kms:Decrypt", - "kms:DescribeKey", - "kms:Encrypt", - "kms:ReEncrypt*", - "kms:GenerateDataKey*" - ], - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::GetAtt": [ - "PipelineRoleD68726F7", - "Arn" - ] - } - }, - "Resource": "*" - }, - { - "Action": [ - "kms:Decrypt", - "kms:DescribeKey", - "kms:Encrypt", - "kms:ReEncrypt*", - "kms:GenerateDataKey*" - ], - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::GetAtt": [ - "MyBuildProjectRole6B7E2258", - "Arn" - ] - } - }, - "Resource": "*" - }, - { - "Action": [ - "kms:Decrypt", - "kms:DescribeKey" - ], - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::GetAtt": [ - "MyBuildProjectRole6B7E2258", - "Arn" - ] - } - }, - "Resource": "*" - } - ], - "Version": "2012-10-17" - } - } - }, "MyRepoF4F48043": { "Type": "AWS::CodeCommit::Repository", "Properties": { @@ -323,9 +222,126 @@ } } }, + "PipelineArtifactsBucketEncryptionKey01D58D69": { + "Type": "AWS::KMS::Key", + "Properties": { + "KeyPolicy": { + "Statement": [ + { + "Action": [ + "kms:Create*", + "kms:Describe*", + "kms:Enable*", + "kms:List*", + "kms:Put*", + "kms:Update*", + "kms:Revoke*", + "kms:Disable*", + "kms:Get*", + "kms:Delete*", + "kms:ScheduleKeyDeletion", + "kms:CancelKeyDeletion" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + }, + "Resource": "*" + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey", + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "PipelineRoleD68726F7", + "Arn" + ] + } + }, + "Resource": "*" + }, + { + "Action": [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "PipelinesourceCodePipelineActionRoleB7E0306A", + "Arn" + ] + } + }, + "Resource": "*" + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey", + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "MyBuildProjectRole6B7E2258", + "Arn" + ] + } + }, + "Resource": "*" + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "MyBuildProjectRole6B7E2258", + "Arn" + ] + } + }, + "Resource": "*" + } + ], + "Version": "2012-10-17" + } + }, + "DeletionPolicy": "Retain" + }, "PipelineArtifactsBucket22248F97": { "Type": "AWS::S3::Bucket", - "DeletionPolicy": "Retain", "Properties": { "BucketEncryption": { "ServerSideEncryptionConfiguration": [ @@ -342,7 +358,8 @@ } ] } - } + }, + "DeletionPolicy": "Retain" }, "PipelineRoleD68726F7": { "Type": "AWS::IAM::Role", @@ -409,7 +426,6 @@ } ] }, - { "Action": [ "kms:Decrypt", @@ -427,31 +443,31 @@ } }, { - "Action": [ - "codecommit:GetBranch", - "codecommit:GetCommit", - "codecommit:UploadArchive", - "codecommit:GetUploadArchiveStatus", - "codecommit:CancelUploadArchive" - ], + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "MyRepoF4F48043", + "PipelinesourceCodePipelineActionRoleB7E0306A", "Arn" ] } }, { - "Action": [ - "codebuild:BatchGetBuilds", - "codebuild:StartBuild", - "codebuild:StopBuild" - ], + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "MyBuildProject30DB9D6E", + "PipelinebuildCodePipelineActionRole11BCD4FF", + "Arn" + ] + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelinebuildtestCodePipelineActionRole467D0DFA", "Arn" ] } @@ -503,6 +519,12 @@ "Name": "SourceArtifact" } ], + "RoleArn": { + "Fn::GetAtt": [ + "PipelinesourceCodePipelineActionRoleB7E0306A", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -533,6 +555,12 @@ "Name": "Artifact_build_build" } ], + "RoleArn": { + "Fn::GetAtt": [ + "PipelinebuildCodePipelineActionRole11BCD4FF", + "Arn" + ] + }, "RunOrder": 1 }, { @@ -554,6 +582,12 @@ ], "Name": "test", "OutputArtifacts": [], + "RoleArn": { + "Fn::GetAtt": [ + "PipelinebuildtestCodePipelineActionRole467D0DFA", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -561,10 +595,6 @@ } ], "ArtifactStore": { - "Location": { - "Ref": "PipelineArtifactsBucket22248F97" - }, - "Type": "S3", "EncryptionKey": { "Id": { "Fn::GetAtt": [ @@ -573,13 +603,249 @@ ] }, "Type": "KMS" - } + }, + "Location": { + "Ref": "PipelineArtifactsBucket22248F97" + }, + "Type": "S3" } }, "DependsOn": [ "PipelineRoleDefaultPolicyC7A05455", "PipelineRoleD68726F7" ] + }, + "PipelinesourceCodePipelineActionRoleB7E0306A": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelinesourceCodePipelineActionRoleDefaultPolicy9E69DE83": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + }, + { + "Action": [ + "codecommit:GetBranch", + "codecommit:GetCommit", + "codecommit:UploadArchive", + "codecommit:GetUploadArchiveStatus", + "codecommit:CancelUploadArchive" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "MyRepoF4F48043", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelinesourceCodePipelineActionRoleDefaultPolicy9E69DE83", + "Roles": [ + { + "Ref": "PipelinesourceCodePipelineActionRoleB7E0306A" + } + ] + } + }, + "PipelinebuildCodePipelineActionRole11BCD4FF": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelinebuildCodePipelineActionRoleDefaultPolicyDC80DBC3": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "codebuild:BatchGetBuilds", + "codebuild:StartBuild", + "codebuild:StopBuild" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "MyBuildProject30DB9D6E", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelinebuildCodePipelineActionRoleDefaultPolicyDC80DBC3", + "Roles": [ + { + "Ref": "PipelinebuildCodePipelineActionRole11BCD4FF" + } + ] + } + }, + "PipelinebuildtestCodePipelineActionRole467D0DFA": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelinebuildtestCodePipelineActionRoleDefaultPolicy319EA326": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "codebuild:BatchGetBuilds", + "codebuild:StartBuild", + "codebuild:StopBuild" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "MyBuildProject30DB9D6E", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelinebuildtestCodePipelineActionRoleDefaultPolicy319EA326", + "Roles": [ + { + "Ref": "PipelinebuildtestCodePipelineActionRole467D0DFA" + } + ] + } } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-commit.expected.json b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-commit.expected.json index 3f81805f2d38f..ed584c2eec19e 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-commit.expected.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-commit.expected.json @@ -131,6 +131,23 @@ } }, "Resource": "*" + }, + { + "Action": [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "PipelinesourceCodePipelineActionRoleB7E0306A", + "Arn" + ] + } + }, + "Resource": "*" } ], "Version": "2012-10-17" @@ -241,17 +258,21 @@ } }, { - "Action": [ - "codecommit:GetBranch", - "codecommit:GetCommit", - "codecommit:UploadArchive", - "codecommit:GetUploadArchiveStatus", - "codecommit:CancelUploadArchive" - ], + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "MyRepoF4F48043", + "PipelinesourceCodePipelineActionRoleB7E0306A", + "Arn" + ] + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelinebuildmanualCodePipelineActionRoleE3306AB0", "Arn" ] } @@ -303,6 +324,12 @@ "Name": "SourceArtifact" } ], + "RoleArn": { + "Fn::GetAtt": [ + "PipelinesourceCodePipelineActionRoleB7E0306A", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -320,6 +347,12 @@ "InputArtifacts": [], "Name": "manual", "OutputArtifacts": [], + "RoleArn": { + "Fn::GetAtt": [ + "PipelinebuildmanualCodePipelineActionRoleE3306AB0", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -347,6 +380,114 @@ "PipelineRoleD68726F7" ] }, + "PipelinesourceCodePipelineActionRoleB7E0306A": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelinesourceCodePipelineActionRoleDefaultPolicy9E69DE83": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + }, + { + "Action": [ + "codecommit:GetBranch", + "codecommit:GetCommit", + "codecommit:UploadArchive", + "codecommit:GetUploadArchiveStatus", + "codecommit:CancelUploadArchive" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "MyRepoF4F48043", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelinesourceCodePipelineActionRoleDefaultPolicy9E69DE83", + "Roles": [ + { + "Ref": "PipelinesourceCodePipelineActionRoleB7E0306A" + } + ] + } + }, "PipelineEventsRole46BEEA7C": { "Type": "AWS::IAM::Role", "Properties": { @@ -416,6 +557,38 @@ } ] } + }, + "PipelinebuildmanualCodePipelineActionRoleE3306AB0": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-deploy.expected.json b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-deploy.expected.json index 2c1373e13b14d..ad0d2cc5f8f52 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-deploy.expected.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-deploy.expected.json @@ -87,12 +87,12 @@ }, "CodeDeployPipelineIntegTest9F618D61": { "Type": "AWS::S3::Bucket", - "DeletionPolicy": "Delete", "Properties": { "VersioningConfiguration": { "Status": "Enabled" } - } + }, + "DeletionPolicy": "Delete" }, "PipelineRoleD68726F7": { "Type": "AWS::IAM::Role", @@ -159,6 +159,165 @@ } ] }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineSourceS3SourceCodePipelineActionRole8DE11A40", + "Arn" + ] + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineDeployCodeDeployCodePipelineActionRoleFA7F8EEF", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineRoleDefaultPolicyC7A05455", + "Roles": [ + { + "Ref": "PipelineRoleD68726F7" + } + ] + } + }, + "PipelineC660917D": { + "Type": "AWS::CodePipeline::Pipeline", + "Properties": { + "RoleArn": { + "Fn::GetAtt": [ + "PipelineRoleD68726F7", + "Arn" + ] + }, + "Stages": [ + { + "Actions": [ + { + "ActionTypeId": { + "Category": "Source", + "Owner": "AWS", + "Provider": "S3", + "Version": "1" + }, + "Configuration": { + "S3Bucket": { + "Ref": "CodeDeployPipelineIntegTest9F618D61" + }, + "S3ObjectKey": "application.zip" + }, + "InputArtifacts": [], + "Name": "S3Source", + "OutputArtifacts": [ + { + "Name": "SourceOutput" + } + ], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineSourceS3SourceCodePipelineActionRole8DE11A40", + "Arn" + ] + }, + "RunOrder": 1 + } + ], + "Name": "Source" + }, + { + "Actions": [ + { + "ActionTypeId": { + "Category": "Deploy", + "Owner": "AWS", + "Provider": "CodeDeploy", + "Version": "1" + }, + "Configuration": { + "ApplicationName": { + "Ref": "CodeDeployApplicationE587C27C" + }, + "DeploymentGroupName": { + "Ref": "CodeDeployGroup58220FC8" + } + }, + "InputArtifacts": [ + { + "Name": "SourceOutput" + } + ], + "Name": "CodeDeploy", + "OutputArtifacts": [], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineDeployCodeDeployCodePipelineActionRoleFA7F8EEF", + "Arn" + ] + }, + "RunOrder": 1 + } + ], + "Name": "Deploy" + } + ], + "ArtifactStore": { + "Location": { + "Ref": "CodeDeployPipelineIntegTest9F618D61" + }, + "Type": "S3" + } + }, + "DependsOn": [ + "PipelineRoleDefaultPolicyC7A05455", + "PipelineRoleD68726F7" + ] + }, + "PipelineSourceS3SourceCodePipelineActionRole8DE11A40": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineSourceS3SourceCodePipelineActionRoleDefaultPolicy352A3912": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ { "Action": [ "s3:GetObject*", @@ -189,6 +348,84 @@ } ] }, + { + "Action": [ + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "CodeDeployPipelineIntegTest9F618D61", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "CodeDeployPipelineIntegTest9F618D61", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineSourceS3SourceCodePipelineActionRoleDefaultPolicy352A3912", + "Roles": [ + { + "Ref": "PipelineSourceS3SourceCodePipelineActionRole8DE11A40" + } + ] + } + }, + "PipelineDeployCodeDeployCodePipelineActionRoleFA7F8EEF": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineDeployCodeDeployCodePipelineActionRoleDefaultPolicy7B34E673": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ { "Action": [ "codedeploy:GetApplicationRevision", @@ -279,96 +516,47 @@ ] ] } + }, + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "CodeDeployPipelineIntegTest9F618D61", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "CodeDeployPipelineIntegTest9F618D61", + "Arn" + ] + }, + "/*" + ] + ] + } + ] } ], "Version": "2012-10-17" }, - "PolicyName": "PipelineRoleDefaultPolicyC7A05455", + "PolicyName": "PipelineDeployCodeDeployCodePipelineActionRoleDefaultPolicy7B34E673", "Roles": [ { - "Ref": "PipelineRoleD68726F7" + "Ref": "PipelineDeployCodeDeployCodePipelineActionRoleFA7F8EEF" } ] } - }, - "PipelineC660917D": { - "Type": "AWS::CodePipeline::Pipeline", - "Properties": { - "RoleArn": { - "Fn::GetAtt": [ - "PipelineRoleD68726F7", - "Arn" - ] - }, - "Stages": [ - { - "Actions": [ - { - "ActionTypeId": { - "Category": "Source", - "Owner": "AWS", - "Provider": "S3", - "Version": "1" - }, - "Configuration": { - "S3Bucket": { - "Ref": "CodeDeployPipelineIntegTest9F618D61" - }, - "S3ObjectKey": "application.zip" - }, - "InputArtifacts": [], - "Name": "S3Source", - "OutputArtifacts": [ - { - "Name": "SourceOutput" - } - ], - "RunOrder": 1 - } - ], - "Name": "Source" - }, - { - "Actions": [ - { - "ActionTypeId": { - "Category": "Deploy", - "Owner": "AWS", - "Provider": "CodeDeploy", - "Version": "1" - }, - "Configuration": { - "ApplicationName": { - "Ref": "CodeDeployApplicationE587C27C" - }, - "DeploymentGroupName": { - "Ref": "CodeDeployGroup58220FC8" - } - }, - "InputArtifacts": [ - { - "Name": "SourceOutput" - } - ], - "Name": "CodeDeploy", - "OutputArtifacts": [], - "RunOrder": 1 - } - ], - "Name": "Deploy" - } - ], - "ArtifactStore": { - "Location": { - "Ref": "CodeDeployPipelineIntegTest9F618D61" - }, - "Type": "S3" - } - }, - "DependsOn": [ - "PipelineRoleDefaultPolicyC7A05455", - "PipelineRoleD68726F7" - ] } } } diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecr-source.expected.json b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecr-source.expected.json index 72935b3ad5341..68f342ae88c02 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecr-source.expected.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecr-source.expected.json @@ -1,8 +1,8 @@ { "Resources": { "MyBucketF68F3FF0": { - "DeletionPolicy": "Delete", - "Type": "AWS::S3::Bucket" + "Type": "AWS::S3::Bucket", + "DeletionPolicy": "Delete" }, "MyPipelineRoleC0D47CA4": { "Type": "AWS::IAM::Role", @@ -70,11 +70,21 @@ ] }, { - "Action": "ecr:DescribeImages", + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "MyEcrRepo767466D0", + "MyPipelineSourceECRSourceCodePipelineActionRole4C6714EE", + "Arn" + ] + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "MyPipelineApproveManualApprovalCodePipelineActionRole9E338F01", "Arn" ] } @@ -121,6 +131,12 @@ "Name": "Artifact_Source_ECR_Source" } ], + "RoleArn": { + "Fn::GetAtt": [ + "MyPipelineSourceECRSourceCodePipelineActionRole4C6714EE", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -138,6 +154,12 @@ "InputArtifacts": [], "Name": "ManualApproval", "OutputArtifacts": [], + "RoleArn": { + "Fn::GetAtt": [ + "MyPipelineApproveManualApprovalCodePipelineActionRole9E338F01", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -156,6 +178,94 @@ "MyPipelineRoleC0D47CA4" ] }, + "MyPipelineSourceECRSourceCodePipelineActionRole4C6714EE": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "MyPipelineSourceECRSourceCodePipelineActionRoleDefaultPolicy7646B7FE": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "ecr:DescribeImages", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "MyEcrRepo767466D0", + "Arn" + ] + } + }, + { + "Action": [ + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyPipelineSourceECRSourceCodePipelineActionRoleDefaultPolicy7646B7FE", + "Roles": [ + { + "Ref": "MyPipelineSourceECRSourceCodePipelineActionRole4C6714EE" + } + ] + } + }, "MyPipelineEventsRoleFAB99F32": { "Type": "AWS::IAM::Role", "Properties": { @@ -226,6 +336,38 @@ ] } }, + "MyPipelineApproveManualApprovalCodePipelineActionRole9E338F01": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, "MyEcrRepo767466D0": { "Type": "AWS::ECR::Repository", "DeletionPolicy": "Retain" @@ -241,16 +383,16 @@ "AWS API Call via CloudTrail" ], "detail": { - "eventName": [ - "PutImage" - ], "requestParameters": { "repositoryName": [ { "Ref": "MyEcrRepo767466D0" } ] - } + }, + "eventName": [ + "PutImage" + ] } }, "State": "ENABLED", diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecs-deploy.expected.json b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecs-deploy.expected.json index 903e8398d86e2..43f06d00801bd 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecs-deploy.expected.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecs-deploy.expected.json @@ -311,12 +311,12 @@ }, "MyBucketF68F3FF0": { "Type": "AWS::S3::Bucket", - "DeletionPolicy": "Delete", "Properties": { "VersioningConfiguration": { "Status": "Enabled" } - } + }, + "DeletionPolicy": "Delete" }, "EcsProjectRoleE2F0E9D2": { "Type": "AWS::IAM::Role", @@ -625,73 +625,34 @@ ] }, { - "Action": [ - "s3:GetObject*", - "s3:GetBucket*", - "s3:List*" - ], - "Effect": "Allow", - "Resource": [ - { - "Fn::GetAtt": [ - "MyBucketF68F3FF0", - "Arn" - ] - }, - { - "Fn::Join": [ - "", - [ - { - "Fn::GetAtt": [ - "MyBucketF68F3FF0", - "Arn" - ] - }, - "/*" - ] - ] - } - ] - }, - { - "Action": [ - "codebuild:BatchGetBuilds", - "codebuild:StartBuild", - "codebuild:StopBuild" - ], + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "EcsProject54EFDCA6", + "MyPipelineSourceCodePipelineActionRoleAA05D76F", "Arn" ] } }, { - "Action": [ - "ecs:DescribeServices", - "ecs:DescribeTaskDefinition", - "ecs:DescribeTasks", - "ecs:ListTasks", - "ecs:RegisterTaskDefinition", - "ecs:UpdateService" - ], + "Action": "sts:AssumeRole", "Effect": "Allow", - "Resource": "*" + "Resource": { + "Fn::GetAtt": [ + "MyPipelineBuildCodeBuildCodePipelineActionRoleCAE538CA", + "Arn" + ] + } }, { - "Action": "iam:PassRole", - "Condition": { - "StringEqualsIfExists": { - "iam:PassedToService": [ - "ec2.amazonaws.com", - "ecs-tasks.amazonaws.com" - ] - } - }, + "Action": "sts:AssumeRole", "Effect": "Allow", - "Resource": "*" + "Resource": { + "Fn::GetAtt": [ + "MyPipelineDeployDeployActionCodePipelineActionRole854184EF", + "Arn" + ] + } } ], "Version": "2012-10-17" @@ -736,6 +697,12 @@ "Name": "SourceArtifact" } ], + "RoleArn": { + "Fn::GetAtt": [ + "MyPipelineSourceCodePipelineActionRoleAA05D76F", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -766,6 +733,12 @@ "Name": "Artifact_Build_CodeBuild" } ], + "RoleArn": { + "Fn::GetAtt": [ + "MyPipelineBuildCodeBuildCodePipelineActionRoleCAE538CA", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -798,6 +771,12 @@ ], "Name": "DeployAction", "OutputArtifacts": [], + "RoleArn": { + "Fn::GetAtt": [ + "MyPipelineDeployDeployActionCodePipelineActionRole854184EF", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -815,6 +794,279 @@ "MyPipelineRoleDefaultPolicy34F09EFA", "MyPipelineRoleC0D47CA4" ] + }, + "MyPipelineSourceCodePipelineActionRoleAA05D76F": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "MyPipelineSourceCodePipelineActionRoleDefaultPolicy10C831A9": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyPipelineSourceCodePipelineActionRoleDefaultPolicy10C831A9", + "Roles": [ + { + "Ref": "MyPipelineSourceCodePipelineActionRoleAA05D76F" + } + ] + } + }, + "MyPipelineBuildCodeBuildCodePipelineActionRoleCAE538CA": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "MyPipelineBuildCodeBuildCodePipelineActionRoleDefaultPolicyD9654D9B": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "codebuild:BatchGetBuilds", + "codebuild:StartBuild", + "codebuild:StopBuild" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "EcsProject54EFDCA6", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyPipelineBuildCodeBuildCodePipelineActionRoleDefaultPolicyD9654D9B", + "Roles": [ + { + "Ref": "MyPipelineBuildCodeBuildCodePipelineActionRoleCAE538CA" + } + ] + } + }, + "MyPipelineDeployDeployActionCodePipelineActionRole854184EF": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "MyPipelineDeployDeployActionCodePipelineActionRoleDefaultPolicy8B712933": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "ecs:DescribeServices", + "ecs:DescribeTaskDefinition", + "ecs:DescribeTasks", + "ecs:ListTasks", + "ecs:RegisterTaskDefinition", + "ecs:UpdateService" + ], + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": "iam:PassRole", + "Condition": { + "StringEqualsIfExists": { + "iam:PassedToService": [ + "ec2.amazonaws.com", + "ecs-tasks.amazonaws.com" + ] + } + }, + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyPipelineDeployDeployActionCodePipelineActionRoleDefaultPolicy8B712933", + "Roles": [ + { + "Ref": "MyPipelineDeployDeployActionCodePipelineActionRole854184EF" + } + ] + } } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-events.expected.json b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-events.expected.json index 51efdb5f7d3cb..c0a966cd9214b 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-events.expected.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-events.expected.json @@ -60,6 +60,23 @@ }, "Resource": "*" }, + { + "Action": [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "MyPipelineSourceCodeCommitSourceCodePipelineActionRole0B6D0F4F", + "Arn" + ] + } + }, + "Resource": "*" + }, { "Action": [ "kms:Decrypt", @@ -188,31 +205,21 @@ } }, { - "Action": [ - "codecommit:GetBranch", - "codecommit:GetCommit", - "codecommit:UploadArchive", - "codecommit:GetUploadArchiveStatus", - "codecommit:CancelUploadArchive" - ], + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "CodeCommitRepoDC6A41F9", + "MyPipelineSourceCodeCommitSourceCodePipelineActionRole0B6D0F4F", "Arn" ] } }, { - "Action": [ - "codebuild:BatchGetBuilds", - "codebuild:StartBuild", - "codebuild:StopBuild" - ], + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "BuildProject097C5DB7", + "MyPipelineBuildCodeBuildActionCodePipelineActionRole3185ADC7", "Arn" ] } @@ -264,6 +271,12 @@ "Name": "Source" } ], + "RoleArn": { + "Fn::GetAtt": [ + "MyPipelineSourceCodeCommitSourceCodePipelineActionRole0B6D0F4F", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -294,6 +307,12 @@ "Name": "Artifact_Build_CodeBuildAction" } ], + "RoleArn": { + "Fn::GetAtt": [ + "MyPipelineBuildCodeBuildActionCodePipelineActionRole3185ADC7", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -321,6 +340,114 @@ "MyPipelineRoleC0D47CA4" ] }, + "MyPipelineSourceCodeCommitSourceCodePipelineActionRole0B6D0F4F": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "MyPipelineSourceCodeCommitSourceCodePipelineActionRoleDefaultPolicyE6664925": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "MyPipelineArtifactsBucket727923DD", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyPipelineArtifactsBucket727923DD", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "MyPipelineArtifactsBucketEncryptionKey8BF0A7F3", + "Arn" + ] + } + }, + { + "Action": [ + "codecommit:GetBranch", + "codecommit:GetCommit", + "codecommit:UploadArchive", + "codecommit:GetUploadArchiveStatus", + "codecommit:CancelUploadArchive" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "CodeCommitRepoDC6A41F9", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyPipelineSourceCodeCommitSourceCodePipelineActionRoleDefaultPolicyE6664925", + "Roles": [ + { + "Ref": "MyPipelineSourceCodeCommitSourceCodePipelineActionRole0B6D0F4F" + } + ] + } + }, "MyPipelineSourceCodeCommitSourceOnActionStateChangeDCAF781A": { "Type": "AWS::Events::Rule", "Properties": { @@ -431,13 +558,72 @@ ] } }, + "MyPipelineBuildCodeBuildActionCodePipelineActionRole3185ADC7": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "MyPipelineBuildCodeBuildActionCodePipelineActionRoleDefaultPolicy96378DF6": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "codebuild:BatchGetBuilds", + "codebuild:StartBuild", + "codebuild:StopBuild" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "BuildProject097C5DB7", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyPipelineBuildCodeBuildActionCodePipelineActionRoleDefaultPolicy96378DF6", + "Roles": [ + { + "Ref": "MyPipelineBuildCodeBuildActionCodePipelineActionRole3185ADC7" + } + ] + } + }, "MyPipelineOnPipelineStateChangeA017E4B1": { "Type": "AWS::Events::Rule", "Properties": { "EventPattern": { - "detail-type": [ - "CodePipeline Pipeline Execution State Change" - ], "source": [ "aws.codepipeline" ], @@ -465,6 +651,9 @@ ] ] } + ], + "detail-type": [ + "CodePipeline Pipeline Execution State Change" ] }, "State": "ENABLED", @@ -704,4 +893,4 @@ } } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-jenkins.expected.json b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-jenkins.expected.json index 09dde45fc5791..f0c9dcab53b19 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-jenkins.expected.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-jenkins.expected.json @@ -75,34 +75,14 @@ ] }, { - "Action": [ - "s3:GetObject*", - "s3:GetBucket*", - "s3:List*" - ], + "Action": "sts:AssumeRole", "Effect": "Allow", - "Resource": [ - { - "Fn::GetAtt": [ - "MyBucketF68F3FF0", - "Arn" - ] - }, - { - "Fn::Join": [ - "", - [ - { - "Fn::GetAtt": [ - "MyBucketF68F3FF0", - "Arn" - ] - }, - "/*" - ] - ] - } - ] + "Resource": { + "Fn::GetAtt": [ + "PipelineSourceS3CodePipelineActionRole3CAFD08F", + "Arn" + ] + } } ], "Version": "2012-10-17" @@ -147,6 +127,12 @@ "Name": "Artifact_Source_S3" } ], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineSourceS3CodePipelineActionRole3CAFD08F", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -231,6 +217,114 @@ "PipelineRoleD68726F7" ] }, + "PipelineSourceS3CodePipelineActionRole3CAFD08F": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineSourceS3CodePipelineActionRoleDefaultPolicy8B9DCBCF": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineSourceS3CodePipelineActionRoleDefaultPolicy8B9DCBCF", + "Roles": [ + { + "Ref": "PipelineSourceS3CodePipelineActionRole3CAFD08F" + } + ] + } + }, "JenkinsProviderJenkinsBuildProviderResourceD9231CAC": { "Type": "AWS::CodePipeline::CustomActionType", "Properties": { @@ -244,6 +338,7 @@ "MinimumCount": 0 }, "Provider": "JenkinsProvider", + "Version": "2", "ConfigurationProperties": [ { "Key": true, @@ -256,8 +351,7 @@ "Settings": { "EntityUrlTemplate": "http://myjenkins.com:8080/job/{Config:ProjectName}", "ExecutionUrlTemplate": "http://myjenkins.com:8080/job/{Config:ProjectName}/{ExternalExecutionId}" - }, - "Version": "2" + } } }, "JenkinsProviderJenkinsTestProviderResourceF0CF8F0E": { @@ -273,6 +367,7 @@ "MinimumCount": 0 }, "Provider": "JenkinsProvider", + "Version": "2", "ConfigurationProperties": [ { "Key": true, @@ -285,9 +380,8 @@ "Settings": { "EntityUrlTemplate": "http://myjenkins.com:8080/job/{Config:ProjectName}", "ExecutionUrlTemplate": "http://myjenkins.com:8080/job/{Config:ProjectName}/{ExternalExecutionId}" - }, - "Version": "2" + } } } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-manual-approval.expected.json b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-manual-approval.expected.json index 056fd542a15ca..a4033c8ba6512 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-manual-approval.expected.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-manual-approval.expected.json @@ -70,40 +70,23 @@ ] }, { - "Action": [ - "s3:GetObject*", - "s3:GetBucket*", - "s3:List*" - ], + "Action": "sts:AssumeRole", "Effect": "Allow", - "Resource": [ - { - "Fn::GetAtt": [ - "Bucket83908E77", - "Arn" - ] - }, - { - "Fn::Join": [ - "", - [ - { - "Fn::GetAtt": [ - "Bucket83908E77", - "Arn" - ] - }, - "/*" - ] - ] - } - ] + "Resource": { + "Fn::GetAtt": [ + "PipelineSourceS3CodePipelineActionRole3CAFD08F", + "Arn" + ] + } }, { - "Action": "sns:Publish", + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": { - "Ref": "PipelineApproveManualApprovalTopicResourceF5A35B20" + "Fn::GetAtt": [ + "PipelineApproveManualApprovalCodePipelineActionRole51D669A5", + "Arn" + ] } } ], @@ -149,6 +132,12 @@ "Name": "Artifact_Source_S3" } ], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineSourceS3CodePipelineActionRole3CAFD08F", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -171,6 +160,12 @@ "InputArtifacts": [], "Name": "ManualApproval", "OutputArtifacts": [], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineApproveManualApprovalCodePipelineActionRole51D669A5", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -189,6 +184,169 @@ "PipelineRoleD68726F7" ] }, + "PipelineSourceS3CodePipelineActionRole3CAFD08F": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineSourceS3CodePipelineActionRoleDefaultPolicy8B9DCBCF": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineSourceS3CodePipelineActionRoleDefaultPolicy8B9DCBCF", + "Roles": [ + { + "Ref": "PipelineSourceS3CodePipelineActionRole3CAFD08F" + } + ] + } + }, + "PipelineApproveManualApprovalCodePipelineActionRole51D669A5": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineApproveManualApprovalCodePipelineActionRoleDefaultPolicyB6418282": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "sns:Publish", + "Effect": "Allow", + "Resource": { + "Ref": "PipelineApproveManualApprovalTopicResourceF5A35B20" + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineApproveManualApprovalCodePipelineActionRoleDefaultPolicyB6418282", + "Roles": [ + { + "Ref": "PipelineApproveManualApprovalCodePipelineActionRole51D669A5" + } + ] + } + }, "PipelineApproveManualApprovalTopicResourceF5A35B20": { "Type": "AWS::SNS::Topic" }, diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-s3-deploy.expected.json b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-s3-deploy.expected.json index ebf160e8cfca6..1ef960cdf766c 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-s3-deploy.expected.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-s3-deploy.expected.json @@ -1,8 +1,20 @@ { "Resources": { - "PipelineArtifactsBucketEncryptionKey01D58D69" : { + "PipelineBucketB967BD35": { + "Type": "AWS::S3::Bucket", + "Properties": { + "VersioningConfiguration": { + "Status": "Enabled" + } + }, + "DeletionPolicy": "Delete" + }, + "DeployBucket67E2C076": { + "Type": "AWS::S3::Bucket", + "DeletionPolicy": "Retain" + }, + "PipelineArtifactsBucketEncryptionKey01D58D69": { "Type": "AWS::KMS::Key", - "DeletionPolicy": "Retain", "Properties": { "KeyPolicy": { "Statement": [ @@ -60,28 +72,48 @@ } }, "Resource": "*" + }, + { + "Action": [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "PipelineSourceCodePipelineActionRoleC6F9E7F5", + "Arn" + ] + } + }, + "Resource": "*" + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "PipelineDeployDeployActionCodePipelineActionRole1C288A60", + "Arn" + ] + } + }, + "Resource": "*" } ], "Version": "2012-10-17" } - } - }, - "PipelineBucketB967BD35": { - "DeletionPolicy": "Delete", - "Type": "AWS::S3::Bucket", - "Properties": { - "VersioningConfiguration": { - "Status": "Enabled" - } - } - }, - "DeployBucket67E2C076": { - "Type": "AWS::S3::Bucket", + }, "DeletionPolicy": "Retain" }, "PipelineArtifactsBucket22248F97": { "Type": "AWS::S3::Bucket", - "DeletionPolicy": "Retain", "Properties": { "BucketEncryption": { "ServerSideEncryptionConfiguration": [ @@ -98,7 +130,8 @@ } ] } - } + }, + "DeletionPolicy": "Retain" }, "PipelineRoleD68726F7": { "Type": "AWS::IAM::Role", @@ -182,64 +215,24 @@ } }, { - "Action": [ - "s3:GetObject*", - "s3:GetBucket*", - "s3:List*" - ], + "Action": "sts:AssumeRole", "Effect": "Allow", - "Resource": [ - { - "Fn::GetAtt": [ - "PipelineBucketB967BD35", - "Arn" - ] - }, - { - "Fn::Join": [ - "", - [ - { - "Fn::GetAtt": [ - "PipelineBucketB967BD35", - "Arn" - ] - }, - "/*" - ] - ] - } - ] + "Resource": { + "Fn::GetAtt": [ + "PipelineSourceCodePipelineActionRoleC6F9E7F5", + "Arn" + ] + } }, { - "Action": [ - "s3:DeleteObject*", - "s3:PutObject*", - "s3:Abort*" - ], + "Action": "sts:AssumeRole", "Effect": "Allow", - "Resource": [ - { - "Fn::GetAtt": [ - "DeployBucket67E2C076", - "Arn" - ] - }, - { - "Fn::Join": [ - "", - [ - { - "Fn::GetAtt": [ - "DeployBucket67E2C076", - "Arn" - ] - }, - "/*" - ] - ] - } - ] + "Resource": { + "Fn::GetAtt": [ + "PipelineDeployDeployActionCodePipelineActionRole1C288A60", + "Arn" + ] + } } ], "Version": "2012-10-17" @@ -284,6 +277,12 @@ "Name": "SourceArtifact" } ], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineSourceCodePipelineActionRoleC6F9E7F5", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -311,6 +310,12 @@ ], "Name": "DeployAction", "OutputArtifacts": [], + "RoleArn": { + "Fn::GetAtt": [ + "PipelineDeployDeployActionCodePipelineActionRole1C288A60", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -318,10 +323,6 @@ } ], "ArtifactStore": { - "Location": { - "Ref": "PipelineArtifactsBucket22248F97" - }, - "Type": "S3", "EncryptionKey": { "Id": { "Fn::GetAtt": [ @@ -330,13 +331,260 @@ ] }, "Type": "KMS" - } + }, + "Location": { + "Ref": "PipelineArtifactsBucket22248F97" + }, + "Type": "S3" } }, "DependsOn": [ "PipelineRoleDefaultPolicyC7A05455", "PipelineRoleD68726F7" ] + }, + "PipelineSourceCodePipelineActionRoleC6F9E7F5": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineSourceCodePipelineActionRoleDefaultPolicy2D565925": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineBucketB967BD35", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineBucketB967BD35", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineSourceCodePipelineActionRoleDefaultPolicy2D565925", + "Roles": [ + { + "Ref": "PipelineSourceCodePipelineActionRoleC6F9E7F5" + } + ] + } + }, + "PipelineDeployDeployActionCodePipelineActionRole1C288A60": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "PipelineDeployDeployActionCodePipelineActionRoleDefaultPolicyE194961B": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "DeployBucket67E2C076", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "DeployBucket67E2C076", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "PipelineArtifactsBucket22248F97", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "PipelineDeployDeployActionCodePipelineActionRoleDefaultPolicyE194961B", + "Roles": [ + { + "Ref": "PipelineDeployDeployActionCodePipelineActionRole1C288A60" + } + ] + } } } -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-codepipeline/lib/action.ts b/packages/@aws-cdk/aws-codepipeline/lib/action.ts index 3b2ccd1c9d64b..82158047bb3f6 100644 --- a/packages/@aws-cdk/aws-codepipeline/lib/action.ts +++ b/packages/@aws-cdk/aws-codepipeline/lib/action.ts @@ -166,3 +166,21 @@ export interface CommonActionProps { */ readonly runOrder?: number; } + +/** + * Common properties shared by all Actions whose {@link ActionProperties.owner} field is 'AWS' + * (or unset, as 'AWS' is the default). + */ +export interface CommonAwsActionProps extends CommonActionProps { + /** + * The Role in which context's this Action will be executing in. + * The Pipeline's Role will assume this Role + * (the required permissions for that will be granted automatically) + * right before executing this Action. + * This Action will be passed into your {@link IAction.bind} + * method in the {@link ActionBindOptions.role} property. + * + * @default a new Role will be generated + */ + readonly role?: iam.IRole; +} diff --git a/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts b/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts index 9245c6bb90edd..4b2040acbdfad 100644 --- a/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts +++ b/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts @@ -308,7 +308,7 @@ export class Pipeline extends PipelineBase { this.ensureReplicationBucketExistsFor(action.actionProperties.region); // get the role for the given action - const actionRole = this.getRoleForAction(stage, action); + const actionRole = this.getRoleForAction(stage, action, actionScope); // bind the Action const actionDescriptor = action.bind(actionScope, stage, { @@ -335,14 +335,6 @@ export class Pipeline extends PipelineBase { ]; } - private requireRegion(): string { - const region = Stack.of(this).region; - if (Token.isUnresolved(region)) { - throw new Error(`You need to specify an explicit region when using CodePipeline's cross-region support`); - } - return region; - } - private ensureReplicationBucketExistsFor(region?: string) { if (!region) { return; @@ -395,13 +387,17 @@ export class Pipeline extends PipelineBase { * @param stage the stage the action belongs to * @param action the action to return/create a role for */ - private getRoleForAction(stage: Stage, action: IAction): iam.IRole | undefined { - let actionRole: iam.IRole | undefined; + private getRoleForAction(stage: Stage, action: IAction, actionScope: Construct): iam.IRole | undefined { + const pipelineStack = Stack.of(this); + let actionRole: iam.IRole | undefined; if (action.actionProperties.role) { + if (!this.isAwsOwned(action)) { + throw new Error("Specifying a Role is not supported for actions with an owner different than 'AWS' - " + + `got '${action.actionProperties.owner}' (Action: '${action.actionProperties.actionName}' in Stage: '${stage.stageName}')`); + } actionRole = action.actionProperties.role; } else if (action.actionProperties.resource) { - const pipelineStack = Stack.of(this); const resourceStack = Stack.of(action.actionProperties.resource); // check if resource is from a different account if (pipelineStack.environment !== resourceStack.environment) { @@ -425,6 +421,13 @@ export class Pipeline extends PipelineBase { } } + if (!actionRole && this.isAwsOwned(action)) { + // generate a Role for this specific Action + actionRole = new iam.Role(actionScope, 'CodePipelineActionRole', { + assumedBy: new iam.AccountPrincipal(pipelineStack.account), + }); + } + // the pipeline role needs assumeRole permissions to the action role if (actionRole) { this.role.addToPolicy(new iam.PolicyStatement({ @@ -436,6 +439,11 @@ export class Pipeline extends PipelineBase { return actionRole; } + private isAwsOwned(action: IAction) { + const owner = action.actionProperties.owner; + return !owner || owner === 'AWS'; + } + private getArtifactBucketFromProps(props: PipelineProps): s3.IBucket | undefined { if (props.artifactBucket) { return props.artifactBucket; @@ -592,6 +600,14 @@ export class Pipeline extends PipelineBase { private renderStages(): CfnPipeline.StageDeclarationProperty[] { return this.stages.map(stage => stage.render()); } + + private requireRegion(): string { + const region = Stack.of(this).region; + if (Token.isUnresolved(region)) { + throw new Error(`You need to specify an explicit region when using CodePipeline's cross-region support`); + } + return region; + } } /** diff --git a/packages/@aws-cdk/aws-codepipeline/package.json b/packages/@aws-cdk/aws-codepipeline/package.json index 9efcd5a4cb538..71aba15bc6580 100644 --- a/packages/@aws-cdk/aws-codepipeline/package.json +++ b/packages/@aws-cdk/aws-codepipeline/package.json @@ -101,9 +101,10 @@ "export:@aws-cdk/aws-codepipeline.IPipeline", "import-props-interface:@aws-cdk/aws-codepipeline.PipelineImportProps", "no-unused-type:@aws-cdk/aws-codepipeline.CommonActionProps", + "no-unused-type:@aws-cdk/aws-codepipeline.CommonAwsActionProps", "resource-attribute:@aws-cdk/aws-codepipeline.IPipeline.pipelineVersion", "from-method:@aws-cdk/aws-codepipeline.Pipeline" ] }, "stability": "experimental" -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-codepipeline/test/fake-build-action.ts b/packages/@aws-cdk/aws-codepipeline/test/fake-build-action.ts index fef3d112b3f9d..b22fa90cc70fa 100644 --- a/packages/@aws-cdk/aws-codepipeline/test/fake-build-action.ts +++ b/packages/@aws-cdk/aws-codepipeline/test/fake-build-action.ts @@ -1,4 +1,5 @@ import events = require('@aws-cdk/aws-events'); +import iam = require('@aws-cdk/aws-iam'); import { Construct } from '@aws-cdk/core'; import codepipeline = require('../lib'); @@ -8,6 +9,10 @@ export interface FakeBuildActionProps extends codepipeline.CommonActionProps { output?: codepipeline.Artifact; extraInputs?: codepipeline.Artifact[]; + + owner?: string; + + role?: iam.IRole; } export class FakeBuildAction implements codepipeline.IAction { diff --git a/packages/@aws-cdk/aws-codepipeline/test/test.action.ts b/packages/@aws-cdk/aws-codepipeline/test/test.action.ts index 253a4b66e9cf8..654e57a6e717a 100644 --- a/packages/@aws-cdk/aws-codepipeline/test/test.action.ts +++ b/packages/@aws-cdk/aws-codepipeline/test/test.action.ts @@ -1,4 +1,5 @@ import { expect, haveResourceLike } from '@aws-cdk/assert'; +import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/core'); import { Test } from 'nodeunit'; import codepipeline = require('../lib'); @@ -322,6 +323,43 @@ export = { test.done(); }, }, + + 'an Action with a non-AWS owner cannot have a Role passed for it'(test: Test) { + const stack = new cdk.Stack(); + + const sourceOutput = new codepipeline.Artifact(); + const pipeline = new codepipeline.Pipeline(stack, 'Pipeline', { + stages: [ + { + stageName: 'Source', + actions: [ + new FakeSourceAction({ + actionName: 'source', + output: sourceOutput, + }), + ], + }, + ], + }); + const buildStage = pipeline.addStage({ stageName: 'Build' }); + + // constructing it is fine + const buildAction = new FakeBuildAction({ + actionName: 'build', + input: sourceOutput, + owner: 'ThirdParty', + role: new iam.Role(stack, 'Role', { + assumedBy: new iam.AnyPrincipal(), + }), + }); + + // an attempt to add it to the Pipeline is where things blow up + test.throws(() => { + buildStage.addAction(buildAction); + }, /Role is not supported for actions with an owner different than 'AWS' - got 'ThirdParty' \(Action: 'build' in Stage: 'Build'\)/); + + test.done(); + }, }; function boundsValidationResult(numberOfArtifacts: number, min: number, max: number): string[] { diff --git a/packages/@aws-cdk/aws-events-targets/test/codepipeline/integ.pipeline-event-target.expected.json b/packages/@aws-cdk/aws-events-targets/test/codepipeline/integ.pipeline-event-target.expected.json index e99a13854f285..b993508c46936 100644 --- a/packages/@aws-cdk/aws-events-targets/test/codepipeline/integ.pipeline-event-target.expected.json +++ b/packages/@aws-cdk/aws-events-targets/test/codepipeline/integ.pipeline-event-target.expected.json @@ -174,6 +174,26 @@ "Arn" ] } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "pipelinePipeline22F2A91DSourceCodeCommitCodePipelineActionRoleE54633E5", + "Arn" + ] + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "pipelinePipeline22F2A91DBuildHelloCodePipelineActionRoleA9729116", + "Arn" + ] + } } ], "Version": "2012-10-17" @@ -221,6 +241,12 @@ "Name": "Src" } ], + "RoleArn": { + "Fn::GetAtt": [ + "pipelinePipeline22F2A91DSourceCodeCommitCodePipelineActionRoleE54633E5", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -238,6 +264,12 @@ "InputArtifacts": [], "Name": "Hello", "OutputArtifacts": [], + "RoleArn": { + "Fn::GetAtt": [ + "pipelinePipeline22F2A91DBuildHelloCodePipelineActionRoleA9729116", + "Arn" + ] + }, "RunOrder": 1 } ], @@ -265,6 +297,70 @@ "pipelinePipeline22F2A91DRole58B7B05E" ] }, + "pipelinePipeline22F2A91DSourceCodeCommitCodePipelineActionRoleE54633E5": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "pipelinePipeline22F2A91DBuildHelloCodePipelineActionRoleA9729116": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, "pipelinePipeline22F2A91DEventsRole048D7F59": { "Type": "AWS::IAM::Role", "Properties": { diff --git a/packages/decdk/test/__snapshots__/synth.test.js.snap b/packages/decdk/test/__snapshots__/synth.test.js.snap index fefb681ed9aee..da4eb41f8f3e5 100644 --- a/packages/decdk/test/__snapshots__/synth.test.js.snap +++ b/packages/decdk/test/__snapshots__/synth.test.js.snap @@ -2024,6 +2024,23 @@ Object { }, "Resource": "*", }, + Object { + "Action": Array [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::GetAtt": Array [ + "PipelineSourceCodePipelineActionRoleC6F9E7F5", + "Arn", + ], + }, + }, + "Resource": "*", + }, Object { "Action": Array [ "kms:Decrypt", @@ -2043,12 +2060,90 @@ Object { }, "Resource": "*", }, + Object { + "Action": Array [ + "kms:Decrypt", + "kms:DescribeKey", + ], + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::GetAtt": Array [ + "PipelineDeployCodePipelineActionRole8B83082E", + "Arn", + ], + }, + }, + "Resource": "*", + }, ], "Version": "2012-10-17", }, }, "Type": "AWS::KMS::Key", }, + "PipelineBuildCodePipelineActionRoleD77A08E6": Object { + "Properties": Object { + "AssumeRolePolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::IAM::Role", + }, + "PipelineBuildCodePipelineActionRoleDefaultPolicyC9CB73F8": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "codebuild:BatchGetBuilds", + "codebuild:StartBuild", + "codebuild:StopBuild", + ], + "Effect": "Allow", + "Resource": Object { + "Fn::GetAtt": Array [ + "BuildProject097C5DB7", + "Arn", + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "PipelineBuildCodePipelineActionRoleDefaultPolicyC9CB73F8", + "Roles": Array [ + Object { + "Ref": "PipelineBuildCodePipelineActionRoleD77A08E6", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, "PipelineC660917D": Object { "DependsOn": Array [ "PipelineRoleDefaultPolicyC7A05455", @@ -2103,6 +2198,12 @@ Object { "Name": "Source", }, ], + "RoleArn": Object { + "Fn::GetAtt": Array [ + "PipelineSourceCodePipelineActionRoleC6F9E7F5", + "Arn", + ], + }, "RunOrder": 1, }, ], @@ -2133,6 +2234,12 @@ Object { "Name": "Build", }, ], + "RoleArn": Object { + "Fn::GetAtt": Array [ + "PipelineBuildCodePipelineActionRoleD77A08E6", + "Arn", + ], + }, "RunOrder": 1, }, ], @@ -2166,6 +2273,12 @@ Object { ], "Name": "Deploy", "OutputArtifacts": Array [], + "RoleArn": Object { + "Fn::GetAtt": Array [ + "PipelineDeployCodePipelineActionRole8B83082E", + "Arn", + ], + }, "RunOrder": 1, }, ], @@ -2175,6 +2288,139 @@ Object { }, "Type": "AWS::CodePipeline::Pipeline", }, + "PipelineDeployCodePipelineActionRole8B83082E": Object { + "Properties": Object { + "AssumeRolePolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::IAM::Role", + }, + "PipelineDeployCodePipelineActionRoleDefaultPolicyEE6D615B": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "iam:PassRole", + "Effect": "Allow", + "Resource": Object { + "Fn::GetAtt": Array [ + "PipelineDeployRole97597E3E", + "Arn", + ], + }, + }, + Object { + "Action": Array [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*", + ], + "Effect": "Allow", + "Resource": Array [ + Object { + "Fn::GetAtt": Array [ + "PipelineArtifactsBucket22248F97", + "Arn", + ], + }, + Object { + "Fn::Join": Array [ + "", + Array [ + Object { + "Fn::GetAtt": Array [ + "PipelineArtifactsBucket22248F97", + "Arn", + ], + }, + "/*", + ], + ], + }, + ], + }, + Object { + "Action": Array [ + "kms:Decrypt", + "kms:DescribeKey", + ], + "Effect": "Allow", + "Resource": Object { + "Fn::GetAtt": Array [ + "PipelineArtifactsBucketEncryptionKey01D58D69", + "Arn", + ], + }, + }, + Object { + "Action": Array [ + "cloudformation:CreateStack", + "cloudformation:DescribeStack*", + "cloudformation:GetStackPolicy", + "cloudformation:GetTemplate*", + "cloudformation:SetStackPolicy", + "cloudformation:UpdateStack", + "cloudformation:ValidateTemplate", + ], + "Effect": "Allow", + "Resource": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":cloudformation:", + Object { + "Ref": "AWS::Region", + }, + ":", + Object { + "Ref": "AWS::AccountId", + }, + ":stack/MyStack/*", + ], + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "PipelineDeployCodePipelineActionRoleDefaultPolicyEE6D615B", + "Roles": Array [ + Object { + "Ref": "PipelineDeployCodePipelineActionRole8B83082E", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, "PipelineDeployRole97597E3E": Object { "Properties": Object { "AssumeRolePolicyDocument": Object { @@ -2374,84 +2620,150 @@ Object { }, }, Object { - "Action": Array [ - "codecommit:GetBranch", - "codecommit:GetCommit", - "codecommit:UploadArchive", - "codecommit:GetUploadArchiveStatus", - "codecommit:CancelUploadArchive", - ], + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": Object { "Fn::GetAtt": Array [ - "Repo02AC86CF", + "PipelineSourceCodePipelineActionRoleC6F9E7F5", "Arn", ], }, }, Object { - "Action": Array [ - "codebuild:BatchGetBuilds", - "codebuild:StartBuild", - "codebuild:StopBuild", - ], + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": Object { "Fn::GetAtt": Array [ - "BuildProject097C5DB7", + "PipelineBuildCodePipelineActionRoleD77A08E6", "Arn", ], }, }, Object { - "Action": "iam:PassRole", + "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": Object { "Fn::GetAtt": Array [ - "PipelineDeployRole97597E3E", + "PipelineDeployCodePipelineActionRole8B83082E", + "Arn", + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "PipelineRoleDefaultPolicyC7A05455", + "Roles": Array [ + Object { + "Ref": "PipelineRoleD68726F7", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, + "PipelineSourceCodePipelineActionRoleC6F9E7F5": Object { + "Properties": Object { + "AssumeRolePolicyDocument": Object { + "Statement": Array [ + Object { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": Object { + "AWS": Object { + "Fn::Join": Array [ + "", + Array [ + "arn:", + Object { + "Ref": "AWS::Partition", + }, + ":iam::", + Object { + "Ref": "AWS::AccountId", + }, + ":root", + ], + ], + }, + }, + }, + ], + "Version": "2012-10-17", + }, + }, + "Type": "AWS::IAM::Role", + }, + "PipelineSourceCodePipelineActionRoleDefaultPolicy2D565925": Object { + "Properties": Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*", + ], + "Effect": "Allow", + "Resource": Array [ + Object { + "Fn::GetAtt": Array [ + "PipelineArtifactsBucket22248F97", + "Arn", + ], + }, + Object { + "Fn::Join": Array [ + "", + Array [ + Object { + "Fn::GetAtt": Array [ + "PipelineArtifactsBucket22248F97", + "Arn", + ], + }, + "/*", + ], + ], + }, + ], + }, + Object { + "Action": Array [ + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*", + ], + "Effect": "Allow", + "Resource": Object { + "Fn::GetAtt": Array [ + "PipelineArtifactsBucketEncryptionKey01D58D69", "Arn", ], }, }, Object { "Action": Array [ - "cloudformation:CreateStack", - "cloudformation:DescribeStack*", - "cloudformation:GetStackPolicy", - "cloudformation:GetTemplate*", - "cloudformation:SetStackPolicy", - "cloudformation:UpdateStack", - "cloudformation:ValidateTemplate", + "codecommit:GetBranch", + "codecommit:GetCommit", + "codecommit:UploadArchive", + "codecommit:GetUploadArchiveStatus", + "codecommit:CancelUploadArchive", ], "Effect": "Allow", "Resource": Object { - "Fn::Join": Array [ - "", - Array [ - "arn:", - Object { - "Ref": "AWS::Partition", - }, - ":cloudformation:", - Object { - "Ref": "AWS::Region", - }, - ":", - Object { - "Ref": "AWS::AccountId", - }, - ":stack/MyStack/*", - ], + "Fn::GetAtt": Array [ + "Repo02AC86CF", + "Arn", ], }, }, ], "Version": "2012-10-17", }, - "PolicyName": "PipelineRoleDefaultPolicyC7A05455", + "PolicyName": "PipelineSourceCodePipelineActionRoleDefaultPolicy2D565925", "Roles": Array [ Object { - "Ref": "PipelineRoleD68726F7", + "Ref": "PipelineSourceCodePipelineActionRoleC6F9E7F5", }, ], },