Skip to content

Commit

Permalink
feat(core): Add construct.node.stack attribute (#1753)
Browse files Browse the repository at this point in the history
Makes it easier to access some construct's `Stack`, avoiding
having to sprinkle `Stack.find(this)` everywhere.

BREAKING CHANGE: `Stack.find(c)` and `Stack.tryFind(c)` were
replaced by `c.node.stack`.

Fixes #798
  • Loading branch information
RomainMuller authored Feb 13, 2019
1 parent 77b516f commit a46cfd8
Show file tree
Hide file tree
Showing 53 changed files with 171 additions and 193 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export class PipelineDeployStackAction extends cdk.Construct {
constructor(scope: cdk.Construct, id: string, props: PipelineDeployStackActionProps) {
super(scope, id);

if (!cdk.environmentEquals(props.stack.env, cdk.Stack.find(this).env)) {
if (!cdk.environmentEquals(props.stack.env, this.node.stack.env)) {
// FIXME: Add the necessary to extend to stacks in a different account
throw new Error(`Cross-environment deployment is not supported`);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-apigateway/lib/integrations/aws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export class AwsIntegration extends Integration {
integrationHttpMethod: 'POST',
uri: new cdk.Token(() => {
if (!this.scope) { throw new Error('AwsIntegration must be used in API'); }
return cdk.Stack.find(this.scope).formatArn({
return this.scope.node.stack.formatArn({
service: 'apigateway',
account: backend,
resource: apiType,
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-apigateway/lib/method.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ export class Method extends cdk.Construct {
} else if (options.credentialsPassthrough) {
// arn:aws:iam::*:user/*
// tslint:disable-next-line:max-line-length
credentials = cdk.Stack.find(this).formatArn({ service: 'iam', region: '', account: '*', resource: 'user', sep: '/', resourceName: '*' });
credentials = this.node.stack.formatArn({ service: 'iam', region: '', account: '*', resource: 'user', sep: '/', resourceName: '*' });
}

return {
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-apigateway/lib/restapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ export class RestApi extends cdk.Construct implements IRestApi {
method = '*';
}

return cdk.Stack.find(this).formatArn({
return this.node.stack.formatArn({
service: 'execute-api',
resource: this.restApiId,
sep: '/',
Expand Down Expand Up @@ -328,7 +328,7 @@ export class RestApi extends cdk.Construct implements IRestApi {
private configureCloudWatchRole(apiResource: CfnRestApi) {
const role = new iam.Role(this, 'CloudWatchRole', {
assumedBy: new iam.ServicePrincipal('apigateway.amazonaws.com'),
managedPolicyArns: [ cdk.Stack.find(this).formatArn({
managedPolicyArns: [ this.node.stack.formatArn({
service: 'iam',
region: '',
account: 'aws',
Expand Down
4 changes: 1 addition & 3 deletions packages/@aws-cdk/aws-apigateway/lib/stage.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import cdk = require('@aws-cdk/cdk');
import { Stack } from '@aws-cdk/cdk';
import { CfnStage } from './apigateway.generated';
import { Deployment } from './deployment';
import { IRestApi } from './restapi';
Expand Down Expand Up @@ -179,8 +178,7 @@ export class Stage extends cdk.Construct {
if (!path.startsWith('/')) {
throw new Error(`Path must begin with "/": ${path}`);
}
const stack = Stack.find(this);
return `https://${this.restApi.restApiId}.execute-api.${stack.region}.${stack.urlSuffix}/${this.stageName}${path}`;
return `https://${this.restApi.restApiId}.execute-api.${this.node.stack.region}.${this.node.stack.urlSuffix}/${this.stageName}${path}`;
}

private renderMethodSettings(props: StageProps): CfnStage.MethodSettingProperty[] | undefined {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ class SingletonPolicy extends cdk.Construct {
}

private stackArnFromProps(props: { stackName: string, region?: string }): string {
return cdk.Stack.find(this).formatArn({
return this.node.stack.formatArn({
region: props.region,
service: 'cloudformation',
resource: 'stack',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ function _isOrContains(entity: string | string[], value: string): boolean {
}

function _stackArn(stackName: string, scope: cdk.IConstruct): string {
return cdk.Stack.find(scope).formatArn({
return scope.node.stack.formatArn({
service: 'cloudformation',
resource: 'stack',
resourceName: `${stackName}/*`,
Expand All @@ -308,7 +308,7 @@ class PipelineDouble extends cdk.Construct implements cpapi.IPipeline {
constructor(scope: cdk.Construct, id: string, { pipelineName, role }: { pipelineName?: string, role: iam.Role }) {
super(scope, id);
this.pipelineName = pipelineName || 'TestPipeline';
this.pipelineArn = cdk.Stack.find(this).formatArn({ service: 'codepipeline', resource: 'pipeline', resourceName: this.pipelineName });
this.pipelineArn = this.node.stack.formatArn({ service: 'codepipeline', resource: 'pipeline', resourceName: this.pipelineName });
this.role = role;
}

Expand Down
4 changes: 1 addition & 3 deletions packages/@aws-cdk/aws-cloudtrail/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,15 +132,13 @@ export class CloudTrail extends cdk.Construct {
const s3bucket = new s3.Bucket(this, 'S3', {encryption: s3.BucketEncryption.Unencrypted});
const cloudTrailPrincipal = "cloudtrail.amazonaws.com";

const stack = cdk.Stack.find(this);

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

s3bucket.addToResourcePolicy(new iam.PolicyStatement()
.addResource(s3bucket.arnForObjects(`AWSLogs/${stack.accountId}/*`))
.addResource(s3bucket.arnForObjects(`AWSLogs/${this.node.stack.accountId}/*`))
.addActions("s3:PutObject")
.addServicePrincipal(cloudTrailPrincipal)
.setCondition("StringEquals", {'s3:x-amz-acl': "bucket-owner-full-control"}));
Expand Down
5 changes: 2 additions & 3 deletions packages/@aws-cdk/aws-cloudwatch/lib/dashboard.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Construct, Stack, Token } from "@aws-cdk/cdk";
import { Construct, Token } from "@aws-cdk/cdk";
import { CfnDashboard } from './cloudwatch.generated';
import { Column, Row } from "./layout";
import { IWidget } from "./widget";
Expand Down Expand Up @@ -61,7 +61,6 @@ export class Dashboard extends Construct {
*/
private generateDashboardName(): string {
// Combination of stack name and LogicalID, which are guaranteed to be unique.
const stack = Stack.find(this);
return stack.name + '-' + this.dashboard.logicalId;
return this.node.stack.name + '-' + this.dashboard.logicalId;
}
}
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-codebuild/lib/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ class ImportedProject extends ProjectBase {
constructor(scope: cdk.Construct, id: string, private readonly props: ProjectImportProps) {
super(scope, id);

this.projectArn = cdk.Stack.find(this).formatArn({
this.projectArn = this.node.stack.formatArn({
service: 'codebuild',
resource: 'project',
resourceName: props.projectName,
Expand Down Expand Up @@ -744,7 +744,7 @@ export class Project extends ProjectBase {
}

private createLoggingPermission() {
const logGroupArn = cdk.Stack.find(this).formatArn({
const logGroupArn = this.node.stack.formatArn({
service: 'logs',
resource: 'log-group',
sep: ':',
Expand Down
7 changes: 3 additions & 4 deletions packages/@aws-cdk/aws-codecommit/lib/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ class ImportedRepository extends RepositoryBase {
constructor(scope: cdk.Construct, id: string, private readonly props: RepositoryImportProps) {
super(scope, id);

this.repositoryArn = cdk.Stack.find(this).formatArn({
this.repositoryArn = this.node.stack.formatArn({
service: 'codecommit',
resource: props.repositoryName,
});
Expand All @@ -249,9 +249,8 @@ class ImportedRepository extends RepositoryBase {
return this.repositoryCloneUrl('ssh');
}

private repositoryCloneUrl(protocol: 'https' | 'ssh'): string {
const stack = cdk.Stack.find(this);
return `${protocol}://git-codecommit.${stack.region}.${stack.urlSuffix}/v1/repos/${this.repositoryName}`;
private repositoryCloneUrl(protocol: 'https' | 'ssh'): string {
return `${protocol}://git-codecommit.${this.node.stack.region}.${this.node.stack.urlSuffix}/v1/repos/${this.repositoryName}`;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,8 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupBase {

this._autoScalingGroups = props.autoScalingGroups || [];
this.installAgent = props.installAgent === undefined ? true : props.installAgent;
const stack = cdk.Stack.find(this);
this.codeDeployBucket = s3.Bucket.import(this, 'CodeDeployBucket', {
bucketName: `aws-codedeploy-${stack.region}`,
bucketName: `aws-codedeploy-${this.node.stack.region}`,
});
for (const asg of this._autoScalingGroups) {
this.addCodeDeployAgentInstallUserData(asg);
Expand Down Expand Up @@ -359,7 +358,6 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupBase {

this.codeDeployBucket.grantRead(asg.role, 'latest/*');

const stack = cdk.Stack.find(this);
switch (asg.osType) {
case ec2.OperatingSystemType.Linux:
asg.addUserData(
Expand All @@ -377,7 +375,7 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupBase {
'$PKG_CMD install -y awscli',
'TMP_DIR=`mktemp -d`',
'cd $TMP_DIR',
`aws s3 cp s3://aws-codedeploy-${stack.region}/latest/install . --region ${stack.region}`,
`aws s3 cp s3://aws-codedeploy-${this.node.stack.region}/latest/install . --region ${this.node.stack.region}`,
'chmod +x ./install',
'./install auto',
'rm -fr $TMP_DIR',
Expand All @@ -386,7 +384,7 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupBase {
case ec2.OperatingSystemType.Windows:
asg.addUserData(
'Set-Variable -Name TEMPDIR -Value (New-TemporaryFile).DirectoryName',
`aws s3 cp s3://aws-codedeploy-${stack.region}/latest/codedeploy-agent.msi $TEMPDIR\\codedeploy-agent.msi`,
`aws s3 cp s3://aws-codedeploy-${this.node.stack.region}/latest/codedeploy-agent.msi $TEMPDIR\\codedeploy-agent.msi`,
'$TEMPDIR\\codedeploy-agent.msi /quiet /l c:\\temp\\host-agent-install-log.txt',
);
break;
Expand Down
6 changes: 3 additions & 3 deletions packages/@aws-cdk/aws-codedeploy/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { CfnDeploymentGroup } from './codedeploy.generated';
import { AutoRollbackConfig } from './rollback-config';

export function applicationNameToArn(applicationName: string, scope: cdk.IConstruct): string {
return cdk.Stack.find(scope).formatArn({
return scope.node.stack.formatArn({
service: 'codedeploy',
resource: 'application',
resourceName: applicationName,
Expand All @@ -13,7 +13,7 @@ export function applicationNameToArn(applicationName: string, scope: cdk.IConstr
}

export function deploymentGroupNameToArn(applicationName: string, deploymentGroupName: string, scope: cdk.IConstruct): string {
return cdk.Stack.find(scope).formatArn({
return scope.node.stack.formatArn({
service: 'codedeploy',
resource: 'deploymentgroup',
resourceName: `${applicationName}/${deploymentGroupName}`,
Expand All @@ -22,7 +22,7 @@ export function deploymentGroupNameToArn(applicationName: string, deploymentGrou
}

export function arnForDeploymentConfigName(name: string, scope: cdk.IConstruct): string {
return cdk.Stack.find(scope).formatArn({
return scope.node.stack.formatArn({
service: 'codedeploy',
resource: 'deploymentconfig',
resourceName: name,
Expand Down
11 changes: 5 additions & 6 deletions packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ export class Pipeline extends cdk.Construct implements cpapi.IPipeline {
this.artifactStores = {};

// Does not expose a Fn::GetAtt for the ARN so we'll have to make it ourselves
this.pipelineArn = cdk.Stack.find(this).formatArn({
this.pipelineArn = this.node.stack.formatArn({
service: 'codepipeline',
resource: this.pipelineName
});
Expand Down Expand Up @@ -336,8 +336,7 @@ export class Pipeline extends cdk.Construct implements cpapi.IPipeline {
}

// get the region the Pipeline itself is in
const pipelineStack = cdk.Stack.find(this);
const pipelineRegion = pipelineStack.requireRegion(
const pipelineRegion = this.node.stack.requireRegion(
"You need to specify an explicit region when using CodePipeline's cross-region support");

// if we already have an ArtifactStore generated for this region, or it's the Pipeline's region, nothing to do
Expand All @@ -347,9 +346,9 @@ export class Pipeline extends cdk.Construct implements cpapi.IPipeline {

let replicationBucketName = this.crossRegionReplicationBuckets[action.region];
if (!replicationBucketName) {
const pipelineAccount = pipelineStack.requireAccountId(
const pipelineAccount = this.node.stack.requireAccountId(
"You need to specify an explicit account when using CodePipeline's cross-region support");
const app = pipelineStack.parentApp();
const app = this.node.stack.parentApp();
if (!app) {
throw new Error(`Pipeline stack which uses cross region actions must be part of an application`);
}
Expand Down Expand Up @@ -477,7 +476,7 @@ export class Pipeline extends cdk.Construct implements cpapi.IPipeline {

// add the Pipeline's artifact store
const artifactStore = this.renderArtifactStore();
this.artifactStores[cdk.Stack.find(this).requireRegion()] = {
this.artifactStores[this.node.stack.requireRegion()] = {
Location: artifactStore.location,
Type: artifactStore.type,
EncryptionKey: artifactStore.encryptionKey,
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-dynamodb/lib/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@ export class Table extends Construct {
private makeScalingRole(): iam.IRole {
// Use a Service Linked Role.
return iam.Role.import(this, 'ScalingRole', {
roleArn: cdk.Stack.find(this).formatArn({
roleArn: this.node.stack.formatArn({
// https://docs.aws.amazon.com/autoscaling/application/userguide/application-auto-scaling-service-linked-roles.html
service: 'iam',
resource: 'role/aws-service-role/dynamodb.application-autoscaling.amazonaws.com',
Expand Down
5 changes: 2 additions & 3 deletions packages/@aws-cdk/aws-ec2/lib/machine-image.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Construct, SSMParameterProvider, Stack } from '@aws-cdk/cdk';
import { Construct, SSMParameterProvider } from '@aws-cdk/cdk';

/**
* Interface for classes that can select an appropriate machine image to use
Expand Down Expand Up @@ -188,8 +188,7 @@ export class GenericLinuxImage implements IMachineImageSource {
}

public getImage(scope: Construct): MachineImage {
const stack = Stack.find(scope);
const region = stack.requireRegion('AMI cannot be determined');
const region = scope.node.stack.requireRegion('AMI cannot be determined');
const ami = region !== 'test-region' ? this.amiMap[region] : 'ami-12345';
if (!ami) {
throw new Error(`Unable to find AMI in AMI map: no AMI specified for region '${region}'`);
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-ec2/lib/security-group.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Construct, IConstruct, Output, Stack, Token } from '@aws-cdk/cdk';
import { Construct, IConstruct, Output, Token } from '@aws-cdk/cdk';
import { Connections, IConnectable } from './connections';
import { CfnSecurityGroup, CfnSecurityGroupEgress, CfnSecurityGroupIngress } from './ec2.generated';
import { IPortRange, ISecurityGroupRule } from './security-group-rule';
Expand Down Expand Up @@ -193,7 +193,7 @@ function determineRuleScope(
}

function differentStacks(group1: SecurityGroupBase, group2: SecurityGroupBase) {
return Stack.find(group1) !== Stack.find(group2);
return group1.node.stack !== group2.node.stack;
}

export interface SecurityGroupProps {
Expand Down
6 changes: 3 additions & 3 deletions packages/@aws-cdk/aws-ec2/lib/vpc-ref.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Construct, IConstruct, IDependable, Stack } from "@aws-cdk/cdk";
import { Construct, IConstruct, IDependable } from "@aws-cdk/cdk";
import { subnetName } from './util';

export interface IVpcSubnet extends IConstruct {
Expand Down Expand Up @@ -231,7 +231,7 @@ export abstract class VpcNetworkBase extends Construct implements IVpcNetwork {
* The region where this VPC is defined
*/
public get vpcRegion(): string {
return Stack.find(this).region;
return this.node.stack.region;
}

}
Expand Down Expand Up @@ -303,4 +303,4 @@ export interface VpcSubnetImportProps {
* The subnetId for this particular subnet
*/
subnetId: string;
}
}
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-ecr/lib/repository-ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export abstract class RepositoryBase extends cdk.Construct implements IRepositor
* as the current stack.
*/
public static arnForLocalRepository(repositoryName: string, scope: cdk.IConstruct): string {
return cdk.Stack.find(scope).formatArn({
return scope.node.stack.formatArn({
service: 'ecr',
resource: 'repository',
resourceName: repositoryName
Expand Down Expand Up @@ -160,7 +160,7 @@ export abstract class RepositoryBase extends cdk.Construct implements IRepositor
*/
public repositoryUriForTag(tag?: string): string {
const tagSuffix = tag ? `:${tag}` : '';
const parts = cdk.Stack.find(this).parseArn(this.repositoryArn);
const parts = this.node.stack.parseArn(this.repositoryArn);
return `${parts.account}.dkr.ecr.${parts.region}.amazonaws.com/${this.repositoryName}${tagSuffix}`;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-ecs/lib/base/base-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ export abstract class BaseService extends cdk.Construct
private makeAutoScalingRole(): iam.IRole {
// Use a Service Linked Role.
return iam.Role.import(this, 'ScalingRole', {
roleArn: cdk.Stack.find(this).formatArn({
roleArn: this.node.stack.formatArn({
service: 'iam',
resource: 'role/aws-service-role/ecs.application-autoscaling.amazonaws.com',
resourceName: 'AWSServiceRoleForApplicationAutoScaling_ECSService',
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-ecs/lib/cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ class ImportedCluster extends cdk.Construct implements ICluster {
this.vpc = ec2.VpcNetwork.import(this, "vpc", props.vpc);
this.hasEc2Capacity = props.hasEc2Capacity !== false;

this.clusterArn = props.clusterArn !== undefined ? props.clusterArn : cdk.Stack.find(this).formatArn({
this.clusterArn = props.clusterArn !== undefined ? props.clusterArn : this.node.stack.formatArn({
service: 'ecs',
resource: 'cluster',
resourceName: props.clusterName,
Expand Down
3 changes: 1 addition & 2 deletions packages/@aws-cdk/aws-ecs/lib/log-drivers/aws-log-driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,12 @@ export class AwsLogDriver extends LogDriver {
* Return the log driver CloudFormation JSON
*/
public renderLogDriver(): CfnTaskDefinition.LogConfigurationProperty {
const stack = cdk.Stack.find(this);
return {
logDriver: 'awslogs',
options: removeEmpty({
'awslogs-group': this.logGroup.logGroupName,
'awslogs-stream-prefix': this.props.streamPrefix,
'awslogs-region': stack.region,
'awslogs-region': this.node.stack.region,
'awslogs-datetime-format': this.props.datetimeFormat,
'awslogs-multiline-pattern': this.props.multilinePattern,
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,7 @@ export class ApplicationLoadBalancer extends BaseLoadBalancer implements IApplic
this.setAttribute('access_logs.s3.bucket', bucket.bucketName.toString());
this.setAttribute('access_logs.s3.prefix', prefix);

const stack = cdk.Stack.find(this);

const region = stack.requireRegion('Enable ELBv2 access logging');
const region = this.node.stack.requireRegion('Enable ELBv2 access logging');
const account = ELBV2_ACCOUNTS[region];
if (!account) {
throw new Error(`Cannot enable access logging; don't know ELBv2 account for region ${region}`);
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-iam/lib/managed-policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export class AwsManagedPolicy {
*/
public get policyArn(): string {
// the arn is in the form of - arn:aws:iam::aws:policy/<policyName>
return cdk.Stack.find(this.scope).formatArn({
return this.scope.node.stack.formatArn({
service: "iam",
region: "", // no region for managed policy
account: "aws", // the account for a managed policy is 'aws'
Expand Down
Loading

0 comments on commit a46cfd8

Please sign in to comment.