Download local file from remote URL on apply and delete file on destroy

I need to download a lambda archive file from an URL before actual lambda resource is created and this file needs to be deleted when I run terraform destroy. Basically a local file resource created from a remote URL. I have it currently done using a null_resource and local-exec provisioner like below. But this doesn’t delete the file when i run terraform destroy. Is there a better way?

resource "null_resource" "lambda_jar" {
  triggers = {
    on_version_change = "${var.lambda_archive_version}"
  }

  provisioner "local-exec" {
    command = "curl -o lambda.jar ${var.server_url}/${var.lambda_archive_version}.jar"
  }
}

Hi @nytins,

Terraform isn’t really designed to work generally with files on local disk. Sometimes we can make things work using e.g. the local_file resource and the http data source, but those answers don’t seem appropriate here because I assume your lambda.jar is a binary file and so loading it into memory as a Terraform string would not be possible, nor really desirable.

When I’ve seen Terraform configurations involving AWS Lambda before the common pattern I’ve seen is to place function artifacts directly into S3 as a result of whatever process is building them (outside of Terraform altogether) and then use Terraform only to tell AWS Lambda to fetch the source code from S3. That then avoids the need to use Terraform for software-build-related tasks that it isn’t really designed for.

However, if you have an unusual situation where the above design wouldn’t be appropriate then one direct solution I can offer you is a destroy-time provisioner, which will allow you to run a second local-exec when the null_resource resource instance is destroyed:

  provisioner "local-exec" {
    when    = destroy
    command = "rm lambda.jar"
  }

Provisioners are a last resort, so I wouldn’t recommend this approach if there were a more Terraform-native way to solve it, but in this case since you are doing something that is slightly outside of Terraform’s intended use-cases I think using a pair of provisioners is the best answer if you must do this within Terraform itself, rather than using another tool more suited to this sort of operation.