Skip to content

Commit

Permalink
fix: Avoid unstable fqn for TerraformElements
Browse files Browse the repository at this point in the history
  • Loading branch information
x3cion committed May 6, 2022
1 parent cbd5215 commit 79369d6
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 45 deletions.
9 changes: 1 addition & 8 deletions packages/cdktf/lib/terraform-data-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,9 @@ export class TerraformDataSource
public count?: number;
public provider?: TerraformProvider;
public lifecycle?: TerraformResourceLifecycle;
public readonly fqn: string;

constructor(scope: Construct, id: string, config: TerraformResourceConfig) {
super(scope, id);
super(scope, id, `data.${config.terraformResourceType}`);

this.terraformResourceType = config.terraformResourceType;
this.terraformGeneratorMetadata = config.terraformGeneratorMetadata;
Expand All @@ -41,12 +40,6 @@ export class TerraformDataSource
this.count = config.count;
this.provider = config.provider;
this.lifecycle = config.lifecycle;
this.fqn = Token.asString(
ref(
`data.${this.terraformResourceType}.${this.friendlyUniqueId}`,
this.cdktfStack
)
);
}

public getStringAttribute(terraformAttribute: string) {
Expand Down
43 changes: 38 additions & 5 deletions packages/cdktf/lib/terraform-element.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { ok } from "assert";
import { Construct } from "constructs";
import { Token } from ".";
import { TerraformStack } from "./terraform-stack";
import { ref } from "./tfExpression";

export interface TerraformElementMetadata {
readonly path: string;
Expand All @@ -17,8 +19,14 @@ export class TerraformElement extends Construct {
*/
private _logicalIdOverride?: string;

constructor(scope: Construct, id: string) {
/**
* Type of this element, used for fqn
*/
private readonly _elementType?: string;

constructor(scope: Construct, id: string, elementType?: string) {
super(scope, id);
this._elementType = elementType;

if (Token.isUnresolved(id)) {
throw new Error(
Expand All @@ -38,26 +46,51 @@ export class TerraformElement extends Construct {
return {};
}

private _fqnToken?: string;

public get fqn() {
if (!this._fqnToken) {
ok(!!this._elementType, "Element type not set");
this._fqnToken = Token.asString(
ref(`${this._elementType}.${this.friendlyUniqueId}`, this.cdktfStack)
);
}
return this._fqnToken;
}

private _friendlyUniqueId?: string;

public get friendlyUniqueId() {
if (this._logicalIdOverride) {
return this._logicalIdOverride;
} else {
return this.cdktfStack.getLogicalId(this);
if (!this._friendlyUniqueId) {
if (this._logicalIdOverride) {
this._friendlyUniqueId = this._logicalIdOverride;
} else {
this._friendlyUniqueId = this.cdktfStack.getLogicalId(this);
}
}
return this._friendlyUniqueId;
}

/**
* Overrides the auto-generated logical ID with a specific ID.
* @param newLogicalId The new logical ID to use for this stack element.
*/
public overrideLogicalId(newLogicalId: string) {
ok(
!this._fqnToken,
"Logical ID may not be overriden once .fqn has been requested"
);
this._logicalIdOverride = newLogicalId;
}

/**
* Resets a previously passed logical Id to use the auto-generated logical id again
*/
public resetOverrideLogicalId() {
ok(
!this._fqnToken,
"Logical ID may not be overriden once .fqn has been requested"
);
this._logicalIdOverride = undefined;
}

Expand Down
6 changes: 1 addition & 5 deletions packages/cdktf/lib/terraform-local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,11 @@ export class TerraformLocal
implements ITerraformAddressable
{
private _expression: any;
public readonly fqn: string;

constructor(scope: Construct, id: string, expression: any) {
super(scope, id);
super(scope, id, "local");

this._expression = expression;
this.fqn = Token.asString(
ref(`local.${this.friendlyUniqueId}`, this.cdktfStack)
);
}

public set expression(value: any) {
Expand Down
7 changes: 1 addition & 6 deletions packages/cdktf/lib/terraform-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@ export abstract class TerraformModule
public readonly version?: string;
private _providers?: (TerraformProvider | TerraformModuleProvider)[];
public dependsOn?: string[];
public readonly fqn: string;

constructor(scope: Construct, id: string, options: TerraformModuleOptions) {
super(scope, id);
super(scope, id, "module");

if (options.source.startsWith("./") || options.source.startsWith("../")) {
// Create an asset for the local module for better TFC support
Expand All @@ -51,10 +50,6 @@ export abstract class TerraformModule
insideTfExpression(dependency.fqn)
);
}

this.fqn = Token.asString(
ref(`module.${this.friendlyUniqueId}`, this.cdktfStack)
);
}

// jsii can't handle abstract classes?
Expand Down
9 changes: 1 addition & 8 deletions packages/cdktf/lib/terraform-remote-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,14 @@ export abstract class TerraformRemoteState
implements ITerraformAddressable
{
public static readonly tfResourceType = "terraform_remote_state";
public readonly fqn: string;

constructor(
scope: Construct,
id: string,
private readonly backend: string,
private readonly config: DataTerraformRemoteStateConfig
) {
super(scope, id);
this.fqn = Token.asString(
ref(
`data.terraform_remote_state.${this.friendlyUniqueId}`,
this.cdktfStack
)
);
super(scope, id, "data.terraform_remote_state");
}

public getString(output: string): string {
Expand Down
9 changes: 1 addition & 8 deletions packages/cdktf/lib/terraform-resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,9 @@ export class TerraformResource
public count?: number;
public provider?: TerraformProvider;
public lifecycle?: TerraformResourceLifecycle;
public readonly fqn: string;

constructor(scope: Construct, id: string, config: TerraformResourceConfig) {
super(scope, id);
super(scope, id, config.terraformResourceType);

this.terraformResourceType = config.terraformResourceType;
this.terraformGeneratorMetadata = config.terraformGeneratorMetadata;
Expand All @@ -73,12 +72,6 @@ export class TerraformResource
this.count = config.count;
this.provider = config.provider;
this.lifecycle = config.lifecycle;
this.fqn = Token.asString(
ref(
`${this.terraformResourceType}.${this.friendlyUniqueId}`,
this.cdktfStack
)
);
}

public getStringAttribute(terraformAttribute: string) {
Expand Down
5 changes: 1 addition & 4 deletions packages/cdktf/lib/terraform-variable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,14 @@ export class TerraformVariable
public readonly sensitive?: boolean;
public readonly nullable?: boolean;

public readonly fqn: string;

constructor(scope: Construct, id: string, config: TerraformVariableConfig) {
super(scope, id);
super(scope, id, "var");

this.default = config.default;
this.description = config.description;
this.type = config.type;
this.sensitive = config.sensitive;
this.nullable = config.nullable;
this.fqn = Token.asString(this.interpolation());
}

public get stringValue(): string {
Expand Down
18 changes: 17 additions & 1 deletion packages/cdktf/test/resource.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Testing, TerraformStack } from "../lib";
import { Testing, TerraformStack, TerraformElement } from "../lib";
import { TestProvider, TestResource, OtherTestResource } from "./helper";
import { TestDataSource } from "./helper/data-source";
import { TerraformOutput } from "../lib/terraform-output";
Expand Down Expand Up @@ -69,6 +69,22 @@ test("resource fqn", () => {
);
});

test("fqn is stable", () => {
const app = Testing.app();
const stack = new TerraformStack(app, "test");

const elementWithFQN = new TerraformElement(stack, "test", "valid_type");
const fqn = elementWithFQN.fqn;
expect(elementWithFQN.fqn).toBe(fqn);

// May not override logical id after fqn has been requested
expect(() => elementWithFQN.overrideLogicalId("new-id")).toThrow();

const elementWithoutFQN = new TerraformElement(stack, "test2");
// May not request fqn on element without element type
expect(() => elementWithoutFQN.fqn).toThrow();
});

test("serialize list interpolation", () => {
const app = Testing.app();
const stack = new TerraformStack(app, "tests");
Expand Down

0 comments on commit 79369d6

Please sign in to comment.