Skip to content

Commit 98afdeb

Browse files
authoredJun 21, 2019
refactor(codepipeline): change the API of cross-region replication Buckets. (#2977)
Changed the name and type of the Pipeline.crossRegionScaffold property. Users are now supposed to pass instances of IBucket instead of just Bucket names. BREAKING CHANGE: the Pipeline construction property crossRegionReplicationBuckets now takes values of type IBucket instead of string. * The property Pipeline.crossRegionScaffoldStacks has been renamed to crossRegionSupport, and its type changed from CrossRegionScaffoldStack to CrossRegionSupport.
1 parent 13025c4 commit 98afdeb

File tree

4 files changed

+175
-70
lines changed

4 files changed

+175
-70
lines changed
 

‎packages/@aws-cdk/aws-codepipeline-actions/test/test.pipeline.ts

+92-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { expect, haveResource, haveResourceLike, not, SynthUtils } from '@aws-cdk/assert';
1+
import { countResources, expect, haveResource, haveResourceLike, not, SynthUtils } from '@aws-cdk/assert';
22
import codebuild = require('@aws-cdk/aws-codebuild');
33
import codecommit = require('@aws-cdk/aws-codecommit');
44
import codepipeline = require('@aws-cdk/aws-codepipeline');
@@ -567,19 +567,19 @@ export = {
567567
account: pipelineAccount,
568568
},
569569
});
570-
const bucket = new s3.Bucket(stack, 'MyBucket');
571570
const pipeline = new codepipeline.Pipeline(stack, 'MyPipeline', {
572571
crossRegionReplicationBuckets: {
573-
'us-west-1': 'sfo-replication-bucket',
572+
'us-west-1': s3.Bucket.fromBucketName(stack, 'ImportedBucket', 'sfo-replication-bucket'),
574573
},
575574
});
576575

576+
const sourceBucket = new s3.Bucket(stack, 'MyBucket');
577577
const sourceOutput = new codepipeline.Artifact('SourceOutput');
578578
const sourceAction = new cpactions.S3SourceAction({
579579
actionName: 'BucketSource',
580580
bucketKey: '/some/key',
581581
output: sourceOutput,
582-
bucket,
582+
bucket: sourceBucket,
583583
});
584584
pipeline.addStage({
585585
stageName: 'Stage1',
@@ -619,19 +619,25 @@ export = {
619619
"Region": "us-east-1",
620620
"ArtifactStore": {
621621
"Type": "S3",
622+
"Location": "cdk-cross-region-codepipeline-replication-bucket-685c6feea5fb",
622623
},
623624
},
624625
{
625626
"Region": "us-west-1",
626627
"ArtifactStore": {
627-
"Location": "sfo-replication-bucket",
628628
"Type": "S3",
629+
"Location": "sfo-replication-bucket",
629630
},
630631
},
631632
{
632633
"Region": "us-west-2",
633634
"ArtifactStore": {
634635
"Type": "S3",
636+
"EncryptionKey": {
637+
"Type": "KMS",
638+
"Id": {
639+
},
640+
},
635641
},
636642
},
637643
],
@@ -656,18 +662,90 @@ export = {
656662
},
657663
],
658664
},
659-
]
665+
],
660666
}));
661667

662-
test.equal(pipeline.crossRegionScaffolding[pipelineRegion], undefined);
663-
test.equal(pipeline.crossRegionScaffolding['us-west-1'], undefined);
668+
test.equal(pipeline.crossRegionSupport[pipelineRegion], undefined);
669+
test.equal(pipeline.crossRegionSupport['us-west-1'], undefined);
670+
671+
const usEast1Support = pipeline.crossRegionSupport['us-east-1'];
672+
test.notEqual(usEast1Support, undefined);
673+
test.equal(usEast1Support.stack.region, 'us-east-1');
674+
test.equal(usEast1Support.stack.account, pipelineAccount);
675+
test.ok(usEast1Support.stack.node.id.indexOf('us-east-1') !== -1,
676+
`expected '${usEast1Support.stack.node.id}' to contain 'us-east-1'`);
677+
678+
test.done();
679+
},
680+
681+
'allows specifying only one of artifactBucket and crossRegionReplicationBuckets'(test: Test) {
682+
const stack = new Stack();
683+
684+
test.throws(() => {
685+
new codepipeline.Pipeline(stack, 'Pipeline', {
686+
artifactBucket: new s3.Bucket(stack, 'Bucket'),
687+
crossRegionReplicationBuckets: {
688+
// even an empty map should trigger this validation...
689+
},
690+
});
691+
}, /Only one of artifactBucket and crossRegionReplicationBuckets can be specified!/);
692+
test.done();
693+
},
694+
695+
'does not create a new artifact Bucket if one was provided in the cross-region Buckets for the Pipeline region'(test: Test) {
696+
const pipelineRegion = 'us-west-2';
697+
698+
const stack = new Stack(undefined, undefined, {
699+
env: {
700+
region: pipelineRegion,
701+
},
702+
});
703+
const sourceOutput = new codepipeline.Artifact();
704+
new codepipeline.Pipeline(stack, 'Pipeline', {
705+
crossRegionReplicationBuckets: {
706+
[pipelineRegion]: new s3.Bucket(stack, 'Bucket', {
707+
bucketName: PhysicalName.of('my-pipeline-bucket'),
708+
})
709+
},
710+
stages: [
711+
{
712+
stageName: 'Source',
713+
actions: [
714+
new cpactions.CodeCommitSourceAction({
715+
actionName: 'Source',
716+
output: sourceOutput,
717+
repository: new codecommit.Repository(stack, 'Repo', { repositoryName: 'Repo' }),
718+
}),
719+
],
720+
},
721+
{
722+
stageName: 'Build',
723+
actions: [
724+
new cpactions.CodeBuildAction({
725+
actionName: 'Build',
726+
input: sourceOutput,
727+
project: new codebuild.PipelineProject(stack, 'Project'),
728+
}),
729+
],
730+
},
731+
],
732+
});
733+
734+
expect(stack).to(countResources('AWS::S3::Bucket', 1));
664735

665-
const usEast1ScaffoldStack = pipeline.crossRegionScaffolding['us-east-1'];
666-
test.notEqual(usEast1ScaffoldStack, undefined);
667-
test.equal(usEast1ScaffoldStack.region, 'us-east-1');
668-
test.equal(usEast1ScaffoldStack.account, pipelineAccount);
669-
test.ok(usEast1ScaffoldStack.node.id.indexOf('us-east-1') !== -1,
670-
`expected '${usEast1ScaffoldStack.node.id}' to contain 'us-east-1'`);
736+
expect(stack).to(haveResourceLike('AWS::CodePipeline::Pipeline', {
737+
"ArtifactStores": [
738+
{
739+
"Region": pipelineRegion,
740+
"ArtifactStore": {
741+
"Type": "S3",
742+
"Location": {
743+
"Ref": "Bucket83908E77",
744+
},
745+
},
746+
},
747+
],
748+
}));
671749

672750
test.done();
673751
},

‎packages/@aws-cdk/aws-codepipeline/README.md

+10-10
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@ It works like this:
100100
const pipeline = new codepipeline.Pipeline(this, 'MyFirstPipeline', {
101101
// ...
102102
crossRegionReplicationBuckets: {
103-
'us-west-1': 'my-us-west-1-replication-bucket',
103+
// note that a physical name of the replication Bucket must be known at synthesis time
104+
'us-west-1': s3.Bucket.fromBucketName(this, 'UsWest1ReplicationBucket',
105+
'my-us-west-1-replication-bucket'),
104106
},
105107
});
106108

@@ -115,22 +117,20 @@ new codepipeline_actions.CloudFormationCreateUpdateStackAction({
115117
This way, the `CFN_US_West_1` Action will operate in the `us-west-1` region,
116118
regardless of which region your Pipeline is in.
117119

118-
If you don't provide a bucket name for a region (other than the Pipeline's region)
119-
that you're using for an Action with the `crossRegionReplicationBuckets` property,
120-
there will be a new Stack, named `aws-cdk-codepipeline-cross-region-scaffolding-<region>`,
120+
If you don't provide a bucket for a region (other than the Pipeline's region)
121+
that you're using for an Action,
122+
there will be a new Stack, called `<nameOfYourPipelineStack>-support-<region>`,
121123
defined for you, containing a replication Bucket.
122-
Note that you have to make sure to `cdk deploy` all of these automatically created Stacks
123-
before you can deploy your main Stack (the one containing your Pipeline).
124-
Use the `cdk ls` command to see all of the Stacks comprising your CDK application.
124+
This new Stack will depend on your Pipeline Stack,
125+
so deploying the Pipeline Stack will deploy the support Stack(s) first.
125126
Example:
126127

127128
```bash
128129
$ cdk ls
129130
MyMainStack
130-
aws-cdk-codepipeline-cross-region-scaffolding-us-west-1
131-
$ cdk deploy aws-cdk-codepipeline-cross-region-scaffolding-us-west-1
132-
# output of cdk deploy here...
131+
MyMainStack-support-us-west-1
133132
$ cdk deploy MyMainStack
133+
# output of cdk deploy here...
134134
```
135135

136136
See [the AWS docs here](https://docs.aws.amazon.com/codepipeline/latest/userguide/actions-create-cross-region.html)

‎packages/@aws-cdk/aws-codepipeline/lib/cross-region-scaffold-stack.ts renamed to ‎packages/@aws-cdk/aws-codepipeline/lib/cross-region-support-stack.ts

+16-10
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
import s3 = require('@aws-cdk/aws-s3');
22
import cdk = require('@aws-cdk/cdk');
33
import crypto = require('crypto');
4-
import { CrossRegionScaffolding } from './pipeline';
54

65
/**
7-
* Construction properties for {@link CrossRegionScaffoldStack}.
6+
* Construction properties for {@link CrossRegionSupportStack}.
7+
* This interface is private to the aws-codepipeline package.
88
*/
9-
export interface CrossRegionScaffoldStackProps {
9+
export interface CrossRegionSupportStackProps {
10+
/**
11+
* The name of the Stack the Pipeline itself belongs to.
12+
* Used to generate a more friendly name for the support Stack.
13+
*/
14+
readonly pipelineStackName: string;
15+
1016
/**
1117
* The AWS region this Stack resides in.
1218
*/
@@ -22,14 +28,15 @@ export interface CrossRegionScaffoldStackProps {
2228

2329
/**
2430
* A Stack containing resources required for the cross-region CodePipeline functionality to work.
31+
* This class is private to the aws-codepipeline package.
2532
*/
26-
export class CrossRegionScaffoldStack extends CrossRegionScaffolding {
33+
export class CrossRegionSupportStack extends cdk.Stack {
2734
/**
2835
* The name of the S3 Bucket used for replicating the Pipeline's artifacts into the region.
2936
*/
30-
public readonly replicationBucketName: string;
37+
public readonly replicationBucket: s3.IBucket;
3138

32-
constructor(scope: cdk.Construct, id: string, props: CrossRegionScaffoldStackProps) {
39+
constructor(scope: cdk.Construct, id: string, props: CrossRegionSupportStackProps) {
3340
super(scope, id, {
3441
stackName: generateStackName(props),
3542
env: {
@@ -41,15 +48,14 @@ export class CrossRegionScaffoldStack extends CrossRegionScaffolding {
4148
const replicationBucketName = generateUniqueName('cdk-cross-region-codepipeline-replication-bucket-',
4249
props.region, props.account, false, 12);
4350

44-
new s3.Bucket(this, 'CrossRegionCodePipelineReplicationBucket', {
51+
this.replicationBucket = new s3.Bucket(this, 'CrossRegionCodePipelineReplicationBucket', {
4552
bucketName: cdk.PhysicalName.of(replicationBucketName),
4653
});
47-
this.replicationBucketName = replicationBucketName;
4854
}
4955
}
5056

51-
function generateStackName(props: CrossRegionScaffoldStackProps): string {
52-
return `aws-cdk-codepipeline-cross-region-scaffolding-${props.region}`;
57+
function generateStackName(props: CrossRegionSupportStackProps): string {
58+
return `${props.pipelineStackName}-support-${props.region}`;
5359
}
5460

5561
function generateUniqueName(baseName: string, region: string, account: string,

0 commit comments

Comments
 (0)