I am currently working on deploying a Google Cloud Function and associated resources (bucket, archive, etc) using Terraform. Running my terraform commands from Git Bash on Windows 10 I have a good amount of Terraform and AWS experience, but GCP is new to me. I've written many AWS Lambdas using TFE, but it has been about 2.5 years since.
The GC Function is using Node.js and express, however I am having problems accessing express in my deployed function. I actually want to use TypeScript but after running into some issues I decided to create a simple bare bones function with just javascript. Once I figure this out I'll move to update it to TypeScript.
Project Structure:
.
├── terraform
│ ├── modules
│ │ └── function
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ ├── main.tf
│ ├── backend.tf
│ ├── outputs.tf
│ └── variables.tf
└── src
| └── index.js
└── package.json
└── node_modules
Relevant Terraform:
data "archive_file" "source" {
type = "zip"
source_dir = "../src" # Here is the potential issue
output_path = "/tmp/function-${local.timestamp}.zip"
}
Issues
When executing terraform apply in the root terraform directory, I get the following:
Error: Error waiting for Creating CloudFunctions Function: Error code 3, message: Function failed on loading user code. This is likely due to a bug in the user code.
And within the GCP Logs Explorer:
Provided module can't be loaded.
Did you list all required modules in the package.json ?
"Detailed stack trace: Error: Cannot find module 'express'"
Resolution Efforts
You can see above in my archive_file source_dir that I am pointing to the src folder containing my index.js.
After doing some digging, I've realized that because the package.json containing my express dependency is not in that src directory, but instead at project root, it does not get included in my zipped folder.
However, if I set the archive_file source_dir to the project root, terraform apply tries to read the produced terraform.tfstate file within the root terraform directory, and it gives me this error:
Error: error archiving directory: error reading file for archival: read C:\Users<user><proj>\test-project\terraform\terraform.tfstate: The process cannot access the file because another process has locked a portion of the file.
Questions
- How can I include npm dependencies that are in my
package.jsonin my zipped GCP function folder? - Do I have to include
node_modulesdirectly in the archive file? Or will the GC Function automatically recognize the package.json in the zipped dir, and install my dependencies? - Would using a GCP backend vs local backend resolve the .tfstate issue?
I'd greatly appreciate some help, and hope I provided good enough information! Thank you all!