Using a token within a terraform function (CDKTF)

I have the following CDKTF file in python with the following code

MODULE_PATH = Token.as_string("${path.module}")
# some code
"MetadataFile": Fn.file(f"${MODULE_PATH}/{xml_asset.path}"),

When this gets synthesize, it will produce the following tf.json

"MetadataFile": "${file(\"$${path.module}/assets/xml_asset/E474FA1A5F88681658D71508D6557A90/metadata.xml\")}"

Now, when trying to deploy terraform, it will complain that the path parameter for file is invalid. The main issue is that there is an extra $.

Using the following is a decent workaround

MODULE_PATH = Token.as_string("${path.module}")
# some code
"MetadataFile": f"${{file(\"{MODULE_PATH}/{xml_asset.path}\")}}",

It will produce the tf.json

"MetadataFile": "${file(\"${path.module}/assets/xml_asset/E474FA1A5F88681658D71508D6557A90/metadata.xml\")}"

which is correct and is able to be deployed.

I prefer the top method, it seems cleaner but I can’t make it work. Is there a way I can keep it clean and avoid writing terraform code inside my python?

If you are working on a CDKTF application, I think you would want to use an Asset instead of ${path.module} to include a file or directory. So assuming xml_asset is an asset you could do xml_asset.path and be done.

If you are trying to use the output of CDKTF as a module it’s a but harder. We have a special mechanic in place to escape ${ because we generally don’t treat the input as possible terraform code. This is triggered when you use Fn.file(...) , so you might be able to craft a string that looks like a terraform expression calling file instead, thereby getting around the restriction. That’s basically your workaround.

Thanks Daniel

The plan is to use this as a module so I won’t be able to just use Assets.

I just wanted to make sure there wasn’t something obvious or better that I was missing.