diff --git a/packages/@cdktf/hcl2cdk/lib/__tests__/expressionToTs.test.ts b/packages/@cdktf/hcl2cdk/lib/__tests__/expressionToTs.test.ts index 97d834282f..2dac3bfd72 100644 --- a/packages/@cdktf/hcl2cdk/lib/__tests__/expressionToTs.test.ts +++ b/packages/@cdktf/hcl2cdk/lib/__tests__/expressionToTs.test.ts @@ -420,7 +420,7 @@ describe("expressionToTs", () => { getType ); expect(code(result)).toMatchInlineSnapshot( - `"Token.asString(propertyAccess(foo, ["*", "id"]))"` + `"Token.asString(Fn.lookupNested(foo, ["*", "id"]))"` ); }); @@ -434,7 +434,7 @@ describe("expressionToTs", () => { getType ); expect(code(result)).toMatchInlineSnapshot( - `"Token.asString(propertyAccess(examplebucket.networkInterface, ["0", "access_config", "0", "assigned_nat_ip"]))"` + `"Token.asString(Fn.lookupNested(examplebucket.networkInterface, ["0", "access_config", "0", "assigned_nat_ip"]))"` ); }); @@ -448,7 +448,7 @@ describe("expressionToTs", () => { getType ); expect(code(result)).toMatchInlineSnapshot( - `"Token.asString(propertyAccess(examplebucket.networkInterface, ["0", "access_config", "0", "assigned_nat_ip"]))"` + `"Token.asString(Fn.lookupNested(examplebucket.networkInterface, ["0", "access_config", "0", "assigned_nat_ip"]))"` ); }); @@ -462,7 +462,7 @@ describe("expressionToTs", () => { getType ); expect(code(result)).toMatchInlineSnapshot( - `"Token.asString(propertyAccess(examplebucket.networkInterface, ["0", "access_config", "0", "assigned_nat_ip"]))"` + `"Token.asString(Fn.lookupNested(examplebucket.networkInterface, ["0", "access_config", "0", "assigned_nat_ip"]))"` ); }); @@ -475,7 +475,7 @@ describe("expressionToTs", () => { getType ); expect(code(result)).toMatchInlineSnapshot( - `"Token.asString(Fn.toset(propertyAccess(examplebucket, ["*"])))"` + `"Token.asString(Fn.toset(Fn.lookupNested(examplebucket, ["*"])))"` ); }); @@ -502,7 +502,7 @@ describe("expressionToTs", () => { getType ); expect(code(result)).toMatchInlineSnapshot( - `"Token.asString(propertyAccess(Fn.element(examplebucket, 0), ["id"]))"` + `"Token.asString(Fn.lookupNested(Fn.element(examplebucket, 0), ["id"]))"` ); }); @@ -515,7 +515,7 @@ describe("expressionToTs", () => { getType ); expect(code(result)).toMatchInlineSnapshot( - `"Token.asString(Fn.element(propertyAccess(examplebucket, ["*", "id"]), 0))"` + `"Token.asString(Fn.element(Fn.lookupNested(examplebucket, ["*", "id"]), 0))"` ); }); @@ -584,7 +584,7 @@ describe("expressionToTs", () => { getType ); expect(code(result)).toMatchInlineSnapshot( - `"Token.asString(propertyAccess(examplebucket, ["0", "id"]))"` + `"Token.asString(Fn.lookupNested(examplebucket, ["0", "id"]))"` ); }); @@ -646,7 +646,7 @@ describe("expressionToTs", () => { getType ); expect(code(result)).toMatchInlineSnapshot( - `"Token.asString(Fn.element(propertyAccess(test2.value, ["\\"val1\\""]), 0))"` + `"Token.asString(Fn.element(Fn.lookupNested(test2.value, ["\\"val1\\""]), 0))"` ); }); @@ -659,7 +659,7 @@ describe("expressionToTs", () => { getType ); expect(code(result)).toMatchInlineSnapshot( - `"Token.asString(Fn.flatten(propertyAccess(vnets.value, ["*", "subnets", "*", "name"])))"` + `"Token.asString(Fn.flatten(Fn.lookupNested(vnets.value, ["*", "subnets", "*", "name"])))"` ); }); @@ -677,7 +677,7 @@ describe("expressionToTs", () => { getType ); expect(code(result)).toMatchInlineSnapshot( - `""\${{ for vnet in \${" + propertyAccess(vnets.value, ["*"]) + "} : (vnet.vnet_name) => vnet.subnets[*].name}}""` + `""\${{ for vnet in \${" + Fn.lookupNested(vnets.value, ["*"]) + "} : (vnet.vnet_name) => vnet.subnets[*].name}}""` ); }); @@ -779,7 +779,7 @@ describe("expressionToTs", () => { getType ); expect(code(result)).toMatchInlineSnapshot( - `"Token.asString(Fn.join("-", Token.asList([propertyAccess(tags.value, ["app"]), propertyAccess(tags.value, ["env"])])))"` + `"Token.asString(Fn.join("-", Token.asList([Fn.lookupNested(tags.value, ["app"]), Fn.lookupNested(tags.value, ["env"])])))"` ); }); @@ -793,7 +793,7 @@ describe("expressionToTs", () => { getType ); expect(code(result)).toMatchInlineSnapshot( - `"Token.asString(Fn.join("-", Token.asList(Fn.concat([propertyAccess(tags.value, ["app"]), propertyAccess(tags.value, ["env"]), propertyAccess(tags.value, ["other"])]))))"` + `"Token.asString(Fn.join("-", Token.asList(Fn.concat([Fn.lookupNested(tags.value, ["app"]), Fn.lookupNested(tags.value, ["env"]), Fn.lookupNested(tags.value, ["other"])]))))"` ); }); @@ -845,7 +845,7 @@ describe("expressionToTs", () => { getType ); expect(code(result)).toMatchInlineSnapshot( - `"Token.asString(propertyAccess(myIterator.value, ["name"]))"` + `"Token.asString(Fn.lookupNested(myIterator.value, ["name"]))"` ); }); @@ -858,7 +858,7 @@ describe("expressionToTs", () => { getType ); expect(code(result)).toMatchInlineSnapshot( - `"Token.asString(propertyAccess(Fn.element(examplebucket, 0), ["id"]))"` + `"Token.asString(Fn.lookupNested(Fn.element(examplebucket, 0), ["id"]))"` ); }); @@ -873,7 +873,7 @@ describe("expressionToTs", () => { getType ); expect(code(result)).toMatchInlineSnapshot( - `"Token.asString(Fn.concat([propertyAccess(privateSubnets.value, ["*", "id"]), propertyAccess(publicSubnets.value, ["*", "id"])]))"` + `"Token.asString(Fn.concat([Fn.lookupNested(privateSubnets.value, ["*", "id"]), Fn.lookupNested(publicSubnets.value, ["*", "id"])]))"` ); }); @@ -1003,7 +1003,7 @@ EOF`; getType ); expect(code(result)).toMatchInlineSnapshot( - `"Token.asString(propertyAccess(changemeAzListEbsSnapshot.names, ["0"]))"` + `"Token.asString(Fn.lookupNested(changemeAzListEbsSnapshot.names, ["0"]))"` ); }); @@ -1019,7 +1019,7 @@ EOF`; getType ); expect(code(result)).toMatchInlineSnapshot( - `"Token.asString(propertyAccess(changemeAzListEbsSnapshot, ["testing_map", "foo"]))"` + `"Token.asString(Fn.lookupNested(changemeAzListEbsSnapshot, ["testing_map", "foo"]))"` ); }); @@ -1053,7 +1053,7 @@ EOF`; () => ["map", "string"] ); expect(code(result)).toMatchInlineSnapshot( - `"Token.asStringMap(propertyAccess(changemeExternalThumbprintData, ["result", "thumbprint"]))"` + `"Token.asStringMap(Fn.lookupNested(changemeExternalThumbprintData, ["result", "thumbprint"]))"` ); }); @@ -1069,7 +1069,7 @@ EOF`; () => "string" ); expect(code(result)).toMatchInlineSnapshot( - `"Token.asString(propertyAccess(examplebucket, ["foo", "bar"]))"` + `"Token.asString(Fn.lookupNested(examplebucket, ["foo", "bar"]))"` ); }); @@ -1086,7 +1086,7 @@ EOF`; () => "string" ); expect(code(result)).toMatchInlineSnapshot( - `"Token.asString(propertyAccess(defaultTags.value, ["project"])) + "-client-tg""` + `"Token.asString(Fn.lookupNested(defaultTags.value, ["project"])) + "-client-tg""` ); }); @@ -1115,7 +1115,7 @@ EOF`; getType ); expect(code(result)).toMatchInlineSnapshot( - `"Token.asString(propertyAccess(available.names, ["\${count.index}"]))"` + `"Token.asString(Fn.lookupNested(available.names, ["\${count.index}"]))"` ); }); diff --git a/packages/@cdktf/hcl2cdk/lib/__tests__/expressions.test.ts b/packages/@cdktf/hcl2cdk/lib/__tests__/expressions.test.ts index f786f323ab..da439f3502 100644 --- a/packages/@cdktf/hcl2cdk/lib/__tests__/expressions.test.ts +++ b/packages/@cdktf/hcl2cdk/lib/__tests__/expressions.test.ts @@ -513,7 +513,7 @@ describe("expressions", () => { it("should convert iterator value deep accessor", async () => { expect(await run('"${each.value.list.map.name}"')).toMatchInlineSnapshot( - `"propertyAccess(myIterator.value, ["list", "map", "name"]);"` + `"Fn.lookupNested(myIterator.value, ["list", "map", "name"]);"` ); }); @@ -521,7 +521,7 @@ describe("expressions", () => { expect( await run('"${each.value[0]["map"]["name"]}"') ).toMatchInlineSnapshot( - `"propertyAccess(myIterator.value, ["[0]", "[\\"map\\"]", "[\\"name\\"]"]);"` + `"Fn.lookupNested(myIterator.value, ["[0]", "[\\"map\\"]", "[\\"name\\"]"]);"` ); }); }); diff --git a/packages/@cdktf/hcl2cdk/lib/expressions.ts b/packages/@cdktf/hcl2cdk/lib/expressions.ts index 58593e9119..f2d97a6d42 100644 --- a/packages/@cdktf/hcl2cdk/lib/expressions.ts +++ b/packages/@cdktf/hcl2cdk/lib/expressions.ts @@ -260,10 +260,14 @@ function convertScopeTraversalExpressionToTs( if (segments.length > 2) { scope.importables.push({ - constructName: "propertyAccess", + constructName: "Fn", provider: "cdktf", }); - return t.callExpression(t.identifier("propertyAccess"), [ + const callee = t.memberExpression( + t.identifier("Fn"), + t.identifier("lookupNested") + ); + return t.callExpression(callee, [ variableAccessor, t.arrayExpression( segments.slice(2).map((s) => t.stringLiteral(s.segment)) @@ -340,10 +344,14 @@ function convertScopeTraversalExpressionToTs( } scope.importables.push({ - constructName: "propertyAccess", + constructName: "Fn", provider: "cdktf", }); - return t.callExpression(t.identifier("propertyAccess"), [ + const callee = t.memberExpression( + t.identifier("Fn"), + t.identifier("lookupNested") + ); + return t.callExpression(callee, [ ref, t.arrayExpression(nonRefSegments.map((s) => t.stringLiteral(s.segment))), ]); @@ -598,11 +606,14 @@ function convertIndexExpressionToTs( const keyExpression = convertTFExpressionAstToTs(scope, keyExpressionChild!); scope.importables.push({ - constructName: "propertyAccess", + constructName: "Fn", provider: "cdktf", }); - - return t.callExpression(t.identifier("propertyAccess"), [ + const callee = t.memberExpression( + t.identifier("Fn"), + t.identifier("lookupNested") + ); + return t.callExpression(callee, [ collectionExpression, t.arrayExpression([keyExpression]), ]); @@ -631,11 +642,15 @@ function convertSplatExpressionToTs( const segments = relativeExpression.split(/\.|\[|\]/).filter((s) => s); scope.importables.push({ - constructName: "propertyAccess", + constructName: "Fn", provider: "cdktf", }); + const callee = t.memberExpression( + t.identifier("Fn"), + t.identifier("lookupNested") + ); - return t.callExpression(t.identifier("propertyAccess"), [ + return t.callExpression(callee, [ sourceExpression, t.arrayExpression([ // we don't need to use the anonSymbolExpression here because @@ -708,11 +723,15 @@ function convertRelativeTraversalExpressionToTs( ); scope.importables.push({ - constructName: "propertyAccess", + constructName: "Fn", provider: "cdktf", }); + const callee = t.memberExpression( + t.identifier("Fn"), + t.identifier("lookupNested") + ); - return t.callExpression(t.identifier("propertyAccess"), [ + return t.callExpression(callee, [ source, t.arrayExpression(segments.map((s) => t.stringLiteral(s.segment))), ]); @@ -922,10 +941,14 @@ export function dynamicVariableToAst( ) { const segmentsAfterEachValue = segments.slice(2); scope.importables.push({ + constructName: "Fn", provider: "cdktf", - constructName: "propertyAccess", }); - return t.callExpression(t.identifier("propertyAccess"), [ + const callee = t.memberExpression( + t.identifier("Fn"), + t.identifier("lookupNested") + ); + return t.callExpression(callee, [ t.memberExpression(t.identifier(iteratorName), t.identifier("value")), t.arrayExpression( segmentsAfterEachValue.map((part) => { diff --git a/packages/@cdktf/hcl2cdk/test/__snapshots__/externals.test.ts.snap b/packages/@cdktf/hcl2cdk/test/__snapshots__/externals.test.ts.snap index 0071e0746f..6a6a490c41 100644 --- a/packages/@cdktf/hcl2cdk/test/__snapshots__/externals.test.ts.snap +++ b/packages/@cdktf/hcl2cdk/test/__snapshots__/externals.test.ts.snap @@ -6,7 +6,7 @@ import { VariableType, TerraformVariable, TerraformOutput, - propertyAccess, + Fn, TerraformStack, } from "cdktf"; /* @@ -29,7 +29,7 @@ class MyConvertedCode extends TerraformStack { program: ["\${path.module}/oidc_thumbprint.sh", fargateRegion.value], }); new TerraformOutput(this, "foo", { - value: propertyAccess(dataExternalThumbprint, ["result", "thumbprint"]), + value: Fn.lookupNested(dataExternalThumbprint, ["result", "thumbprint"]), }); } } diff --git a/packages/@cdktf/hcl2cdk/test/__snapshots__/iteration.test.ts.snap b/packages/@cdktf/hcl2cdk/test/__snapshots__/iteration.test.ts.snap index d2c6d12ca1..6b633c8c61 100644 --- a/packages/@cdktf/hcl2cdk/test/__snapshots__/iteration.test.ts.snap +++ b/packages/@cdktf/hcl2cdk/test/__snapshots__/iteration.test.ts.snap @@ -2,12 +2,7 @@ exports[`iteration complex for each loops snapshot typescript 1`] = ` "import { Construct } from "constructs"; -import { - Token, - TerraformIterator, - propertyAccess, - TerraformStack, -} from "cdktf"; +import { Token, TerraformIterator, Fn, TerraformStack } from "cdktf"; /* * Provider bindings are generated by running \`cdktf get\`. * See https://cdk.tf/provider-generation for more details. @@ -52,16 +47,16 @@ class MyConvertedCode extends TerraformStack { const awsRoute53RecordExample = new Route53Record(this, "example_3", { allowOverwrite: true, name: Token.asString( - propertyAccess(exampleForEachIterator.value, ["name"]) + Fn.lookupNested(exampleForEachIterator.value, ["name"]) ), records: [ Token.asString( - propertyAccess(exampleForEachIterator.value, ["record"]) + Fn.lookupNested(exampleForEachIterator.value, ["record"]) ), ], ttl: 60, type: Token.asString( - propertyAccess(exampleForEachIterator.value, ["type"]) + Fn.lookupNested(exampleForEachIterator.value, ["type"]) ), zoneId: Token.asString(dataAwsRoute53ZoneExample.zoneId), forEach: exampleForEachIterator, @@ -155,7 +150,7 @@ import { TerraformVariable, Token, TerraformIterator, - propertyAccess, + Fn, TerraformStack, } from "cdktf"; /* @@ -190,9 +185,9 @@ class MyConvertedCode extends TerraformStack { name: "tf-test-name", solutionStackName: "64bit Amazon Linux 2018.03 v2.11.4 running Go 1.12.6", setting: tfenvtestDynamicIterator0.dynamic({ - name: propertyAccess(tfenvtestDynamicIterator0.value, ['["name"]']), + name: Fn.lookupNested(tfenvtestDynamicIterator0.value, ['["name"]']), namespace: namespace.value, - value: propertyAccess(tfenvtestDynamicIterator0.value, ['["value"]']), + value: Fn.lookupNested(tfenvtestDynamicIterator0.value, ['["value"]']), }), }); } @@ -206,7 +201,7 @@ import { VariableType, TerraformVariable, TerraformCount, - propertyAccess, + Fn, Token, TerraformStack, } from "cdktf"; @@ -244,7 +239,7 @@ class MyConvertedCode extends TerraformStack { const publicCount = TerraformCount.of(publicSubnetCount.numberValue); new Subnet(this, "public", { availabilityZone: Token.asString( - propertyAccess(available.names, [publicCount.index]) + Fn.lookupNested(available.names, [publicCount.index]) ), cidrBlock: "10.0.1.0/24", vpcId: "10123", @@ -260,7 +255,6 @@ exports[`iteration for each on list using splat snapshot typescript 1`] = ` import { VariableType, TerraformVariable, - propertyAccess, Fn, Token, TerraformIterator, @@ -294,7 +288,7 @@ class MyConvertedCode extends TerraformStack { you should consider using a for loop. If you are looping over something only known to Terraform, e.g. a result of a data source you need to keep this like it is.*/ const examplebucketForEachIterator = TerraformIterator.fromList( - Token.asAny(Fn.toset(propertyAccess(buckets.value, ["*"]))) + Token.asAny(Fn.toset(Fn.lookupNested(buckets.value, ["*"]))) ); const examplebucket = new S3Bucket(this, "examplebucket", { acl: "private", @@ -306,7 +300,7 @@ class MyConvertedCode extends TerraformStack { you should consider using a for loop. If you are looping over something only known to Terraform, e.g. a result of a data source you need to keep this like it is.*/ const examplebucketObjectForEachIterator = TerraformIterator.fromList( - Token.asAny(Fn.toset(propertyAccess(examplebucket, ["*"]))) + Token.asAny(Fn.toset(Fn.lookupNested(examplebucket, ["*"]))) ); new S3BucketObject(this, "examplebucket_object", { bucket: examplebucketObjectForEachIterator.key, diff --git a/packages/@cdktf/hcl2cdk/test/__snapshots__/references.test.ts.snap b/packages/@cdktf/hcl2cdk/test/__snapshots__/references.test.ts.snap index 947869e9af..7f5d1fcb52 100644 --- a/packages/@cdktf/hcl2cdk/test/__snapshots__/references.test.ts.snap +++ b/packages/@cdktf/hcl2cdk/test/__snapshots__/references.test.ts.snap @@ -217,13 +217,7 @@ class MyConvertedCode extends TerraformStack { exports[`references resource references with HCL functions snapshot typescript 1`] = ` "import { Construct } from "constructs"; -import { - Token, - TerraformCount, - Fn, - propertyAccess, - TerraformStack, -} from "cdktf"; +import { Token, TerraformCount, Fn, TerraformStack } from "cdktf"; /* * Provider bindings are generated by running \`cdktf get\`. * See https://cdk.tf/provider-generation for more details. @@ -254,7 +248,7 @@ class MyConvertedCode extends TerraformStack { }); new S3BucketObject(this, "examplebucket_object", { bucket: Token.asString( - propertyAccess(Fn.element(examplebucket, 0), ["id"]) + Fn.lookupNested(Fn.element(examplebucket, 0), ["id"]) ), key: "someobject", kmsKeyId: examplekms.arn, @@ -271,7 +265,7 @@ import { VariableType, TerraformVariable, TerraformOutput, - propertyAccess, + Fn, TerraformStack, } from "cdktf"; class MyConvertedCode extends TerraformStack { @@ -299,7 +293,7 @@ class MyConvertedCode extends TerraformStack { ), }); new TerraformOutput(this, "values", { - value: propertyAccess(keyValuePairs.value, ["*", "bar"]), + value: Fn.lookupNested(keyValuePairs.value, ["*", "bar"]), }); } } @@ -341,7 +335,7 @@ exports[`references variables with maps need to use accessor syntax snapshot typ import { VariableType, TerraformVariable, - propertyAccess, + Fn, Token, TerraformStack, } from "cdktf"; @@ -371,7 +365,7 @@ class MyConvertedCode extends TerraformStack { new Eip(this, "nat", { tags: { Name: - Token.asString(propertyAccess(defaultTags.value, ["project"])) + + Token.asString(Fn.lookupNested(defaultTags.value, ["project"])) + "-nat-eip", }, vpc: true, diff --git a/packages/@cdktf/hcl2cdk/test/__snapshots__/resources.test.ts.snap b/packages/@cdktf/hcl2cdk/test/__snapshots__/resources.test.ts.snap index b5ccf9ea11..e7b8e35c03 100644 --- a/packages/@cdktf/hcl2cdk/test/__snapshots__/resources.test.ts.snap +++ b/packages/@cdktf/hcl2cdk/test/__snapshots__/resources.test.ts.snap @@ -2,7 +2,7 @@ exports[`resources access use fqn for data source snapshot typescript 1`] = ` "import { Construct } from "constructs"; -import { propertyAccess, Token, TerraformStack } from "cdktf"; +import { Fn, Token, TerraformStack } from "cdktf"; /* * Provider bindings are generated by running \`cdktf get\`. * See https://cdk.tf/provider-generation for more details. @@ -25,7 +25,7 @@ class MyConvertedCode extends TerraformStack { ); new EbsVolume(this, "changeme_ebs_volume_snapshot", { availabilityZone: Token.asString( - propertyAccess(changemeAzListEbsSnapshot.names, ["0"]) + Fn.lookupNested(changemeAzListEbsSnapshot.names, ["0"]) ), encrypted: false, size: 10, @@ -544,7 +544,6 @@ exports[`resources tricky to parse items snapshot typescript 1`] = ` import { VariableType, TerraformVariable, - propertyAccess, Fn, Token, TerraformSelf, @@ -572,8 +571,8 @@ class MyConvertedCode extends TerraformStack { Fn.join( "-", Token.asList([ - propertyAccess(tags.value, ["app"]), - propertyAccess(tags.value, ["env"]), + Fn.lookupNested(tags.value, ["app"]), + Fn.lookupNested(tags.value, ["env"]), ]) ) ), diff --git a/packages/@cdktf/hcl2cdk/test/__snapshots__/tfExpressions.test.ts.snap b/packages/@cdktf/hcl2cdk/test/__snapshots__/tfExpressions.test.ts.snap index 4b38dbd1fd..85106569dc 100644 --- a/packages/@cdktf/hcl2cdk/test/__snapshots__/tfExpressions.test.ts.snap +++ b/packages/@cdktf/hcl2cdk/test/__snapshots__/tfExpressions.test.ts.snap @@ -221,7 +221,7 @@ exports[`tfExpressions list access through square brackets snapshot typescript 1 import { VariableType, TerraformVariable, - propertyAccess, + Fn, Token, TerraformStack, } from "cdktf"; @@ -245,7 +245,7 @@ class MyConvertedCode extends TerraformStack { new S3Bucket(this, "examplebucket", { acl: "private", bucket: Token.asString( - propertyAccess(settings.value, ["0", '"bucket_name"']) + Fn.lookupNested(settings.value, ["0", '"bucket_name"']) ), }); } @@ -270,7 +270,7 @@ class MyConvertedCode extends TerraformStack { exports[`tfExpressions numeric property access snapshot typescript 1`] = ` "import { Construct } from "constructs"; -import { TerraformOutput, propertyAccess, TerraformStack } from "cdktf"; +import { TerraformOutput, Fn, TerraformStack } from "cdktf"; /* * Provider bindings are generated by running \`cdktf get\`. * See https://cdk.tf/provider-generation for more details. @@ -301,7 +301,7 @@ class MyConvertedCode extends TerraformStack { zone: "us-east1-b", }); new TerraformOutput(this, "public_ip", { - value: propertyAccess(example.networkInterface, [ + value: Fn.lookupNested(example.networkInterface, [ "0", "access_config", "0", @@ -313,12 +313,184 @@ class MyConvertedCode extends TerraformStack { " `; +exports[`tfExpressions property access in maps works snapshot csharp 1`] = ` +"using Constructs; +using HashiCorp.Cdktf; +/* + * Provider bindings are generated by running \`cdktf get\`. + * See https://cdk.tf/provider-generation for more details. + */ +using aws.Eip; +class MyConvertedCode : TerraformStack +{ + public MyConvertedCode(Construct scope, string name) : base(scope, name) + { + /*Terraform Variables are not always the best fit for getting inputs in the context of Terraform CDK. + You can read more about this at https://cdk.tf/variables*/ + var defaultTags = new TerraformVariable(this, "default_tags", new TerraformVariableConfig { + Default = new [] { new Dictionary { + { "project", "Learning Live with AWS & HashiCorp" } + } }, + Description = "Map of default tags to apply to resources", + Type = VariableType.Map(VariableType.STRING) + }); + new Eip(this, "nat", new EipConfig { + Tags = new Dictionary { + { "Name", Token.AsString(Fn.LookupNested(defaultTags.Value, new [] { "project" })) + "-nat-eip" } + }, + Vpc = true + }); + } +}" +`; + +exports[`tfExpressions property access in maps works snapshot go 1`] = ` +"import "github.com/aws/constructs-go/constructs" +import "github.com/hashicorp/terraform-cdk-go/cdktf" +/* + * Provider bindings are generated by running \`cdktf get\`. + * See https://cdk.tf/provider-generation for more details. + */ +import "cdk.tf/go/stack/generated/aws/eip" +type myConvertedCode struct { + terraformStack +} + +func newMyConvertedCode(scope construct, name *string) *myConvertedCode { + this := &myConvertedCode{} + newTerraformStack_Override(this, scope, name) + /*Terraform Variables are not always the best fit for getting inputs in the context of Terraform CDK. + You can read more about this at https://cdk.tf/variables*/ + defaultTags := cdktf.NewTerraformVariable(this, jsii.String("default_tags"), &TerraformVariableConfig{ + Default: []interface{}{ + map[string]*string{ + "project": jsii.String("Learning Live with AWS & HashiCorp"), + }, + }, + Description: jsii.String("Map of default tags to apply to resources"), + Type: cdktf.VariableType_Map(cdktf.VariableType_STRING()), + }) + genprovidersawseip.NewEip(this, jsii.String("nat"), &eipConfig{ + tags: map[string]*string{ + "Name": jsii.String(cdktf.Token_asString(cdktf.Fn_lookupNested(defaultTags.value, []interface{}{ + jsii.String("project"), + })) + "-nat-eip"), + }, + vpc: jsii.Boolean(true), + }) + return this +}" +`; + +exports[`tfExpressions property access in maps works snapshot java 1`] = ` +"import software.constructs.Construct; +import com.hashicorp.cdktf.VariableType; +import com.hashicorp.cdktf.TerraformVariable; +import com.hashicorp.cdktf.Fn; +import com.hashicorp.cdktf.Token; +import com.hashicorp.cdktf.TerraformStack; +/* + * Provider bindings are generated by running \`cdktf get\`. + * See https://cdk.tf/provider-generation for more details. + */ +import imports.aws.eip.Eip; +public class MyConvertedCode extends TerraformStack { + public MyConvertedCode(Construct scope, String name) { + super(scope, name); + /*Terraform Variables are not always the best fit for getting inputs in the context of Terraform CDK. + You can read more about this at https://cdk.tf/variables*/ + TerraformVariable defaultTags = TerraformVariable.Builder.create(this, "default_tags") + .default(List.of(Map.of( + "project", "Learning Live with AWS & HashiCorp"))) + .description("Map of default tags to apply to resources") + .type(VariableType.map(VariableType.STRING)) + .build(); + new Eip(this, "nat", new EipConfig() + .tags(Map.of( + "Name", Token.asString(Fn.lookupNested(defaultTags.getValue(), List.of("project"))) + "-nat-eip")) + .vpc(true) + ); + } +}" +`; + +exports[`tfExpressions property access in maps works snapshot python 1`] = ` +"from constructs import Construct +from cdktf import VariableType, TerraformVariable, Fn, Token, TerraformStack +# +# Provider bindings are generated by running \`cdktf get\`. +# See https://cdk.tf/provider-generation for more details. +# +from imports.aws.eip import Eip +class MyConvertedCode(TerraformStack): + def __init__(self, scope, name): + super().__init__(scope, name) + # Terraform Variables are not always the best fit for getting inputs in the context of Terraform CDK. + # You can read more about this at https://cdk.tf/variables + default_tags = TerraformVariable(self, "default_tags", + default=[{ + "project": "Learning Live with AWS & HashiCorp" + } + ], + description="Map of default tags to apply to resources", + type=VariableType.map(VariableType.STRING) + ) + Eip(self, "nat", + tags={ + "Name": + Token.as_string(Fn.lookup_nested(default_tags.value, ["project"])) + "-nat-eip" + }, + vpc=True + )" +`; + +exports[`tfExpressions property access in maps works snapshot typescript 1`] = ` +"import { Construct } from "constructs"; +import { + VariableType, + TerraformVariable, + Fn, + Token, + TerraformStack, +} from "cdktf"; +/* + * Provider bindings are generated by running \`cdktf get\`. + * See https://cdk.tf/provider-generation for more details. + */ +import { Eip } from "./.gen/providers/aws/eip"; +class MyConvertedCode extends TerraformStack { + constructor(scope: Construct, name: string) { + super(scope, name); + /*Terraform Variables are not always the best fit for getting inputs in the context of Terraform CDK. + You can read more about this at https://cdk.tf/variables*/ + const defaultTags = new TerraformVariable(this, "default_tags", { + default: [ + { + project: "Learning Live with AWS & HashiCorp", + }, + ], + description: "Map of default tags to apply to resources", + type: VariableType.map(VariableType.STRING), + }); + new Eip(this, "nat", { + tags: { + Name: + Token.asString(Fn.lookupNested(defaultTags.value, ["project"])) + + "-nat-eip", + }, + vpc: true, + }); + } +} +" +`; + exports[`tfExpressions property access through square brackets snapshot typescript 1`] = ` "import { Construct } from "constructs"; import { VariableType, TerraformVariable, - propertyAccess, + Fn, Token, TerraformStack, } from "cdktf"; @@ -341,7 +513,9 @@ class MyConvertedCode extends TerraformStack { }); new S3Bucket(this, "examplebucket", { acl: "private", - bucket: Token.asString(propertyAccess(settings.value, ['"bucket_name"'])), + bucket: Token.asString( + Fn.lookupNested(settings.value, ['"bucket_name"']) + ), }); } } diff --git a/packages/@cdktf/hcl2cdk/test/__snapshots__/typeCoercion.test.ts.snap b/packages/@cdktf/hcl2cdk/test/__snapshots__/typeCoercion.test.ts.snap index ad4caac757..9b71d3e4f4 100644 --- a/packages/@cdktf/hcl2cdk/test/__snapshots__/typeCoercion.test.ts.snap +++ b/packages/@cdktf/hcl2cdk/test/__snapshots__/typeCoercion.test.ts.snap @@ -35,7 +35,6 @@ exports[`type coercion expressions need to be coerced to required type snapshot import { VariableType, TerraformVariable, - propertyAccess, Fn, Token, TerraformStack, @@ -84,8 +83,8 @@ class MyConvertedCode extends TerraformStack { vpcConfig: { subnetIds: Token.asList( Fn.concat([ - propertyAccess(privateSubnets.value, ["*", "id"]), - propertyAccess(publicSubnets.value, ["*", "id"]), + Fn.lookupNested(privateSubnets.value, ["*", "id"]), + Fn.lookupNested(publicSubnets.value, ["*", "id"]), ]) ), }, @@ -142,7 +141,7 @@ import { TerraformVariable, Token, TerraformIterator, - propertyAccess, + Fn, TerraformStack, } from "cdktf"; /* @@ -174,7 +173,7 @@ class MyConvertedCode extends TerraformStack { TerraformIterator.fromList(Token.asAny(iamGroupsUsers.value)); new IamUserGroupMembership(this, "iam_user_group_membership_user_groups", { groups: Token.asList( - propertyAccess(iamUserGroupMembershipUserGroupsForEachIterator.value, [ + Fn.lookupNested(iamUserGroupMembershipUserGroupsForEachIterator.value, [ '["groups"]', ]) ), diff --git a/packages/@cdktf/hcl2cdk/test/__snapshots__/variables.test.ts.snap b/packages/@cdktf/hcl2cdk/test/__snapshots__/variables.test.ts.snap index c34bd19170..a3367c2963 100644 --- a/packages/@cdktf/hcl2cdk/test/__snapshots__/variables.test.ts.snap +++ b/packages/@cdktf/hcl2cdk/test/__snapshots__/variables.test.ts.snap @@ -31,7 +31,7 @@ exports[`variables complex type and default snapshot typescript 1`] = ` import { VariableType, TerraformVariable, - propertyAccess, + Fn, Token, TerraformStack, } from "cdktf"; @@ -66,7 +66,7 @@ class MyConvertedCode extends TerraformStack { new DataLocalFile(this, "foo", { filename: "./" + - Token.asString(propertyAccess(dockerPorts.value, ["0", "protocol"])) + + Token.asString(Fn.lookupNested(dockerPorts.value, ["0", "protocol"])) + ".img", }); } @@ -79,7 +79,7 @@ exports[`variables sensitive and required snapshot typescript 1`] = ` import { VariableType, TerraformVariable, - propertyAccess, + Fn, Token, TerraformStack, } from "cdktf"; @@ -106,7 +106,7 @@ class MyConvertedCode extends TerraformStack { new DataLocalFile(this, "foo", { filename: "./" + - Token.asString(propertyAccess(userInformation.value, ["name"])) + + Token.asString(Fn.lookupNested(userInformation.value, ["name"])) + ".img", }); } diff --git a/packages/@cdktf/hcl2cdk/test/tfExpressions.test.ts b/packages/@cdktf/hcl2cdk/test/tfExpressions.test.ts index 0359f7fd93..174d760f45 100644 --- a/packages/@cdktf/hcl2cdk/test/tfExpressions.test.ts +++ b/packages/@cdktf/hcl2cdk/test/tfExpressions.test.ts @@ -258,6 +258,32 @@ ITEM } ); + testCase.test( + "property access in maps works", + ` + variable "default_tags" { + type = map(string) + description = "Map of default tags to apply to resources" + default = { + project = "Learning Live with AWS & HashiCorp" + } + } + + resource "aws_eip" "nat" { + vpc = true + tags = { + "Name" = "\${var.default_tags.project}-nat-eip" + } + } + `, + [binding.aws], + Snapshot.yes_all_languages, + Synth.yes_but_only_typescript_right_now_because_it_breaks, + { + resources: [], + } + ); + testCase.test( "strings containing single outer quotes are supported", `