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 (this also occurs if I move index.js
to root and update my package.json
main):
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.json
in my zipped GCP function folder? - Do I have to include
node_modules
directly 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 TFE backend vs local backend resolve the .tfstate issue?
I’ve created an SO question here: node.js - Issues with using npm packages in Google Cloud Function - Stack Overflow
I’d greatly appreciate some help, and hope I provided good enough information! Thank you all!