hashicorp / terraform-cdk

Define infrastructure resources using programming constructs and provision them using HashiCorp Terraform
https://www.terraform.io/cdktf
Mozilla Public License 2.0
4.88k stars 454 forks source link

CDKTF paths: Fail to find the file because CDKTF takes another path into consideration #3755

Open LozanoMatheus opened 2 weeks ago

LozanoMatheus commented 2 weeks ago

Expected Behavior

I expected the CDKTF (Typescript) to use the current path to read the file. This is happening to any CDKTF thing, like TF functions (e.g. file, filemd5), AWS resources (e.g. aws_s3_object).

Instead of considering the current folder (./), it's considering a subfolder (./cdktf.out/stacks/myproject-dev). So, for me to read any files in the current folder (e.g. under the ./templates/), I would need to do ../../../templates/.

But, if I do this const filePath = path.resolve(file); and pass the filePath it will work fine because it will have the full path. So, only the TF stuff considers the path ./cdktf.out/stacks/<stackName>.

This issue took me a while to figure this out. I couldn't use the full path since I'm uploading a file to S3 and the state will change if I run from my machine vs a colleague's machine vs CI/CD pipelines. I could, of course, use the lifecycle ignore-changes, but it's just a workaround and I would rather not do it.

This behaviour doesn't happen on TF, only in CDKTF.

Actual Behavior

            │ Invalid value for "path" parameter: no file exists at
            │ "templates/my-template.json"; this function works only with
            │ files that are distributed as part of the configuration source code, so if
            │ this file will be created by a resource in this configuration you must
            │ instead obtain this result from an attribute of that resource.

Steps to Reproduce

import { Fn } from 'cdktf';

...

/*
The way to solve this is to go up three directories
const file = `../../../templates/my-template.json`;

IMO, doing like 'const filePath = path.resolve(file);' is just a terrible workaround as you'll also have to use ignoreChanges.
*/

const file = 'templates/my-template.json' // or const file = './templates/my-template.json'
const etag = Fn.filemd5(file);

new S3Object(this, `s3-object-${file}`, {
        bucket: s3Created.id,
        key: file,
        source: file,
        etag,
        tags,
      });

Versions

cdktf debug
language: typescript
cdktf-cli: 0.20.8
node: v20.15.1
cdktf: 0.20.9
constructs: 10.3.0
jsii: null
terraform: 1.9.6
arch: x64
os: darwin 23.5.0
providers
@cdktf/provider-aws (PREBUILT)
        terraform provider version: 5.65.0
        prebuilt provider version: 19.33.0
        cdktf version: ^0.20.0

Providers

┌───────────────┬──────────────────┬─────────┬────────────┬─────────────────────┬─────────────────┐
│ Provider Name │ Provider Version │ CDKTF   │ Constraint │ Package Name        │ Package Version │
├───────────────┼──────────────────┼─────────┼────────────┼─────────────────────┼─────────────────┤
│ aws           │ 5.65.0           │ ^0.20.0 │            │ @cdktf/provider-aws │ 19.33.0         │
└───────────────┴──────────────────┴─────────┴────────────┴─────────────────────┴─────────────────┘

Gist

No response

Possible Solutions

No response

Workarounds

No response

Anything Else?

No response

References

Help Wanted

Community Note

DanielMSchmidt commented 1 week ago

This problem is why we introduced assets: https://developer.hashicorp.com/terraform/cdktf/concepts/assets They should help you with this 👍