Skip to content

Commit

Permalink
feat(codepipeline): use a special bootstrapless synthesizer for cross…
Browse files Browse the repository at this point in the history
…-region support Stacks

Fixes aws#8082
  • Loading branch information
skinny85 committed May 20, 2020
1 parent 442b5c4 commit 4eb2637
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ export interface CrossRegionSupportStackProps {
* @example '012345678901'
*/
readonly account: string;

readonly synthesizer: cdk.IStackSynthesizer | undefined;
}

/**
Expand All @@ -90,6 +92,7 @@ export class CrossRegionSupportStack extends cdk.Stack {
region: props.region,
account: props.account,
},
synthesizer: props.synthesizer,
});

const crossRegionSupportConstruct = new CrossRegionSupportConstruct(this, 'Default');
Expand Down
17 changes: 16 additions & 1 deletion packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as events from '@aws-cdk/aws-events';
import * as iam from '@aws-cdk/aws-iam';
import * as kms from '@aws-cdk/aws-kms';
import * as s3 from '@aws-cdk/aws-s3';
import { App, Construct, Lazy, PhysicalName, RemovalPolicy, Resource, Stack, Token } from '@aws-cdk/core';
import { App, Construct, DefaultStackSynthesizer, IStackSynthesizer, Lazy, PhysicalName, RemovalPolicy, Resource, Stack, Token } from '@aws-cdk/core';
import { ActionCategory, IAction, IPipeline, IStage } from './action';
import { CfnPipeline } from './codepipeline.generated';
import { CrossRegionSupportConstruct, CrossRegionSupportStack } from './cross-region-support-stack';
Expand Down Expand Up @@ -483,6 +483,7 @@ export class Pipeline extends PipelineBase {
pipelineStackName: pipelineStack.stackName,
region: actionRegion,
account: pipelineAccount,
synthesizer: this.getCrossRegionSupportSynthesizer(),
});
}

Expand All @@ -492,6 +493,20 @@ export class Pipeline extends PipelineBase {
};
}

private getCrossRegionSupportSynthesizer(): IStackSynthesizer | undefined {
if (this.stack.synthesizer instanceof DefaultStackSynthesizer) {
// if we have the new synthesizer,
// we need a bootstrapless copy of it,
// because we don't want to require bootstrapping the environment
// of the pipeline account in this replication region
return this.stack.synthesizer.bootstraplessCopy();
} else {
// any other synthesizer: just return undefined
// (ie., use the default based on the context settings)
return undefined;
}
}

private generateNameForDefaultBucketKeyAlias(): string {
const prefix = 'alias/codepipeline-';
const maxAliasLength = 256;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,12 @@ export class DefaultStackSynthesizer implements IStackSynthesizer {
*/
public static readonly DEFAULT_FILE_ASSETS_BUCKET_NAME = 'cdk-${Qualifier}-assets-${AWS::AccountId}-${AWS::Region}';

private stack?: Stack;
private bucketName?: string;
private repositoryName?: string;
private deployRoleArn?: string;
private cloudFormationExecutionRoleArn?: string;
private assetPublishingRoleArn?: string;
protected stack?: Stack;
protected bucketName?: string;
protected repositoryName?: string;
protected deployRoleArn?: string;
protected cloudFormationExecutionRoleArn?: string;
protected assetPublishingRoleArn?: string;

private readonly files: NonNullable<asset_schema.ManifestFile['files']> = {};
private readonly dockerImages: NonNullable<asset_schema.ManifestFile['dockerImages']> = {};
Expand Down Expand Up @@ -266,6 +266,23 @@ export class DefaultStackSynthesizer implements IStackSynthesizer {
}, [artifactId]);
}

/**
* Create a copy of this synthesizer,
* with all of the fields the same,
* but not bound to any stack yet.
*
* @experimental
*/
public bootstraplessCopy(): IStackSynthesizer {
return new BootstraplessSynthesizer({
fileAssetsBucketName: this.bucketName,
imageAssetsRepositoryName: this.repositoryName,
assetPublishingRoleArn: this.assetPublishingRoleArn,
deployRoleArn: this.deployRoleArn,
cloudFormationExecutionRole: this.cloudFormationExecutionRoleArn,
});
}

/**
* Add the stack's template as one of the manifest assets
*
Expand Down Expand Up @@ -337,6 +354,28 @@ export class DefaultStackSynthesizer implements IStackSynthesizer {
}
}

class BootstraplessSynthesizer extends DefaultStackSynthesizer {
public addFileAsset(_asset: FileAssetSource): FileAssetLocation {
throw new Error('Cannot add assets to a Stack that uses the BootstraplessSynthesizer');
}

public addDockerImageAsset(_asset: DockerImageAssetSource): DockerImageAssetLocation {
throw new Error('Cannot add assets to a Stack that uses the BootstraplessSynthesizer');
}

public synthesizeStackArtifacts(session: ISynthesisSession): void {
assertBound(this.stack);

// do _not_ treat the template as an asset,
// because this synthesizer doesn't have a bootstrap bucket to put it in
addStackArtifactToAssembly(session, this.stack, {
assumeRoleArn: this.deployRoleArn,
cloudFormationExecutionRoleArn: this.cloudFormationExecutionRoleArn,
requiresBootstrapStackVersion: 1,
}, []);
}
}

/**
* Return the given value if resolved or fall back to a default
*/
Expand Down

0 comments on commit 4eb2637

Please sign in to comment.