Skip to content

Commit 53e6825

Browse files
authored
feat(core): generalization of dependencies (#1583)
Constructs can now take a dependency on any other construct. Before, only `Resource`s could take dependencies, and they would depend on `IDependable` which had to be implemented explicitly. In this change we generalize the concept of dependencies from construct trees to other construct trees; all constructs now take dependencies and also implement `IDependable`. The semantics are that any resource in the depending tree will depend on all resources in the depended tree. Dependencies are cross-stack aware If you take a dependency on a construct in another stack, the dependency does not get rendered in the template, but is instead added as a dependency between stacks. Fixes #1568, fixes #95. BREAKING CHANGE: `resource.addDependency()` has been moved onto `ConstructNode`. You now write `resource.node.addDependency()`. VPC's `internetDependency` has been moved to the subnets as `internetConnectivityEstablished`. Target Group's `loadBalancerAssociationDependencies` has been renamed to `loadBalancerAttached`.
1 parent 7cdbcec commit 53e6825

File tree

73 files changed

+500
-564
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+500
-564
lines changed

examples/cdk-examples-typescript/custom-resource/index.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ interface DemoResourceProps {
1616
failCreate?: boolean;
1717
}
1818

19-
class DemoResource extends cdk.Construct implements cdk.IDependable {
20-
public readonly dependencyElements: cdk.IDependable[];
19+
class DemoResource extends cdk.Construct {
2120
public readonly response: string;
2221

2322
constructor(scope: cdk.Construct, id: string, props: DemoResourceProps) {
@@ -36,7 +35,6 @@ class DemoResource extends cdk.Construct implements cdk.IDependable {
3635
});
3736

3837
this.response = resource.getAtt('Response').toString();
39-
this.dependencyElements = [resource];
4038
}
4139
}
4240

@@ -91,7 +89,7 @@ class FailAfterCreatingStack extends cdk.Stack {
9189
});
9290

9391
// Make sure the rollback gets triggered only after the custom resource has been fully created.
94-
bucket.addDependency(resource);
92+
bucket.node.addDependency(resource);
9593
}
9694
}
9795

examples/cdk-examples-typescript/resource-overrides/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class ResourceOverridesExample extends cdk.Stack {
3131
// This is how to specify resource options such as dependencies, metadata, update policy
3232
//
3333

34-
bucketResource.addDependency(otherBucket.node.findChild('Resource') as cdk.Resource);
34+
bucketResource.node.addDependency(otherBucket.node.findChild('Resource') as cdk.Resource);
3535
bucketResource.options.metadata = { MetadataKey: 'MetadataValue' };
3636
bucketResource.options.updatePolicy = {
3737
autoScalingRollingUpdate: {

packages/@aws-cdk/aws-apigateway/lib/deployment.ts

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,13 @@ export interface DeploymentProps {
5151
* Furthermore, since a deployment does not reference any of the REST API
5252
* resources and methods, CloudFormation will likely provision it before these
5353
* resources are created, which means that it will represent a "half-baked"
54-
* model. Use the `addDependency(dep)` method to circumvent that. This is done
54+
* model. Use the `node.addDependency(dep)` method to circumvent that. This is done
5555
* automatically for the `restApi.latestDeployment` deployment.
5656
*/
57-
export class Deployment extends cdk.Construct implements cdk.IDependable {
57+
export class Deployment extends cdk.Construct {
5858
public readonly deploymentId: string;
5959
public readonly api: IRestApi;
6060

61-
/**
62-
* Allows taking a dependency on this construct.
63-
*/
64-
public readonly dependencyElements = new Array<cdk.IDependable>();
65-
6661
private readonly resource: LatestDeploymentResource;
6762

6863
constructor(scope: cdk.Construct, id: string, props: DeploymentProps) {
@@ -79,15 +74,6 @@ export class Deployment extends cdk.Construct implements cdk.IDependable {
7974

8075
this.api = props.api;
8176
this.deploymentId = new cdk.Token(() => this.resource.deploymentId).toString();
82-
this.dependencyElements.push(this.resource);
83-
}
84-
85-
/**
86-
* Adds a dependency for this deployment. Should be called by all resources and methods
87-
* so they are provisioned before this Deployment.
88-
*/
89-
public addDependency(dep: cdk.IDependable) {
90-
this.resource.addDependency(dep);
9177
}
9278

9379
/**
@@ -182,5 +168,7 @@ class LatestDeploymentResource extends CfnDeployment {
182168

183169
this.lazyLogicalId = this.originalLogicalId + md5.digest("hex");
184170
}
171+
172+
super.prepare();
185173
}
186174
}

packages/@aws-cdk/aws-apigateway/lib/method.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export class Method extends cdk.Construct {
104104

105105
const deployment = props.resource.resourceApi.latestDeployment;
106106
if (deployment) {
107-
deployment.addDependency(resource);
107+
deployment.node.addDependency(resource);
108108
deployment.addToLogicalId({ method: methodProps });
109109
}
110110
}

packages/@aws-cdk/aws-apigateway/lib/resource.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ export class Resource extends cdk.Construct implements IRestApiResource {
118118

119119
const deployment = props.parent.resourceApi.latestDeployment;
120120
if (deployment) {
121-
deployment.addDependency(resource);
121+
deployment.node.addDependency(resource);
122122
deployment.addToLogicalId({ resource: resourceProps });
123123
}
124124

packages/@aws-cdk/aws-apigateway/lib/restapi.ts

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ export interface RestApiProps extends ResourceOptions {
154154
* By default, the API will automatically be deployed and accessible from a
155155
* public endpoint.
156156
*/
157-
export class RestApi extends cdk.Construct implements cdk.IDependable, IRestApi {
157+
export class RestApi extends cdk.Construct implements IRestApi {
158158
/**
159159
* Imports an existing REST API resource.
160160
* @param parent Parent construct
@@ -177,11 +177,6 @@ export class RestApi extends cdk.Construct implements cdk.IDependable, IRestApi
177177
*/
178178
public latestDeployment?: Deployment;
179179

180-
/**
181-
* Allows taking a dependency on this construct.
182-
*/
183-
public readonly dependencyElements = new Array<cdk.IDependable>();
184-
185180
/**
186181
* API Gateway stage that points to the latest deployment (if defined).
187182
*
@@ -226,16 +221,9 @@ export class RestApi extends cdk.Construct implements cdk.IDependable, IRestApi
226221
this.configureCloudWatchRole(resource);
227222
}
228223

229-
this.dependencyElements.push(resource);
230-
if (this.latestDeployment) {
231-
this.dependencyElements.push(this.latestDeployment);
232-
}
233-
if (this.deploymentStage) {
234-
this.dependencyElements.push(this.deploymentStage);
235-
}
236-
237224
// configure the "root" resource
238225
this.root = {
226+
get dependencyRoots() { return [this]; },
239227
node: this.node,
240228
addResource: (pathPart: string, options?: ResourceOptions) => {
241229
return new Resource(this, pathPart, { parent: this.root, pathPart, ...options });
@@ -372,7 +360,7 @@ export class RestApi extends cdk.Construct implements cdk.IDependable, IRestApi
372360
cloudWatchRoleArn: role.roleArn
373361
});
374362

375-
resource.addDependency(apiResource);
363+
resource.node.addDependency(apiResource);
376364
}
377365
}
378366

packages/@aws-cdk/aws-apigateway/lib/stage.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,8 @@ export interface MethodDeploymentOptions {
133133
cacheDataEncrypted?: boolean;
134134
}
135135

136-
export class Stage extends cdk.Construct implements cdk.IDependable {
136+
export class Stage extends cdk.Construct {
137137
public readonly stageName: string;
138-
public readonly dependencyElements = new Array<cdk.IDependable>();
139138

140139
private readonly restApi: IRestApi;
141140

@@ -170,7 +169,6 @@ export class Stage extends cdk.Construct implements cdk.IDependable {
170169

171170
this.stageName = resource.ref;
172171
this.restApi = props.deployment.api;
173-
this.dependencyElements.push(resource);
174172
}
175173

176174
/**

packages/@aws-cdk/aws-apigateway/test/integ.restapi.books.expected.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -530,8 +530,8 @@
530530
"booksapibooksGETA776447A",
531531
"booksapibooksPOSTF6C6559D",
532532
"booksapibooksbookid5264BCA2",
533-
"booksapibooksbookidGETCCE21986",
534-
"booksapibooksbookidDELETE214F4059"
533+
"booksapibooksbookidDELETE214F4059",
534+
"booksapibooksbookidGETCCE21986"
535535
]
536536
},
537537
"booksapiDeploymentStageprod55D8E03E": {
@@ -837,7 +837,9 @@
837837
"Ref": "AWS::Region"
838838
},
839839
".",
840-
{ "Ref": "AWS::URLSuffix" },
840+
{
841+
"Ref": "AWS::URLSuffix"
842+
},
841843
"/",
842844
{
843845
"Ref": "booksapiDeploymentStageprod55D8E03E"

packages/@aws-cdk/aws-apigateway/test/integ.restapi.defaults.expected.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,9 @@
110110
"Ref": "AWS::Region"
111111
},
112112
".",
113-
{ "Ref": "AWS::URLSuffix" },
113+
{
114+
"Ref": "AWS::URLSuffix"
115+
},
114116
"/",
115117
{
116118
"Ref": "myapiDeploymentStageprod298F01AF"

packages/@aws-cdk/aws-apigateway/test/integ.restapi.expected.json

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@
1616
},
1717
"DependsOn": [
1818
"myapiv113487378",
19-
"myapiv1toysA55FCBC4",
20-
"myapiv1toysGET7348114D",
21-
"myapiv1toysPOST55128058",
22-
"myapiv1toysPUT59AFBBC2",
2319
"myapiv1appliances507FEFF4",
2420
"myapiv1appliancesGET8FE872EC",
2521
"myapiv1books1D4BE6C1",
2622
"myapiv1booksGETC6B996D0",
27-
"myapiv1booksPOST53E2832E"
23+
"myapiv1booksPOST53E2832E",
24+
"myapiv1toysA55FCBC4",
25+
"myapiv1toysGET7348114D",
26+
"myapiv1toysPOST55128058",
27+
"myapiv1toysPUT59AFBBC2"
2828
],
2929
"DeletionPolicy": "Retain"
3030
},
@@ -602,7 +602,9 @@
602602
"Ref": "AWS::Region"
603603
},
604604
".",
605-
{ "Ref": "AWS::URLSuffix" },
605+
{
606+
"Ref": "AWS::URLSuffix"
607+
},
606608
"/",
607609
{
608610
"Ref": "myapiDeploymentStagebeta96434BEB"

0 commit comments

Comments
 (0)