polo
polo

Reputation: 385

Terraform: using ${path.module} in a module does not point to module directory

I have a repo with my terraform module where i create a zip file using archive file which i then use as a filesource for a lambda

data "archive_file" "example" {
  type        = "zip"
  output_path = "./files/example.zip"

  source {
    content  = templatefile("${path.module}/files/example.py", {})
    filename = "example.py"
  }
}

resource "aws_lambda_function" "example_lambda" {
  filename         = data.archive_file.example.output_path
  source_code_hash = data.archive_file.example.output_base64sha256
  etc...
}

And in this repo example.py file exists and the file path is ./files/example.zip

Then in my project repo i call the module:

module "my_example_module" {
  source                         = "git::https://github.com/my-module-repo"
  project_name                   = var.project_name
  etc...
}

But when i try to apply this it will error saying it can't find the zip file but i think it is looking in my project's directory rather than the module's directory:

module.example.aws_lambda_function.example_lambda: Creating...

Error: reading ZIP file (./files/example.zip): open ./files/example.zip: no such file or directory

Is ${path.module} not correct to use here? How do i get the terraform apply to look in the module for the zip file?

I tried hard typing the path just to see if it would get past the error but don't think i was putting in the right path to a directory in a module - would it be like module.my_example_module../files/example.py?

EDIT

So i think i understand the problem a bit more now. I changed the code a bit so the output path uses path.module:

data "archive_file" "example" {
  type        = "zip"
  output_path = "${path.module}/files/example.zip"

  source {
    content  = templatefile("${path.module}/files/example.py", {})
    filename = "example.py"
  }
}

and now when i call the module in my project it is looking for the path: ".terraform/modules/my_example_module/files/example.zip" which is correct.

but then because the lambda function in the module is set to use the output_path from the data archive block it will also look in ".terraform/modules/my_example_module/files/example.zip" in the module repo which wouldn't exist (unless terraform just creates this these directories if they don't already exist?)

So now the question is, how do I:

My project file structure is:

project
│   README.md   
│
└───terraform
│   └───files
│       │   lambda.tf
│       │   main.tf
│       │   ...

Upvotes: 3

Views: 5058

Answers (2)

aazam
aazam

Reputation: 11

I used a pipeline for running the terraform plan and apply job with an approval gate and I was facing a similar issue.

this worked for me: https://github.com/hashicorp/terraform-provider-archive/issues/39#issuecomment-815021702

data "archive_file" "zip" {
  type        = "zip"
  source_file = "${path.module}/textfile.txt"
  output_path = "${path.module}/myfile-${random_string.r.result}.zip"
}

resource "random_string" "r" {
  length  = 16
  special = false
}

Upvotes: 1

polo
polo

Reputation: 385

Ok so it turned out that the reason was due to the fact I am running my terraform jobs via a pipeline and the plan and approve stages are separate jobs. Sorry i didn't include this information in original post but it didn't cross my mind at all that it was related to the pipeline

Archive provider will create the zip file at the plan stage for some reason and not apply and there for the zip file was not being passed between the jobs.

Here is the discussion for this problem and some workarounds included here: https://github.com/hashicorp/terraform-provider-archive/issues/39

Upvotes: 1

Related Questions