Skip to content

Commit

Permalink
fix(lib): better error for uninitialized provider
Browse files Browse the repository at this point in the history
Fixes #822
  • Loading branch information
DanielMSchmidt committed Aug 9, 2021
1 parent 2baf75f commit 5f2d8f6
Show file tree
Hide file tree
Showing 38 changed files with 260 additions and 23 deletions.
1 change: 1 addition & 0 deletions examples/go/google/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func NewMyStack(scope constructs.Construct, id string) cdktf.TerraformStack {
Zone: jsii.String("us-west1"),
Project: jsii.String("dschmidt-cdk-test"),
})
local.NewLocalProvider(stack, jsii.String("local"), &local.LocalProviderConfig{})

sa := google.NewServiceAccount(stack, jsii.String("sa"), &google.ServiceAccountConfig{
AccountId: jsii.String("cluster-admin"),
Expand Down
6 changes: 5 additions & 1 deletion examples/typescript/backends/s3/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@ import {
S3Backend,
DataTerraformRemoteStateS3,
} from "cdktf";
import { DataAwsS3BucketObject } from "./.gen/providers/aws";
import { AwsProvider, DataAwsS3BucketObject } from "./.gen/providers/aws";

class MyStack extends TerraformStack {
constructor(scope: Construct, name: string) {
super(scope, name);

new AwsProvider(this, "aws", {
region: "eu-central-1",
});

// Only one backend is supported by Terraform

// S3 Backend - https://www.terraform.io/docs/backends/types/s3.html
Expand Down
38 changes: 37 additions & 1 deletion packages/cdktf/lib/terraform-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { Construct, IConstruct, ISynthesisSession, Node } from "constructs";
import { resolve } from "./_tokens";
import * as fs from "fs";
import * as path from "path";
import camelcase = require("camelcase"); // ES module interop

import { TerraformElement } from "./terraform-element";
import { deepMerge } from "./util";
import { TerraformProvider } from "./terraform-provider";
Expand All @@ -14,6 +16,9 @@ import { Manifest } from "./manifest";

const STACK_SYMBOL = Symbol.for("ckdtf/TerraformStack");

const pascalCase = (str: string) =>
camelcase(str.replace(/[-/]/g, "_"), { pascalCase: true });

export interface TerraformStackMetadata {
readonly stackName: string;
readonly version: string;
Expand Down Expand Up @@ -171,6 +176,34 @@ export class TerraformStack extends Construct {
return resolve(this, tf);
}

public validateTerraform(tfConfig: any): void {
// validate provider has been initialized
const requiredProviders = [
...new Set(
Object.keys({ ...tfConfig?.resource, ...tfConfig?.data }).map(
(providerName) => providerName.split("_")[0]
)
),
];

const providers = Object.keys(tfConfig?.provider || {});

const uninitializedProviders = requiredProviders.filter(
(reqProvider) =>
!providers.includes(reqProvider) && reqProvider !== "terraform" // e.g. terraform_remote_state
);

if (uninitializedProviders.length > 0) {
throw new Error(
`Validation failed: Could not find provider initialization for provider ${uninitializedProviders.join(
" & "
)}. Please initialize the provider(s) as ${uninitializedProviders
.map((p) => pascalCase(p + "Provider"))
.join(", ")} in the Stack ${Node.of(this).id}`
);
}
}

protected onSynthesize(session: ISynthesisSession) {
const manifest = session.manifest as Manifest;
const stackManifest = manifest.forStack(this);
Expand All @@ -181,9 +214,12 @@ export class TerraformStack extends Construct {
);
if (!fs.existsSync(workingDirectory)) fs.mkdirSync(workingDirectory);

const tfConfig = this.toTerraform();
this.validateTerraform(tfConfig);

fs.writeFileSync(
path.join(session.outdir, stackManifest.synthesizedStackPath),
JSON.stringify(this.toTerraform(), undefined, 2)
JSON.stringify(tfConfig, undefined, 2)
);
}
}
Expand Down
5 changes: 4 additions & 1 deletion packages/cdktf/lib/testing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ export class Testing {
* Returns the Terraform synthesized JSON.
*/
public static synth(stack: TerraformStack) {
return JSON.stringify(stack.toTerraform(), null, 2);
const tfConfig = stack.toTerraform();
stack.validateTerraform(tfConfig);

return JSON.stringify(tfConfig, null, 2);
}

/* istanbul ignore next */
Expand Down
13 changes: 9 additions & 4 deletions packages/cdktf/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,16 @@
},
"license": "MPL-2.0",
"devDependencies": {
"@types/camelcase": "^5.2.0",
"@types/jest": "^25.1.2",
"@types/node": "^14.0.26",
"@typescript-eslint/eslint-plugin": "^4.28.1",
"@typescript-eslint/parser": "^4.28.1",
"constructs": "^3.3.75",
"eslint": "^7.29.0",
"jest": "^26.6.3",
"jsii": "^1.29.0",
"jsii-pacmak": "^1.29.0",
"jest": "^26.6.3",
"json-schema-to-typescript": "^8.0.1",
"typescript": "^3.9.7"
},
Expand All @@ -98,11 +99,15 @@
]
},
"dependencies": {
"archiver": "5.3.0"
"archiver": "5.3.0",
"camelcase": "^6.2.0"
},
"bundledDependencies": ["archiver"],
"bundledDependencies": [
"archiver",
"camelcase"
],
"stability": "experimental",
"peerDependencies": {
"constructs": "^3.3.75"
}
}
}
30 changes: 30 additions & 0 deletions packages/cdktf/test/__snapshots__/data-source.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ exports[`dependent data source 1`] = `
\\"backend\\": \\"local\\"
}
},
\\"provider\\": {
\\"test\\": [
{}
]
},
\\"resource\\": {
\\"test_resource\\": {
\\"resource\\": {
Expand Down Expand Up @@ -49,6 +54,11 @@ exports[`minimal configuration 1`] = `
\\"backend\\": \\"local\\"
}
},
\\"provider\\": {
\\"test\\": [
{}
]
},
\\"data\\": {
\\"test_data_source\\": {
\\"test\\": {
Expand All @@ -73,6 +83,11 @@ exports[`with boolean map 1`] = `
\\"backend\\": \\"local\\"
}
},
\\"provider\\": {
\\"test\\": [
{}
]
},
\\"data\\": {
\\"test_data_source\\": {
\\"test\\": {
Expand Down Expand Up @@ -110,6 +125,11 @@ exports[`with complex computed list 1`] = `
\\"backend\\": \\"local\\"
}
},
\\"provider\\": {
\\"test\\": [
{}
]
},
\\"data\\": {
\\"test_data_source\\": {
\\"test\\": {
Expand Down Expand Up @@ -147,6 +167,11 @@ exports[`with number map 1`] = `
\\"backend\\": \\"local\\"
}
},
\\"provider\\": {
\\"test\\": [
{}
]
},
\\"data\\": {
\\"test_data_source\\": {
\\"test\\": {
Expand Down Expand Up @@ -184,6 +209,11 @@ exports[`with string map 1`] = `
\\"backend\\": \\"local\\"
}
},
\\"provider\\": {
\\"test\\": [
{}
]
},
\\"data\\": {
\\"test_data_source\\": {
\\"test\\": {
Expand Down
5 changes: 5 additions & 0 deletions packages/cdktf/test/__snapshots__/local.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ exports[`local reference 1`] = `
\\"backend\\": \\"local\\"
}
},
\\"provider\\": {
\\"test\\": [
{}
]
},
\\"locals\\": {
\\"resource_name\\": \\"my_resource\\"
},
Expand Down
5 changes: 5 additions & 0 deletions packages/cdktf/test/__snapshots__/output.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ exports[`dependent output 1`] = `
\\"backend\\": \\"local\\"
}
},
\\"provider\\": {
\\"test\\": [
{}
]
},
\\"resource\\": {
\\"test_resource\\": {
\\"weird-long-running-resource\\": {
Expand Down
5 changes: 5 additions & 0 deletions packages/cdktf/test/__snapshots__/remote-state.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,11 @@ exports[`s3 reference 1`] = `
\\"backend\\": \\"local\\"
}
},
\\"provider\\": {
\\"test\\": [
{}
]
},
\\"data\\": {
\\"terraform_remote_state\\": {
\\"remote\\": {
Expand Down
36 changes: 36 additions & 0 deletions packages/cdktf/test/__snapshots__/resource.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ exports[`dependent resource 1`] = `
\\"backend\\": \\"local\\"
}
},
\\"provider\\": {
\\"test\\": [
{}
]
},
\\"data\\": {
\\"test_data_source\\": {
\\"data_source\\": {
Expand Down Expand Up @@ -49,6 +54,11 @@ exports[`do not change capitalization of arbritary nested types 1`] = `
\\"backend\\": \\"local\\"
}
},
\\"provider\\": {
\\"test\\": [
{}
]
},
\\"resource\\": {
\\"test_resource\\": {
\\"test\\": {
Expand Down Expand Up @@ -77,6 +87,11 @@ exports[`do not change capitalization of tags 1`] = `
\\"backend\\": \\"local\\"
}
},
\\"provider\\": {
\\"test\\": [
{}
]
},
\\"resource\\": {
\\"test_resource\\": {
\\"test\\": {
Expand Down Expand Up @@ -105,6 +120,11 @@ exports[`minimal configuration 1`] = `
\\"backend\\": \\"local\\"
}
},
\\"provider\\": {
\\"test\\": [
{}
]
},
\\"resource\\": {
\\"test_resource\\": {
\\"test\\": {
Expand Down Expand Up @@ -163,6 +183,14 @@ exports[`serialize list interpolation 1`] = `
\\"backend\\": \\"local\\"
}
},
\\"provider\\": {
\\"test\\": [
{}
],
\\"other\\": [
{}
]
},
\\"resource\\": {
\\"test_resource\\": {
\\"test\\": {
Expand Down Expand Up @@ -199,6 +227,14 @@ exports[`with complex computed list 1`] = `
\\"backend\\": \\"local\\"
}
},
\\"provider\\": {
\\"test\\": [
{}
],
\\"other\\": [
{}
]
},
\\"resource\\": {
\\"other_test_resource\\": {
\\"othertest\\": {
Expand Down
4 changes: 2 additions & 2 deletions packages/cdktf/test/__snapshots__/stack.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ exports[`stack synthesis merges all elements into a single output 1`] = `
}
},
\\"provider\\": {
\\"test\\": [
\\"aws\\": [
{
\\"access_key\\": \\"foo\\"
}
Expand Down Expand Up @@ -110,7 +110,7 @@ exports[`stack synthesis no flags 1`] = `
}
},
\\"provider\\": {
\\"test\\": [
\\"aws\\": [
{
\\"access_key\\": \\"foo\\"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ exports[`depend on module 1`] = `
\\"backend\\": \\"local\\"
}
},
\\"provider\\": {
\\"test\\": [
{}
]
},
\\"module\\": {
\\"test\\": {
\\"source\\": \\"../foo\\",
Expand Down Expand Up @@ -263,6 +268,11 @@ exports[`reference module 1`] = `
\\"backend\\": \\"local\\"
}
},
\\"provider\\": {
\\"test\\": [
{}
]
},
\\"module\\": {
\\"test\\": {
\\"source\\": \\"../foo\\",
Expand Down Expand Up @@ -299,6 +309,11 @@ exports[`reference module list 1`] = `
\\"backend\\": \\"local\\"
}
},
\\"provider\\": {
\\"test\\": [
{}
]
},
\\"module\\": {
\\"test\\": {
\\"source\\": \\"../foo\\",
Expand Down
5 changes: 5 additions & 0 deletions packages/cdktf/test/__snapshots__/variable.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,11 @@ exports[`reference 1`] = `
\\"backend\\": \\"local\\"
}
},
\\"provider\\": {
\\"test\\": [
{}
]
},
\\"variable\\": {
\\"test-variable\\": {
\\"type\\": \\"string\\"
Expand Down
Loading

0 comments on commit 5f2d8f6

Please sign in to comment.