Repository: awslabs/cdk8s
Pull request #324 (2020-09-22 11:29:46)

chore: Upgrade constructs
Upgrade construct to version `3.0.4`. This version does not include the tokens mechanism, to replace it, we implemented a simple mechanism that facilitates just the cdk8s needs for tokens:

- Lazy.any
- Implicit token generated by the CLI (objects with a `resolve` function)

This PR enabled https://github.com/aws/aws-cdk/issues/9670

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*


mergify[bot]: Your pull request will be updated and merged automatically (do not update manually).
mergify[bot]: Your pull request will be updated and merged automatically (do not update manually).
mergify[bot]: Your pull request will be updated and merged automatically (do not update manually).

Patch:
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 314a0dc4a..6771be0ac 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -24,7 +24,7 @@ jobs:
     # the head of the pull request instead of the merge commit.
     - run: git checkout HEAD^2
       if: ${{ github.event_name == 'pull_request' }}
-      
+
     # Initializes the CodeQL tools for scanning.
     - name: Initialize CodeQL
       uses: github/codeql-action/init@v1
@@ -36,8 +36,8 @@ jobs:
       shell: bash
       run: |
         cd packages/cdk8s-cli/templates/java-app
-        sed -i 's/{{ cdk8s_version }}/0.26.0/g' pom.xml
-        sed -i 's/{{ constructs_version }}/2.0.2/g' pom.xml
+        sed -i 's/{{ cdk8s_version }}/0.28.0/g' pom.xml
+        sed -i 's/{{ constructs_version }}/3.0.4/g' pom.xml
         mvn install
         mvn compile
 
diff --git a/examples/java/hello/package.json b/examples/java/hello/package.json
index 2925b2b25..bf329d01a 100644
--- a/examples/java/hello/package.json
+++ b/examples/java/hello/package.json
@@ -10,7 +10,7 @@
   },
   "dependencies": {
     "cdk8s": "0.0.0",
-    "constructs": "^2.0.2"
+    "constructs": "^3.0.4"
   },
   "devDependencies": {
     "cdk8s-cli": "0.0.0"
diff --git a/examples/java/hello/pom.xml b/examples/java/hello/pom.xml
index ad5f71331..bee4a75e1 100644
--- a/examples/java/hello/pom.xml
+++ b/examples/java/hello/pom.xml
@@ -16,7 +16,7 @@
     <dependency>
       <groupId>software.constructs</groupId>
       <artifactId>constructs</artifactId>
-      <version>2.0.2</version>
+      <version>3.0.4</version>
     </dependency>
     <dependency>
       <groupId>com.google.guava</groupId>
diff --git a/examples/java/web-service/package.json b/examples/java/web-service/package.json
index 8cff321fa..493364f0b 100644
--- a/examples/java/web-service/package.json
+++ b/examples/java/web-service/package.json
@@ -10,7 +10,7 @@
   },
   "dependencies": {
     "cdk8s": "0.0.0",
-    "constructs": "^2.0.2"
+    "constructs": "^3.0.4"
   },
   "devDependencies": {
     "cdk8s-cli": "0.0.0"
diff --git a/examples/java/web-service/pom.xml b/examples/java/web-service/pom.xml
index 95ea96b0b..009bd205f 100644
--- a/examples/java/web-service/pom.xml
+++ b/examples/java/web-service/pom.xml
@@ -16,7 +16,7 @@
     <dependency>
       <groupId>software.constructs</groupId>
       <artifactId>constructs</artifactId>
-      <version>2.0.2</version>
+      <version>3.0.4</version>
     </dependency>
     <dependency>
       <groupId>com.google.guava</groupId>
diff --git a/examples/python/crd/Pipfile b/examples/python/crd/Pipfile
index 406eb8926..a49ee9aca 100644
--- a/examples/python/crd/Pipfile
+++ b/examples/python/crd/Pipfile
@@ -6,7 +6,7 @@ verify_ssl = true
 [dev-packages]
 
 [packages]
-constructs = "==2.0.2"
+constructs = "==3.0.4"
 cdk8s = "~=0.26.0"
 
 [requires]
diff --git a/examples/python/crd/package.json b/examples/python/crd/package.json
index 837352556..9271404bb 100644
--- a/examples/python/crd/package.json
+++ b/examples/python/crd/package.json
@@ -10,7 +10,7 @@
   },
   "dependencies": {
     "cdk8s": "0.0.0",
-    "constructs": "^2.0.2"
+    "constructs": "^3.0.4"
   },
   "devDependencies": {
     "cdk8s-cli": "0.0.0"
diff --git a/examples/python/hello/Pipfile b/examples/python/hello/Pipfile
index 1cef024fa..4fe1ed517 100644
--- a/examples/python/hello/Pipfile
+++ b/examples/python/hello/Pipfile
@@ -6,7 +6,7 @@ verify_ssl = true
 [dev-packages]
 
 [packages]
-constructs = "==2.0.2"
+constructs = "==3.0.4"
 cdk8s = "~=0.26.0"
 
 [requires]
diff --git a/examples/python/hello/package.json b/examples/python/hello/package.json
index 3179bd5a5..d675648ad 100644
--- a/examples/python/hello/package.json
+++ b/examples/python/hello/package.json
@@ -10,7 +10,7 @@
   },
   "dependencies": {
     "cdk8s": "0.0.0",
-    "constructs": "^2.0.2"
+    "constructs": "^3.0.4"
   },
   "devDependencies": {
     "cdk8s-cli": "0.0.0"
diff --git a/examples/python/web-service/Pipfile b/examples/python/web-service/Pipfile
index 406eb8926..a49ee9aca 100644
--- a/examples/python/web-service/Pipfile
+++ b/examples/python/web-service/Pipfile
@@ -6,7 +6,7 @@ verify_ssl = true
 [dev-packages]
 
 [packages]
-constructs = "==2.0.2"
+constructs = "==3.0.4"
 cdk8s = "~=0.26.0"
 
 [requires]
diff --git a/examples/python/web-service/package.json b/examples/python/web-service/package.json
index 661f6fc97..8631d02f9 100644
--- a/examples/python/web-service/package.json
+++ b/examples/python/web-service/package.json
@@ -10,7 +10,7 @@
   },
   "dependencies": {
     "cdk8s": "0.0.0",
-    "constructs": "^2.0.2"
+    "constructs": "^3.0.4"
   },
   "devDependencies": {
     "cdk8s-cli": "0.0.0"
diff --git a/examples/typescript/cdk8s-plus-elasticsearch-query/package.json b/examples/typescript/cdk8s-plus-elasticsearch-query/package.json
index ad474a55c..17c0c4648 100644
--- a/examples/typescript/cdk8s-plus-elasticsearch-query/package.json
+++ b/examples/typescript/cdk8s-plus-elasticsearch-query/package.json
@@ -19,7 +19,7 @@
   "dependencies": {
     "cdk8s": "0.0.0",
     "cdk8s-plus": "0.0.0",
-    "constructs": "^2.0.2"
+    "constructs": "^3.0.4"
   },
   "devDependencies": {
     "@types/jest": "^26.0.8",
diff --git a/examples/typescript/crd/package.json b/examples/typescript/crd/package.json
index 2e51c7987..09812b7f0 100644
--- a/examples/typescript/crd/package.json
+++ b/examples/typescript/crd/package.json
@@ -19,7 +19,7 @@
   },
   "dependencies": {
     "cdk8s": "0.0.0",
-    "constructs": "^2.0.2"
+    "constructs": "^3.0.4"
   },
   "devDependencies": {
     "@types/jest": "^25.1.2",
diff --git a/examples/typescript/hello/package.json b/examples/typescript/hello/package.json
index 033dcabbe..3c31a13a3 100644
--- a/examples/typescript/hello/package.json
+++ b/examples/typescript/hello/package.json
@@ -19,7 +19,7 @@
   },
   "dependencies": {
     "cdk8s": "0.0.0",
-    "constructs": "^2.0.2"
+    "constructs": "^3.0.4"
   },
   "devDependencies": {
     "@types/jest": "^25.1.2",
diff --git a/examples/typescript/include-dashboard/package.json b/examples/typescript/include-dashboard/package.json
index d096a3b00..01e6227f3 100644
--- a/examples/typescript/include-dashboard/package.json
+++ b/examples/typescript/include-dashboard/package.json
@@ -18,7 +18,7 @@
   },
   "dependencies": {
     "cdk8s": "0.0.0",
-    "constructs": "^2.0.2"
+    "constructs": "^3.0.4"
   },
   "devDependencies": {
     "@types/jest": "^25.1.2",
diff --git a/examples/typescript/podinfo/package.json b/examples/typescript/podinfo/package.json
index bc18cf1e9..d7354c4c3 100644
--- a/examples/typescript/podinfo/package.json
+++ b/examples/typescript/podinfo/package.json
@@ -18,7 +18,7 @@
   },
   "dependencies": {
     "cdk8s": "0.0.0",
-    "constructs": "^2.0.2"
+    "constructs": "^3.0.4"
   },
   "devDependencies": {
     "@types/jest": "^25.1.2",
diff --git a/examples/typescript/web-service/package.json b/examples/typescript/web-service/package.json
index c62615902..0796abcfd 100644
--- a/examples/typescript/web-service/package.json
+++ b/examples/typescript/web-service/package.json
@@ -18,7 +18,7 @@
   },
   "dependencies": {
     "cdk8s": "0.0.0",
-    "constructs": "^2.0.2"
+    "constructs": "^3.0.4"
   },
   "devDependencies": {
     "@types/jest": "^25.1.2",
diff --git a/package.json b/package.json
index 348db1575..3d9857590 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,8 @@
     "bump": "tools/bump.sh",
     "build": "lerna run build",
     "test": "lerna run test",
-    "package": "lerna run package && tools/collect-dist.sh",
+    "projen": "lerna run projen",
+    "package": "tools/pack.sh && tools/collect-dist.sh",
     "integ": "test/run-against-dist test/test-all.sh",
     "integ:update": "UPDATE_SNAPSHOTS=1 yarn integ",
     "release-github": "tools/release-github.sh"
diff --git a/packages/cdk8s-cli/.projenrc.js b/packages/cdk8s-cli/.projenrc.js
index 191062d4e..8971e8f0e 100644
--- a/packages/cdk8s-cli/.projenrc.js
+++ b/packages/cdk8s-cli/.projenrc.js
@@ -11,9 +11,9 @@ const project = new TypeScriptLibraryProject({
   dependencies: {
     "cdk8s": Semver.pinned('0.0.0'),
     "codemaker": Semver.caret('0.22.0'),
-    "constructs": Semver.caret('2.0.2'),
+    "constructs": Semver.caret(common.versions.constructs),
     "fs-extra": Semver.caret('8.1.0'),
-    "jsii-srcmak": Semver.caret('0.1.10'),
+    "jsii-srcmak": Semver.caret('0.1.36'),
     "sscaff": Semver.caret('1.2.0'),
     "yaml": Semver.caret('1.7.2'),
     "yargs": Semver.caret('15.1.0'),
diff --git a/packages/cdk8s-cli/package.json b/packages/cdk8s-cli/package.json
index 784807ea3..5f4be2be1 100644
--- a/packages/cdk8s-cli/package.json
+++ b/packages/cdk8s-cli/package.json
@@ -52,7 +52,7 @@
   "dependencies": {
     "cdk8s": "0.0.0",
     "codemaker": "^0.22.0",
-    "constructs": "^2.0.2",
+    "constructs": "^3.0.4",
     "fs-extra": "^8.1.0",
     "jsii-srcmak": "^0.1.36",
     "sscaff": "^1.2.0",
diff --git a/packages/cdk8s-cli/src/import/base.ts b/packages/cdk8s-cli/src/import/base.ts
index 694f16398..a00675e66 100644
--- a/packages/cdk8s-cli/src/import/base.ts
+++ b/packages/cdk8s-cli/src/import/base.ts
@@ -63,7 +63,7 @@ export abstract class ImportBase {
           await code.save(staging);
 
           // these are the module dependencies we compile against
-          const deps = [ '@types/node', 'constructs', 'cdk8s' ];
+          const deps = [ '@types/node', 'constructs', 'cdk8s'];
 
           const opts: srcmak.Options = {
             entrypoint: fileName,
diff --git a/packages/cdk8s-cli/templates/python-app/.hooks.sscaff.js b/packages/cdk8s-cli/templates/python-app/.hooks.sscaff.js
index b3019c91e..a9dbb04a6 100644
--- a/packages/cdk8s-cli/templates/python-app/.hooks.sscaff.js
+++ b/packages/cdk8s-cli/templates/python-app/.hooks.sscaff.js
@@ -34,20 +34,20 @@ exports.post = options => {
   /**
    * Using --no-deps flag here to ignore subdependencies. For cdk8s_plus, that's
    * these dependencies:
-   * 
+   *
    * jsii (<2.0.0,>=1.7.0)
    * publication (>=0.0.3)
    * cdk8s (==0.0.0)
-   * constructs (<3.0.0,>=2.0.2)
-   * 
+   * constructs (<4.0.0,>=3.0.4)
+   *
    * Even when installing locally, with this command:
-   * 
+   *
    * pipenv install dist/python/cdk8s_plus-0.0.0-py3-none-any.whl
-   * 
+   *
    * this would point to these sub-dependencies in https://pypi.org/ which
    * unfortunataly does not have cdk8s-0.0.0. We've already installed that
    * locally, so this is safe to ignore.
-   * 
+   *
    */
   execSync(`pip3 install --no-deps ${pypi_cdk8s_plus}`, { stdio: 'inherit' });
   chmodSync('main.py', '700');
diff --git a/packages/cdk8s-cli/templates/python-app/Pipfile b/packages/cdk8s-cli/templates/python-app/Pipfile
index 2cdf1077f..91ea3ce1a 100644
--- a/packages/cdk8s-cli/templates/python-app/Pipfile
+++ b/packages/cdk8s-cli/templates/python-app/Pipfile
@@ -7,4 +7,4 @@ verify_ssl = true
 python_version = "3.7"
 
 [packages]
-constructs = "==2.0.2"
+constructs = "==3.0.4"
diff --git a/packages/cdk8s-plus/.projenrc.js b/packages/cdk8s-plus/.projenrc.js
index a1d26b9eb..3c93f7787 100644
--- a/packages/cdk8s-plus/.projenrc.js
+++ b/packages/cdk8s-plus/.projenrc.js
@@ -1,8 +1,6 @@
 const { JsiiProject, Semver } = require('projen');
 const common = require('../projen-common');
 
-const cdk8sDependency = Semver.caret('0.0.0')
-
 const project = new JsiiProject({
   name: 'cdk8s-plus',
   description: 'High level abstractions on top of cdk8s',
@@ -13,16 +11,17 @@ const project = new JsiiProject({
   // dependencies
   jsiiVersion: Semver.caret(common.versions.jsii),
   peerDependencies: {
-    constructs: Semver.caret(common.versions.constructs),
-    cdk8s: cdk8sDependency,
+    "cdk8s": Semver.caret('0.0.0'),
+    "constructs": Semver.caret(common.versions.constructs),
   },
   dependencies: {
     minimatch: Semver.caret('3.0.4'),
-    cdk8s: cdk8sDependency
   },
   bundledDependencies: [ 'minimatch' ],
   devDependencies: {
     '@types/minimatch': Semver.caret('3.0.3'),
+    "cdk8s": Semver.caret('0.0.0'),
+    "constructs": Semver.caret(common.versions.constructs),
   },
 
   // jsii configuration
diff --git a/packages/cdk8s-plus/API.md b/packages/cdk8s-plus/API.md
index ffc4a125a..21eff4bb4 100644
--- a/packages/cdk8s-plus/API.md
+++ b/packages/cdk8s-plus/API.md
@@ -410,9 +410,7 @@ selectByLabel(key: string, value: string): void
 Represents a length of time.
 
 The amount can be specified either as a literal value (e.g: `10`) which
-cannot be negative, or as an unresolved number token.
-
-When the amount is passed as a token, unit conversion is not possible.
+cannot be negative.
 
 
 ### Methods
@@ -524,22 +522,6 @@ toSeconds(opts?: TimeConversionOptions): number
 __Returns__:
 * <code>number</code>
 
-#### toString()🔹 <a id="cdk8s-plus-duration-tostring"></a>
-
-Returns a string representation of this `Duration` that is also a Token that cannot be successfully resolved.
-
-This
-protects users against inadvertently stringifying a `Duration` object, when they should have called one of the
-`to*` methods instead.
-
-```ts
-toString(): string
-```
-
-
-__Returns__:
-* <code>string</code>
-
 #### *static* days(amount)🔹 <a id="cdk8s-plus-duration-days"></a>
 
 Create a Duration representing an amount of days.
@@ -1180,7 +1162,7 @@ serve(port: number, options?: ServicePortOptions): void
 Represents the amount of digital storage.
 
 The amount can be specified either as a literal value (e.g: `10`) which
-cannot be negative, or as an unresolved number token.
+cannot be negative.
 
 When the amount is passed as a token, unit conversion is not possible.
 
diff --git a/packages/cdk8s-plus/package.json b/packages/cdk8s-plus/package.json
index a56941e5d..016b168c8 100644
--- a/packages/cdk8s-plus/package.json
+++ b/packages/cdk8s-plus/package.json
@@ -31,8 +31,8 @@
     "organization": true
   },
   "devDependencies": {
-    "constructs": "2.0.2",
-    "cdk8s": "0.0.0",
+    "cdk8s": "^0.0.0",
+    "constructs": "^3.0.4",
     "@types/minimatch": "^3.0.3",
     "projen": "^0.3.42",
     "standard-version": "^9.0.0",
@@ -48,18 +48,17 @@
     "@types/jest": "^26.0.7",
     "ts-jest": "^26.1.0",
     "@types/node": "^10.17.0",
-    "jsii": "^1.7.0",
-    "jsii-diff": "^1.7.0",
-    "jsii-pacmak": "^1.7.0",
+    "jsii": "^1.9.0",
+    "jsii-diff": "^1.9.0",
+    "jsii-pacmak": "^1.9.0",
     "jsii-docgen": "^1.3.2"
   },
   "peerDependencies": {
-    "constructs": "^2.0.2",
-    "cdk8s": "^0.0.0"
+    "cdk8s": "^0.0.0",
+    "constructs": "^3.0.4"
   },
   "dependencies": {
-    "minimatch": "^3.0.4",
-    "cdk8s": "^0.0.0"
+    "minimatch": "^3.0.4"
   },
   "bundledDependencies": [
     "minimatch"
diff --git a/packages/cdk8s-plus/src/config-map.ts b/packages/cdk8s-plus/src/config-map.ts
index 1d853209b..1d7242211 100644
--- a/packages/cdk8s-plus/src/config-map.ts
+++ b/packages/cdk8s-plus/src/config-map.ts
@@ -5,7 +5,7 @@ import * as cdk8s from 'cdk8s';
 import * as fs from 'fs';
 import * as path from 'path';
 import * as minimatch from 'minimatch';
-import { undefinedIfEmpty, lazy } from './utils';
+import { undefinedIfEmpty } from './utils';
 
 /**
  * Properties for initialization of `ConfigMap`.
@@ -68,8 +68,8 @@ export class ConfigMap extends Resource implements IConfigMap {
       metadata: props.metadata,
 
       // we need lazy here because we filter empty
-      data: lazy(() => this.synthesizeData()),
-      binaryData: lazy(() => this.synthesizeBinaryData()),
+      data: cdk8s.Lazy.any({ produce: () => this.synthesizeData() }),
+      binaryData: cdk8s.Lazy.any({ produce: () => this.synthesizeBinaryData() }),
     });
 
     for (const [k,v] of Object.entries(props.data ?? { })) {
diff --git a/packages/cdk8s-plus/src/deployment.ts b/packages/cdk8s-plus/src/deployment.ts
index 781bf3876..0c200d0e6 100644
--- a/packages/cdk8s-plus/src/deployment.ts
+++ b/packages/cdk8s-plus/src/deployment.ts
@@ -3,7 +3,6 @@ import { Construct, Node } from 'constructs';
 import { Service, ServiceType } from './service';
 import { Resource, ResourceProps } from './base';
 import * as cdk8s from 'cdk8s';
-import { lazy } from './utils';
 import { PodSpecDefinition, PodSpec } from './pod';
 import { ApiObjectMetadata, ApiObjectMetadataDefinition } from 'cdk8s';
 
@@ -85,7 +84,7 @@ export class Deployment extends Resource {
 
     this.apiObject = new k8s.Deployment(this, 'Pod', {
       metadata: props.metadata,
-      spec: lazy(() => this.spec._toKube(this)),
+      spec: cdk8s.Lazy.any({ produce: () => this.spec._toKube(this) }),
     });
   }
 
diff --git a/packages/cdk8s-plus/src/duration.ts b/packages/cdk8s-plus/src/duration.ts
index afc853072..decd399cd 100644
--- a/packages/cdk8s-plus/src/duration.ts
+++ b/packages/cdk8s-plus/src/duration.ts
@@ -1,12 +1,9 @@
-import { Token } from 'constructs';
-
 /**
  * Represents a length of time.
  *
  * The amount can be specified either as a literal value (e.g: `10`) which
- * cannot be negative, or as an unresolved number token.
+ * cannot be negative.
  *
- * When the amount is passed as a token, unit conversion is not possible.
  */
 export class Duration {
   /**
@@ -92,7 +89,7 @@ export class Duration {
   private readonly unit: TimeUnit;
 
   private constructor(amount: number, unit: TimeUnit) {
-    if (!Token.isUnresolved(amount) && amount < 0) {
+    if (amount < 0) {
       throw new Error(`Duration amounts cannot be negative. Received: ${amount}`);
     }
 
@@ -179,7 +176,6 @@ export class Duration {
    */
   public toHumanString(): string {
     if (this.amount === 0) { return fmtUnit(0, this.unit); }
-    if (Token.isUnresolved(this.amount)) { return `<token> ${this.unit.label}`; }
 
     let millis = convert(this.amount, this.unit, TimeUnit.Milliseconds, { integral: false });
     const parts = new Array<string>();
@@ -209,20 +205,6 @@ export class Duration {
     }
   }
 
-  /**
-   * Returns a string representation of this `Duration` that is also a Token that cannot be successfully resolved. This
-   * protects users against inadvertently stringifying a `Duration` object, when they should have called one of the
-   * `to*` methods instead.
-   */
-  public toString(): string {
-    return Token.asString(
-      () => {
-        throw new Error('Duration.toString() was used, but .toSeconds, .toMinutes or .toDays should have been called instead');
-      },
-      { displayHint: `${this.amount} ${this.unit.label}` },
-    );
-  }
-
   private fractionDuration(symbol: string, modulus: number, next: (amount: number) => Duration): string {
     if (this.amount < modulus) {
       return `${this.amount}${symbol}`;
@@ -270,9 +252,6 @@ function convert(amount: number, fromUnit: TimeUnit, toUnit: TimeUnit, { integra
   if (fromUnit.inMillis === toUnit.inMillis) { return amount; }
   const multiplier = fromUnit.inMillis / toUnit.inMillis;
 
-  if (Token.isUnresolved(amount)) {
-    throw new Error(`Unable to perform time unit conversion on un-resolved token ${amount}.`);
-  }
   const value = amount * multiplier;
   if (!Number.isInteger(value) && integral) {
     throw new Error(`'${amount} ${fromUnit}' cannot be converted into a whole number of ${toUnit}.`);
diff --git a/packages/cdk8s-plus/src/job.ts b/packages/cdk8s-plus/src/job.ts
index de94bc923..2e88f2eab 100644
--- a/packages/cdk8s-plus/src/job.ts
+++ b/packages/cdk8s-plus/src/job.ts
@@ -1,11 +1,11 @@
 import { Resource, ResourceProps } from './base';
 import { ApiObject, ApiObjectMetadata, ApiObjectMetadataDefinition } from 'cdk8s';
 import { Construct } from 'constructs';
+import * as cdk8s from 'cdk8s';
 
 import * as k8s from './imports/k8s';
 import { RestartPolicy, PodSpec, PodSpecDefinition } from './pod';
 import { Duration } from './duration';
-import { lazy } from './utils';
 
 
 /**
@@ -40,7 +40,7 @@ export class Job extends Resource {
 
     this.apiObject = new k8s.Job(this, 'Default', {
       metadata: props.metadata,
-      spec: lazy(() => this.spec._toKube()),
+      spec: cdk8s.Lazy.any({ produce: () => this.spec._toKube() }),
     });
   }
 }
diff --git a/packages/cdk8s-plus/src/pod.ts b/packages/cdk8s-plus/src/pod.ts
index 328185cc0..233894a1a 100644
--- a/packages/cdk8s-plus/src/pod.ts
+++ b/packages/cdk8s-plus/src/pod.ts
@@ -5,7 +5,6 @@ import * as cdk8s from 'cdk8s';
 import { IServiceAccount } from './service-account';
 import { Container } from './container';
 import { Volume } from './volume';
-import { lazy } from './utils';
 
 /**
  * Properties for initialization of `Pod`.
@@ -43,7 +42,7 @@ export class Pod extends Resource {
 
     this.apiObject = new k8s.Pod(this, 'Pod', {
       metadata: props.metadata,
-      spec: lazy(() => this.spec._toKube()),
+      spec: cdk8s.Lazy.any({ produce: () => this.spec._toKube() }),
     });
   }
 }
diff --git a/packages/cdk8s-plus/src/service-account.ts b/packages/cdk8s-plus/src/service-account.ts
index 4c5ed0537..61f83b8b7 100644
--- a/packages/cdk8s-plus/src/service-account.ts
+++ b/packages/cdk8s-plus/src/service-account.ts
@@ -3,7 +3,8 @@ import { Construct } from 'constructs';
 import * as k8s from './imports/k8s';
 import { ApiObject } from 'cdk8s';
 import { ISecret } from './secret';
-import { lazy, undefinedIfEmpty } from './utils';
+import * as cdk8s from 'cdk8s';
+import { undefinedIfEmpty } from './utils';
 
 
 /**
@@ -63,7 +64,7 @@ export class ServiceAccount extends Resource implements IServiceAccount {
 
     this.apiObject = new k8s.ServiceAccount(this, 'Resource', {
       metadata: props.metadata,
-      secrets: lazy(() => undefinedIfEmpty(this._secrets.map(s => ({ name: s.name })))),
+      secrets: cdk8s.Lazy.any({ produce: () => undefinedIfEmpty(this._secrets.map(s => ({ name: s.name }))) }),
     });
   }
 
diff --git a/packages/cdk8s-plus/src/service.ts b/packages/cdk8s-plus/src/service.ts
index b1cd95545..e25a0ecf6 100644
--- a/packages/cdk8s-plus/src/service.ts
+++ b/packages/cdk8s-plus/src/service.ts
@@ -2,7 +2,6 @@ import * as k8s from './imports/k8s';
 import { Construct } from 'constructs';
 import { ResourceProps, Resource } from './base';
 import * as cdk8s from 'cdk8s';
-import { lazy } from './utils';
 
 
 /**
@@ -91,7 +90,7 @@ export class Service extends Resource {
 
     this.apiObject = new k8s.Service(this, 'Pod', {
       metadata: props.metadata,
-      spec: lazy(() => this.spec._toKube()),
+      spec: cdk8s.Lazy.any({ produce: () => this.spec._toKube() }),
     });
   }
 
diff --git a/packages/cdk8s-plus/src/size.ts b/packages/cdk8s-plus/src/size.ts
index eee4a4dd4..3fdd060b1 100644
--- a/packages/cdk8s-plus/src/size.ts
+++ b/packages/cdk8s-plus/src/size.ts
@@ -1,10 +1,8 @@
-import { Token } from 'constructs';
-
 /**
  * Represents the amount of digital storage.
  *
  * The amount can be specified either as a literal value (e.g: `10`) which
- * cannot be negative, or as an unresolved number token.
+ * cannot be negative.
  *
  * When the amount is passed as a token, unit conversion is not possible.
  */
@@ -53,7 +51,7 @@ export class Size {
   private readonly unit: StorageUnit;
 
   private constructor(amount: number, unit: StorageUnit) {
-    if (!Token.isUnresolved(amount) && amount < 0) {
+    if (amount < 0) {
       throw new Error(`Storage amounts cannot be negative. Received: ${amount}`);
     }
     this.amount = amount;
@@ -140,9 +138,6 @@ class StorageUnit {
 function convert(amount: number, fromUnit: StorageUnit, toUnit: StorageUnit, options: SizeConversionOptions = {}) {
   const rounding = options.rounding ?? SizeRoundingBehavior.FAIL;
   if (fromUnit.inKibiBytes === toUnit.inKibiBytes) { return amount; }
-  if (Token.isUnresolved(amount)) {
-    throw new Error(`Unable to perform time unit conversion on un-resolved token ${amount}.`);
-  }
 
   const multiplier = fromUnit.inKibiBytes / toUnit.inKibiBytes;
   const value = amount * multiplier;
diff --git a/packages/cdk8s-plus/src/utils.ts b/packages/cdk8s-plus/src/utils.ts
index 0a0ad1e13..b5358d90f 100644
--- a/packages/cdk8s-plus/src/utils.ts
+++ b/packages/cdk8s-plus/src/utils.ts
@@ -1,10 +1,3 @@
-import { Lazy } from 'constructs';
-
-export function lazy<T>(producer: () => T): T {
-  return Lazy.anyValue({ produce: () => producer() }) as unknown as T;
-}
-
-
 export function undefinedIfEmpty<T>(obj: T): T | undefined {
   if (typeof(obj) === 'string' && obj === '') { return undefined; }
   if (Array.isArray(obj) && obj.length === 0) { return undefined; }
diff --git a/packages/cdk8s/.projenrc.js b/packages/cdk8s/.projenrc.js
index 83f04d776..79daece96 100644
--- a/packages/cdk8s/.projenrc.js
+++ b/packages/cdk8s/.projenrc.js
@@ -11,7 +11,7 @@ const project = new JsiiProject({
   // dependencies
   jsiiVersion: Semver.caret(common.versions.jsii),
   peerDependencies: {
-    "constructs": Semver.pinned(common.versions.constructs),
+    "constructs": Semver.caret(common.versions.constructs),
   },
   dependencies: {
     "follow-redirects": Semver.caret("1.11.0"),
diff --git a/packages/cdk8s/API.md b/packages/cdk8s/API.md
index 90c5da5b5..06181b7d6 100644
--- a/packages/cdk8s/API.md
+++ b/packages/cdk8s/API.md
@@ -9,6 +9,7 @@ Name|Description
 [App](#cdk8s-app)|Represents a cdk8s application.
 [Chart](#cdk8s-chart)|*No description*
 [Include](#cdk8s-include)|Reads a YAML manifest from a file or a URL and defines all resources as API objects within the defined scope.
+[Lazy](#cdk8s-lazy)|*No description*
 [Testing](#cdk8s-testing)|Testing utilities for cdk8s applications.
 [Yaml](#cdk8s-yaml)|YAML utilities.
 
@@ -24,6 +25,13 @@ Name|Description
 [IncludeOptions](#cdk8s-includeoptions)|*No description*
 
 
+**Interfaces**
+
+Name|Description
+----|-----------
+[IAnyProducer](#cdk8s-ianyproducer)|*No description*
+
+
 
 ## class ApiObject 🔹 <a id="cdk8s-apiobject"></a>
 
@@ -370,6 +378,41 @@ new Include(scope: Construct, name: string, options: IncludeOptions)
 
 
 
+## class Lazy 🔹 <a id="cdk8s-lazy"></a>
+
+
+
+
+### Methods
+
+
+#### produce()🔹 <a id="cdk8s-lazy-produce"></a>
+
+
+
+```ts
+produce(): any
+```
+
+
+__Returns__:
+* <code>any</code>
+
+#### *static* any(producer)🔹 <a id="cdk8s-lazy-any"></a>
+
+
+
+```ts
+static any(producer: IAnyProducer): any
+```
+
+* **producer** (<code>[IAnyProducer](#cdk8s-ianyproducer)</code>)  *No description*
+
+__Returns__:
+* <code>any</code>
+
+
+
 ## class Testing 🔹 <a id="cdk8s-testing"></a>
 
 Testing utilities for cdk8s applications.
@@ -526,6 +569,27 @@ Name | Type | Description
 
 
 
+## interface IAnyProducer 🔹 <a id="cdk8s-ianyproducer"></a>
+
+
+
+### Methods
+
+
+#### produce()🔹 <a id="cdk8s-ianyproducer-produce"></a>
+
+
+
+```ts
+produce(): any
+```
+
+
+__Returns__:
+* <code>any</code>
+
+
+
 ## struct IncludeOptions 🔹 <a id="cdk8s-includeoptions"></a>
 
 
diff --git a/packages/cdk8s/package.json b/packages/cdk8s/package.json
index 1bb876538..8fd8dc74f 100644
--- a/packages/cdk8s/package.json
+++ b/packages/cdk8s/package.json
@@ -31,7 +31,7 @@
     "organization": true
   },
   "devDependencies": {
-    "constructs": "^2.0.2",
+    "constructs": "^3.0.4",
     "@types/follow-redirects": "^1.8.0",
     "@types/json-stable-stringify": "^1.0.32",
     "@types/yaml": "^1.2.0",
@@ -50,13 +50,13 @@
     "@types/jest": "^26.0.7",
     "ts-jest": "^26.1.0",
     "@types/node": "^10.17.0",
-    "jsii": "^1.7.0",
-    "jsii-diff": "^1.7.0",
-    "jsii-pacmak": "^1.7.0",
+    "jsii": "^1.9.0",
+    "jsii-diff": "^1.9.0",
+    "jsii-pacmak": "^1.9.0",
     "jsii-docgen": "^1.3.2"
   },
   "peerDependencies": {
-    "constructs": "2.0.2"
+    "constructs": "^3.0.4"
   },
   "dependencies": {
     "follow-redirects": "^1.11.0",
diff --git a/packages/cdk8s/src/_tokens.ts b/packages/cdk8s/src/_tokens.ts
deleted file mode 100644
index 802a0f19f..000000000
--- a/packages/cdk8s/src/_tokens.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { Tokenization, DefaultTokenResolver, StringConcat, Construct } from 'constructs';
-
-const TOKEN_RESOLVER = new DefaultTokenResolver(new StringConcat());
-
-export function resolve<T>(scope: Construct, obj: T): T {
-  return Tokenization.resolve(obj, {
-    scope,
-    resolver: TOKEN_RESOLVER,
-  });
-}
\ No newline at end of file
diff --git a/packages/cdk8s/src/api-object.ts b/packages/cdk8s/src/api-object.ts
index 182371595..5a5fa35f1 100644
--- a/packages/cdk8s/src/api-object.ts
+++ b/packages/cdk8s/src/api-object.ts
@@ -1,7 +1,7 @@
 import { Construct, IConstruct, Node } from 'constructs';
 import { Chart } from './chart';
 import { sanitizeValue } from './_util';
-import { resolve } from './_tokens';
+import { resolve } from './lazy';
 import * as stringify from 'json-stable-stringify';
 import { ApiObjectMetadata, ApiObjectMetadataDefinition } from './metadata';
 
@@ -109,6 +109,6 @@ export class ApiObject extends Construct {
 
     // convert to "pure data" so, for example, when we convert to yaml these
     // references are not converted to anchors.
-    return JSON.parse(stringify(sanitizeValue(resolve(this, data))));
+    return JSON.parse(stringify(sanitizeValue(resolve(data))));
   }
 }
diff --git a/packages/cdk8s/src/index.ts b/packages/cdk8s/src/index.ts
index d6db37173..a90326dba 100644
--- a/packages/cdk8s/src/index.ts
+++ b/packages/cdk8s/src/index.ts
@@ -4,4 +4,5 @@ export * from './testing';
 export * from './app';
 export * from './include';
 export * from './yaml';
-export * from './metadata';
\ No newline at end of file
+export * from './metadata';
+export * from './lazy';
\ No newline at end of file
diff --git a/packages/cdk8s/src/lazy.ts b/packages/cdk8s/src/lazy.ts
new file mode 100644
index 000000000..c434b18ec
--- /dev/null
+++ b/packages/cdk8s/src/lazy.ts
@@ -0,0 +1,54 @@
+export class Lazy {
+
+  public static any(producer: IAnyProducer): any {
+    return new Lazy(producer) as unknown as any;
+  }
+
+  public produce(): any {
+    return this.producer.produce();
+  }
+
+  private constructor(private readonly producer: IAnyProducer) {}
+
+}
+
+export interface IAnyProducer {
+  produce(): any;
+}
+
+export function resolve(value: any): any {
+
+  if (value == null) {
+    return value;
+  }
+
+  // cdk8s token
+  if (value instanceof Lazy) {
+    const resolved = value.produce();
+    return resolve(resolved);
+  }
+
+  // implicit token as generated by the cdk8s-cli (e.g IntOrString)
+  if (typeof(value.resolve) === 'function') {
+    const resolved = value.resolve();
+    return resolve(resolved);
+  }
+
+  if (typeof(value) !== 'object') {
+    return value;
+  }
+
+  if (Array.isArray(value)) {
+    return value.map(x => resolve(x));
+  }
+
+  const result: any = {};
+
+  for (const [k,v] of Object.entries(value)) {
+    result[k] = resolve(v);
+  }
+
+  return result;
+
+}
+
diff --git a/packages/projen-common.js b/packages/projen-common.js
index 167d3f890..5dea3f208 100644
--- a/packages/projen-common.js
+++ b/packages/projen-common.js
@@ -1,6 +1,6 @@
 exports.versions = {
-  constructs: '2.0.2',
-  jsii: '1.7.0',
+  constructs: '3.0.4',
+  jsii: '1.9.0',
 };
 
 exports.options = {
@@ -10,6 +10,7 @@ exports.options = {
   authorOrganization: true,
   buildWorkflow: false,
   releaseWorkflow: false,
+  dependabot: false,
   mergify: false,
   compat: false,
   dependabot: false,
diff --git a/tools/align-version.js b/tools/align-version.js
index 7847b7220..5a07fae42 100755
--- a/tools/align-version.js
+++ b/tools/align-version.js
@@ -4,12 +4,13 @@
 //
 const fs = require('fs');
 const semver = require('semver');
+const path = require('path');
 
 const marker = require('./get-version-marker');
 const repoVersion = process.argv[2]
 const files = process.argv.splice(3);
 
-const preRelease = semver.prerelease(repoVersion) ? true : false
+const PRE_RELEASE = semver.prerelease(repoVersion) ? true : false
 
 for (const file of files) {
   const pkg = JSON.parse(fs.readFileSync(file).toString());
@@ -25,14 +26,29 @@ for (const file of files) {
   processSection(pkg.peerDependencies || { });
 
   console.error(`${file} => ${repoVersion}`);
-  fs.writeFileSync(file, JSON.stringify(pkg, undefined, 2));
+
+  const permissions = fs.statSync(file).mode;
+  try {
+    fs.writeFileSync(file, JSON.stringify(pkg, undefined, 2));
+  } catch (err) {
+    const isProjen = fs.existsSync(path.join(path.dirname(file), '.projenrc.js'));
+    if (isProjen && err.message.includes('permission denied')) {
+      // temporary change file permissions if projen
+      fs.chmodSync(file, '600');
+      fs.writeFileSync(file, JSON.stringify(pkg, undefined, 2));
+    } else {
+      throw err;
+    }
+  } finally {
+    fs.chmodSync(file, permissions)
+  }
 }
 
 function processSection(section) {
   for (const [ name, version ] of Object.entries(section)) {
     if (version === marker || version === '^' + marker) {
 
-      if (preRelease) {
+      if (PRE_RELEASE) {
         // pre-release doesn't work with caret dependencies.
         // so we forcefully use pinned versions.
         section[name] = repoVersion;
diff --git a/tools/pack.sh b/tools/pack.sh
new file mode 100755
index 000000000..999da4622
--- /dev/null
+++ b/tools/pack.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+set -euo pipefail
+repo_root=$(cd $(dirname $0)/.. && pwd)
+cd ${repo_root}
+
+echo "Cleaning dist directories..."
+rm -rf dist/
+rm -rf packages/cdk8s/dist
+rm -rf packages/cdk8s-plus/dist
+rm -rf packages/cdk8s-cli/dist
+
+echo "Packaging JSII modules..."
+jsii-pacmak -v -v packages/cdk8s packages/cdk8s-plus
+
+echo "Packaging CLI..."
+cd packages/cdk8s-cli
+yarn package
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index f1cea7fe8..102fc8ef9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2633,15 +2633,6 @@ codemaker@^0.22.0:
     decamelize "^1.2.0"
     fs-extra "^8.1.0"
 
-codemaker@^1.11.0:
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/codemaker/-/codemaker-1.11.0.tgz#4b63b5a04e1566b58fdd80583c383c061f2a8ce1"
-  integrity sha512-cBTHf17J9ukOqwmPFfU7VTqBsl/WLIHh2LQk4mTA8GQgeBSD9E5u52nqHCB3Ca5PY8vBol5ifgtuukJkHqlgqQ==
-  dependencies:
-    camelcase "^6.0.0"
-    decamelize "^4.0.0"
-    fs-extra "^9.0.1"
-
 codemaker@^1.12.0:
   version "1.12.0"
   resolved "https://registry.yarnpkg.com/codemaker/-/codemaker-1.12.0.tgz#4a6a5ec7b6c25a218790060fe547eda96af0e1a0"
@@ -2769,10 +2760,10 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0:
   resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
   integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=
 
-constructs@2.0.2, constructs@^2.0.2:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/constructs/-/constructs-2.0.2.tgz#a731a3bc7e1b7b71b6e8af25c6571cf8615000fb"
-  integrity sha512-I9sc+Nx72ZmTa+4gp8L6s7ELKO6x6AfUoZA/79Fpmq59TaTokdV+ZWrST/E4QH/At/5UuGbevGXeP7kErJlISA==
+constructs@^3.0.4:
+  version "3.0.4"
+  resolved "https://registry.yarnpkg.com/constructs/-/constructs-3.0.4.tgz#eb1ed5b80f6600b8d50de83971357ae0fe8e29a2"
+  integrity sha512-CDvg7gMjphE3DFX4pzkF6j73NREbR8npPFW8Mx/CLRnMR035+Y1o1HrXIsNSss/dq3ZUnNTU9jKyd3fL9EOlfw==
 
 contains-path@^0.1.0:
   version "0.1.0"
@@ -5881,14 +5872,14 @@ jsesc@^2.5.1:
   resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
   integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
 
-jsii-diff@^1.7.0:
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/jsii-diff/-/jsii-diff-1.11.0.tgz#b595cdee5289d359c61b3a1e75dd2e70942ab020"
-  integrity sha512-FQTPmSOV7Iok8gmq31dGSW6KclJ2YTi2TNHeuXTwESooZ9NO1XzpuGz0GvNX469ADBuVb4XrWNmJbd+lctdkdg==
+jsii-diff@^1.9.0:
+  version "1.12.0"
+  resolved "https://registry.yarnpkg.com/jsii-diff/-/jsii-diff-1.12.0.tgz#033f09d241c20a3e503815ce610eaab4d2f26084"
+  integrity sha512-0ny2T36hWzf3aVZqWCBy1pnIs69gpiO24EneEAPs20xLzmyU+MoHJlyM/4E2nsjGVn9+iXks4YmR5gx+Q2CeRg==
   dependencies:
-    "@jsii/spec" "^1.11.0"
+    "@jsii/spec" "^1.12.0"
     fs-extra "^9.0.1"
-    jsii-reflect "^1.11.0"
+    jsii-reflect "^1.12.0"
     log4js "^6.3.0"
     typescript "~3.9.7"
     yargs "^15.4.1"
@@ -5903,7 +5894,7 @@ jsii-docgen@^1.3.2:
     jsii-reflect "^1.9.0"
     yargs "^15.4.1"
 
-jsii-pacmak@^1.12.0:
+jsii-pacmak@^1.12.0, jsii-pacmak@^1.9.0:
   version "1.12.0"
   resolved "https://registry.yarnpkg.com/jsii-pacmak/-/jsii-pacmak-1.12.0.tgz#a3d7e1c0d649d53066a91044b319a1517e8c5481"
   integrity sha512-kSi447LpGZtEBqje13/vO7Kp6rnPGwWhYA/hK9gcS4L6+2DAktfQdiVd9Ff5c0iAzNqaHs3ouDcf0aitSK6GBg==
@@ -5921,25 +5912,18 @@ jsii-pacmak@^1.12.0:
     xmlbuilder "^15.1.1"
     yargs "^15.4.1"
 
-jsii-pacmak@^1.7.0:
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/jsii-pacmak/-/jsii-pacmak-1.11.0.tgz#2110764ed4f37192ba6fc3b3911b2869b59038fd"
-  integrity sha512-rfu13yMmL/KUv3MSaPyhOUvQ5RlOb8NJV/eM6wldJprySDef0sDYHoQJJPfhFtlwuAFmBPxefiXd0+FldLk7AQ==
+jsii-reflect@^1.12.0:
+  version "1.12.0"
+  resolved "https://registry.yarnpkg.com/jsii-reflect/-/jsii-reflect-1.12.0.tgz#e894a823e1abc7d4e0c61e7a8f8ff45f6757566a"
+  integrity sha512-wADLvHWARzV4tSYFwqO3FpUuYmhcwnJENppJ5UY9ONt1E/r5CtxBCxHChnEeMWywyAy+rhl3CXVyCfV0IoPj3g==
   dependencies:
-    "@jsii/spec" "^1.11.0"
-    clone "^2.1.2"
-    codemaker "^1.11.0"
-    commonmark "^0.29.1"
-    escape-string-regexp "^4.0.0"
+    "@jsii/spec" "^1.12.0"
+    colors "^1.4.0"
     fs-extra "^9.0.1"
-    jsii-reflect "^1.11.0"
-    jsii-rosetta "^1.11.0"
-    semver "^7.3.2"
-    spdx-license-list "^6.2.0"
-    xmlbuilder "^15.1.1"
+    oo-ascii-tree "^1.12.0"
     yargs "^15.4.1"
 
-jsii-reflect@^1.11.0, jsii-reflect@^1.9.0:
+jsii-reflect@^1.9.0:
   version "1.11.0"
   resolved "https://registry.yarnpkg.com/jsii-reflect/-/jsii-reflect-1.11.0.tgz#45739fcff6b6ff0a8675893c3285489b555d9d42"
   integrity sha512-XZTC5A66lT2rjAc3mKXzN6VnHA6JDOOespmhAlYxVg9Mo7u5lEl5nupoS7wBUvXHfINX8h+0XkmdCvZbMuKlQQ==
@@ -5950,34 +5934,11 @@ jsii-reflect@^1.11.0, jsii-reflect@^1.9.0:
     oo-ascii-tree "^1.11.0"
     yargs "^15.4.1"
 
-jsii-reflect@^1.12.0:
-  version "1.12.0"
-  resolved "https://registry.yarnpkg.com/jsii-reflect/-/jsii-reflect-1.12.0.tgz#e894a823e1abc7d4e0c61e7a8f8ff45f6757566a"
-  integrity sha512-wADLvHWARzV4tSYFwqO3FpUuYmhcwnJENppJ5UY9ONt1E/r5CtxBCxHChnEeMWywyAy+rhl3CXVyCfV0IoPj3g==
-  dependencies:
-    "@jsii/spec" "^1.12.0"
-    colors "^1.4.0"
-    fs-extra "^9.0.1"
-    oo-ascii-tree "^1.12.0"
-    yargs "^15.4.1"
-
 jsii-release@^0.1.9:
   version "0.1.9"
   resolved "https://registry.yarnpkg.com/jsii-release/-/jsii-release-0.1.9.tgz#da139e68da8841d3f8ed5c0c64301dc3c326363b"
   integrity sha512-aV6qHRjDr41ETEwtXm6cgxQ5rzbRdQ3iNvQ+gzayJT8Ke2UvRHrduY5XkdJ3ZZ5FWqRyxHpY/RCVW7DysT+9Xw==
 
-jsii-rosetta@^1.11.0:
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/jsii-rosetta/-/jsii-rosetta-1.11.0.tgz#73688c1106e811bdb30922439ee80e482ad2cfc9"
-  integrity sha512-TvWOu+GM5pumNb5U+oDtIBXwVEFfo1HrGCdvb5Y6ysakLtHN521m39/tt1JVITi8vz7PlEy5jEPKkHoeR9+lXw==
-  dependencies:
-    "@jsii/spec" "^1.11.0"
-    commonmark "^0.29.1"
-    fs-extra "^9.0.1"
-    typescript "~3.9.7"
-    xmldom "^0.3.0"
-    yargs "^15.4.1"
-
 jsii-rosetta@^1.12.0:
   version "1.12.0"
   resolved "https://registry.yarnpkg.com/jsii-rosetta/-/jsii-rosetta-1.12.0.tgz#75b4109fbc3aa6be52960f33c9e43dd943589ce3"
@@ -5991,9 +5952,9 @@ jsii-rosetta@^1.12.0:
     yargs "^15.4.1"
 
 jsii-srcmak@^0.1.36:
-  version "0.1.36"
-  resolved "https://registry.yarnpkg.com/jsii-srcmak/-/jsii-srcmak-0.1.36.tgz#b151939778dd845df78d1ad185f7f4f1c530f349"
-  integrity sha512-zQmEZpxB6LPYTZygUTo0M3YiuRlSRqz/EGJFszx7Gqs0XZ4UQSHjwxs04xqUqqUbMIuSzvqclWB1Uiv3WbspEg==
+  version "0.1.39"
+  resolved "https://registry.yarnpkg.com/jsii-srcmak/-/jsii-srcmak-0.1.39.tgz#e56defafe13a7ce46d744150858116641cd442f0"
+  integrity sha512-sbaUHM1EMZcsNNRhvokzIraLim0IMDbQeViBJDb3sj5GiX2HtJQqQPmbIwI2DTEkbrBFL7ZDBIRffJBZYdHClQ==
   dependencies:
     fs-extra "^9.0.1"
     jsii "^1.12.0"
@@ -6001,7 +5962,7 @@ jsii-srcmak@^0.1.36:
     ncp "^2.0.0"
     yargs "^15.4.1"
 
-jsii@^1.12.0:
+jsii@^1.12.0, jsii@^1.9.0:
   version "1.12.0"
   resolved "https://registry.yarnpkg.com/jsii/-/jsii-1.12.0.tgz#bb0558cbaa298e4a0cf82846dace2b4db67259b9"
   integrity sha512-IRTjtmNdsUVpb1uB6wP1GMtOYBhOouXfPLquurU+JvSauLFaTPX2piO4yV8xGKnoZwRwCK+QRKB/DPUkYlDQ9w==
@@ -6019,24 +5980,6 @@ jsii@^1.12.0:
     typescript "~3.9.7"
     yargs "^15.4.1"
 
-jsii@^1.7.0:
-  version "1.11.0"
-  resolved "https://registry.yarnpkg.com/jsii/-/jsii-1.11.0.tgz#104454263fa7a57a73977e27de06b0416c894b1f"
-  integrity sha512-5/YZPqpSoXSi6h1JLMv8fa4iIyGfL14Va5p1J2NXkB7cQj5gPbl8gvi0KJiqmQXyF7urczGJB8vzuU15FyCalg==
-  dependencies:
-    "@jsii/spec" "^1.11.0"
-    case "^1.6.3"
-    colors "^1.4.0"
-    deep-equal "^2.0.3"
-    fs-extra "^9.0.1"
-    log4js "^6.3.0"
-    semver "^7.3.2"
-    semver-intersect "^1.4.0"
-    sort-json "^2.0.0"
-    spdx-license-list "^6.2.0"
-    typescript "~3.9.7"
-    yargs "^15.4.1"
-
 json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"


Test patch:
diff --git a/packages/cdk8s-cli/test/import/__snapshots__/import-crd.test.ts.snap b/packages/cdk8s-cli/test/import/__snapshots__/import-crd.test.ts.snap
index a0dfc870c..abf03f130 100644
--- a/packages/cdk8s-cli/test/import/__snapshots__/import-crd.test.ts.snap
+++ b/packages/cdk8s-cli/test/import/__snapshots__/import-crd.test.ts.snap
@@ -10,7 +10,7 @@ Object {
   },
   "dependencies": Object {
     "cdk8s": "999.999.999",
-    "constructs": "2.0.2",
+    "constructs": "3.0.4",
   },
   "dependencyClosure": Object {
     "cdk8s": Object {
@@ -4075,7 +4075,7 @@ Object {
   },
   "dependencies": Object {
     "cdk8s": "999.999.999",
-    "constructs": "2.0.2",
+    "constructs": "3.0.4",
   },
   "dependencyClosure": Object {
     "cdk8s": Object {
@@ -16843,7 +16843,7 @@ Object {
   },
   "dependencies": Object {
     "cdk8s": "999.999.999",
-    "constructs": "2.0.2",
+    "constructs": "3.0.4",
   },
   "dependencyClosure": Object {
     "cdk8s": Object {
@@ -17086,7 +17086,7 @@ Object {
   },
   "dependencies": Object {
     "cdk8s": "999.999.999",
-    "constructs": "2.0.2",
+    "constructs": "3.0.4",
   },
   "dependencyClosure": Object {
     "cdk8s": Object {
@@ -17329,7 +17329,7 @@ Object {
   },
   "dependencies": Object {
     "cdk8s": "999.999.999",
-    "constructs": "2.0.2",
+    "constructs": "3.0.4",
   },
   "dependencyClosure": Object {
     "cdk8s": Object {
diff --git a/packages/cdk8s-cli/test/import/__snapshots__/import-k8s.test.ts.snap b/packages/cdk8s-cli/test/import/__snapshots__/import-k8s.test.ts.snap
index a77aa4a36..9e8dc73ae 100644
--- a/packages/cdk8s-cli/test/import/__snapshots__/import-k8s.test.ts.snap
+++ b/packages/cdk8s-cli/test/import/__snapshots__/import-k8s.test.ts.snap
@@ -10,7 +10,7 @@ Object {
   },
   "dependencies": Object {
     "cdk8s": "999.999.999",
-    "constructs": "2.0.2",
+    "constructs": "3.0.4",
   },
   "dependencyClosure": Object {
     "cdk8s": Object {
@@ -34985,7 +34985,7 @@ Object {
   },
   "dependencies": Object {
     "cdk8s": "999.999.999",
-    "constructs": "2.0.2",
+    "constructs": "3.0.4",
   },
   "dependencyClosure": Object {
     "cdk8s": Object {
@@ -70741,7 +70741,7 @@ Object {
   },
   "dependencies": Object {
     "cdk8s": "999.999.999",
-    "constructs": "2.0.2",
+    "constructs": "3.0.4",
   },
   "dependencyClosure": Object {
     "cdk8s": Object {
@@ -108019,7 +108019,7 @@ Object {
   },
   "dependencies": Object {
     "cdk8s": "999.999.999",
-    "constructs": "2.0.2",
+    "constructs": "3.0.4",
   },
   "dependencyClosure": Object {
     "cdk8s": Object {
diff --git a/packages/cdk8s-plus/test/duration.test.ts b/packages/cdk8s-plus/test/duration.test.ts
index 4df1c8555..d8c5210f7 100644
--- a/packages/cdk8s-plus/test/duration.test.ts
+++ b/packages/cdk8s-plus/test/duration.test.ts
@@ -1,5 +1,4 @@
 import { Duration } from '../src';
-import { Lazy } from 'constructs';
 
 test('negative amount', () => {
   expect(() => Duration.seconds(-1)).toThrow(/negative/);
@@ -90,7 +89,6 @@ test('parse', () => {
 
 test('to human string', () => {
   expect(Duration.minutes(0).toHumanString()).toBe('0 minutes');
-  expect(Duration.minutes(Lazy.numberValue({ produce: () => 5 })).toHumanString()).toBe('<token> minutes');
 
   expect(Duration.minutes(10).toHumanString()).toBe('10 minutes');
   expect(Duration.minutes(1).toHumanString()).toBe('1 minute');
diff --git a/packages/cdk8s/test/chart.test.ts b/packages/cdk8s/test/chart.test.ts
index 85bb8c0c2..71ef62074 100644
--- a/packages/cdk8s/test/chart.test.ts
+++ b/packages/cdk8s/test/chart.test.ts
@@ -1,5 +1,6 @@
 import { Chart, ApiObject, Testing } from '../src';
-import { Construct, Lazy, Node, Dependency } from 'constructs';
+import { Construct, Node, Dependency } from 'constructs';
+import { Lazy } from '../src/lazy';
 
 test('empty stack', () => {
   // GIVEN
@@ -42,7 +43,7 @@ test('tokens are resolved during synth', () => {
     kind: 'Resource1',
     apiVersion: 'v1',
     spec: {
-      foo: Lazy.numberValue({ produce: () => 123 }),
+      foo: Lazy.any({ produce: () => 123 }),
       implicitToken: createImplictToken({ foo: 'bar' }),
     },
   });
diff --git a/packages/cdk8s/test/tokens.test.ts b/packages/cdk8s/test/tokens.test.ts
index fbe11813e..c46f97c9d 100644
--- a/packages/cdk8s/test/tokens.test.ts
+++ b/packages/cdk8s/test/tokens.test.ts
@@ -1,24 +1,16 @@
-import { Lazy } from 'constructs';
-import { resolve } from '../src/_tokens';
-import { Testing } from '../src';
+import { ApiObject, Lazy, Testing } from '../src';
+import { resolve } from '../src/lazy';
+
 
 test('lazy', () => {
   // GIVEN
-  const app = Testing.app();
   const hello = {
-    number: Lazy.numberValue({ produce: () => 1234 }),
-    string: Lazy.stringValue({ produce: () => 'hello' }),
+    number: Lazy.any({ produce: () => 1234 }),
+    string: Lazy.any({ produce: () => 'hello' }),
     implicit: createImplictToken(908),
   };
 
-  // THEN
-  expect(hello).toStrictEqual({
-    number: -1.8881545897087498e+289,
-    string: '${Token[TOKEN.1]}',
-    implicit: { },
-  });
-
-  expect(resolve(app, hello)).toStrictEqual({
+  expect(resolve(hello)).toStrictEqual({
     number: 1234,
     string: 'hello',
     implicit: 908,
@@ -30,4 +22,38 @@ function createImplictToken(value: any) {
   const implicit = {};
   Object.defineProperty(implicit, 'resolve', { value: () => value });
   return implicit;
-}
\ No newline at end of file
+}
+
+test('does not resolve aws-cdk tokens', () => {
+
+  const chart = Testing.chart();
+
+  new ApiObject(chart, 'Pod', {
+    apiVersion: 'v1',
+    kind: 'Pod',
+    metadata: {
+      name: 'mypod',
+    },
+    spec: {
+      // this is how an aws-cdk token looks like in string form
+      bucketName: '${Token[TOKEN.61]}',
+      someLazyProperty: Lazy.any({ produce: () => 'lazyValue' }),
+    },
+  });
+
+  const manifest = chart.toJson();
+
+  expect(manifest).toEqual([{
+    apiVersion: 'v1',
+    kind: 'Pod',
+    metadata: {
+      name: 'mypod',
+    },
+    spec: {
+      // aws-cdk token left untouched on chart synth.
+      bucketName: '${Token[TOKEN.61]}',
+      someLazyProperty: 'lazyValue',
+    },
+  }]);
+
+});
\ No newline at end of file