Search code examples
terraformterraform-provider-gcp

Terraform: create data source when file is modified


I'm creating infrastructure on GCP via terraform. In this code, I'm creating zip of what's in src folder (currently just main.py), uploading it to Cloud Storage and updating Cloud Function with that zip.

In the src folder, there is code for Cloud Function. Terraform files are not within src folder (just to make it clear)

data "archive_file" "source" {
  type = "zip"
  source_dir = "./src"
  output_path = "./tmp/function.zip"
}


resource "google_storage_bucket" "function_bucket" {
    name = "${var.project_id}-function"
    location = var.location
}

resource "google_storage_bucket_object" "zip" {
    source = data.archive_file.source.output_path
    content_type = "application/zip"
    name = "src-${data.archive_file.source.output_md5}.zip"
    bucket = google_storage_bucket.function_bucket.name
    depends_on = [
        google_storage_bucket.function_bucket,
        data.archive_file.source
    ]
}

The thing is: each time I do any changes to other terraform files, terraform will create a new zip and update storage, bucket and function. (like, when I'm working with network or service accounts, it will still change the zip of that python code, that wasn't edited for weeks) I don't want it... Is there a way to only create this zip when anything in src folder gets updated?

What I want here is: if I do any change in src folder, when I update my main.py code, ONLY then create new zip, update bucket and upload it to function. Not when I do changes in tf files


Solution

  • I created a small example where the local resource is updated only when something is changed in the folder ./src (and in this case ${data.archive_file.source.output_sha} changes).

    File main.tf:

    resource "local_file" "foo" {
      content  = "${data.archive_file.source.output_sha}"
      filename = "my_file"
    }
    
    data "archive_file" "source" {
      type = "zip"
      source_dir = "./src"
      output_path = "./tmp/function.zip"
    }
    

    The variable ${data.archive_file.source.output_md5} should also do it but the issue with your code is in:

    depends_on = [
        google_storage_bucket.function_bucket,
        data.archive_file.source
    ]
    

    Since the local file ./tmp/function.zip (data.archive_file.source) always get updated, the resource "google_storage_bucket" "function_bucket" will get updated every time you run terraform apply.

    Removing data.archive_file.source from the depends_on list should solve the issue and make the resource dependent only on ${data.archive_file.source.output_md5} (as in my local file example).