The problem in short:
The problem comes down to this: terraform plan creates data.archive_file resources, that are later used by terraform apply. If you do these two terraform commands in separate gitlab pipeline stages. The zip files generated in the plan stage, won't be available to the apply stage. Unless you add the output directory as an artifact
The longer version of the answer
If you are using multiple stages of the gitlab pipeline, one to plan, then one to apply. This is your problem.
The "dist" zip files are created during the plan stage, so you need to add the $PWD/dist as an artifact to your pipeline. Then in your apply stage, tell the pipeline it needs the plan stage, making the artifacts available to the apply command.
So in our pipeline, I had something like this:
plan_lambda:
stage: plan
needs:
- init_lambda
- validate_lambda
script:
- terraform -chdir=${PROJECT} plan -out=planfile ${args[@]}
artifacts:
paths:
- ${PROJECT}/planfile
# This is important, data.archive_file's are generated during plan stage, not apply, so these artifacts need to be stored
# https://github.com/hashicorp/terraform-provider-archive/issues/39#issuecomment-1013680518
- ${PWD}/dist
and then in the apply stage
apply_lambda:
stage: apply
when: manual
needs:
- init_lambda
- plan_lambda
- apply_execution_role
variables:
PROJECT: lambda
script:
- terraform -chdir=${PROJECT} apply -auto-approve planfile
and here, the generated dist zip files generated in the plan stage will be available to the apply stage and your problem should be fixed.
For extra information and the entire conversation that led me to this solution, here is the ticket in the terraform github repository:
https://github.com/hashicorp/terraform-provider-archive/issues/39#issuecomment-1013680518
What does "dist" or "dist zip" files mean?
Here is some terraform code which runs yarn to install node_modules and then packages up the source code into a zip file so you can deploy on AWS Lambda
resource "null_resource" "run_yarn" {
triggers = {
always_run = timestamp()
}
provisioner "local-exec" {
command = "yarn --cwd ${local.root_path}/app/src install"
}
}
data "archive_file" "app_src" {
depends_on = [null_resource.run_yarn]
type = "zip"
source_dir = "${local.root_path}/app/src"
output_path = "${local.root_path}/dist/app.zip"
}
So "dist" files, are the distributed zip files generated and uploaded to AWS Lambda