Search code examples
terraform

How to build a docker image in terraform only when the source files have changed


We have a way of doing this. But it always sees changes...

  dir_hash    = sha256(join("", [for f in fileset(path.root, "../modules/gcp_gke_cluster/files/email_sender/*") : filesha256(f) if basename(f) != ".DS_Store"]))

We generate that hash and use

resource "null_resource" "docker_build" {
  triggers = {
    dir_hash = local.dir_hash_cluster_notifications
  }

But the hash generated on our workstations (mac) is different than the ones generate in our ci/cd pipelines (linux).

Seems like the sha256 values can vary even from workstation to workstation depending on what is install according to my googling.

So is there a more reliable way to do this?


Solution

  • I recommend you to do some more output, to get details in what file(s) are causing the difference, code could be something like:

    locals {
      dir_hash = (
        {
          for f in fileset(path.root, "../*.tf") :
          f => filesha256(f)
        }
      )
    }
    
    output "test" {
      value = local.dir_hash
    }
    
    

    that will give us a break down of the files, in my case it looks like:

    Changes to Outputs:
      + test = {
          + "../acm.tf"                      = "be024388d7bfbb2fad05a9dd5b128f87a8a33eff3eb4d6a8d52f01031277ede4"
          + "../api_gateway.tf"              = "ea5144bb5ea6f3c99a015046e8189ff64928442caca3473a080027160dce5ce1"
          + "../certificate.tf"              = "ddcd505f62a06922db1711b1aaf60d9f057804de34825d122dfd09fa214b350d"
          + "../count_cannot_be_computed.tf" = "5e119c6a099ad21b704e3f657178214bdd41f31c61ca49db4af25e0350a345d0"
          + "../data.tf"                     = "889cbae409b4d0fb5888290a8d432d76a83bd4c341a7bbd017a2db2a465fcc74"
          + "../ebs.tf"                      = "d92b46555390914a5ee43a24492a15ee69936cca2d2e0ba674ef6aa4875ce564"
          + "../ec2_alpine.tf"               = "d5f8bddd81a9e042da68a61305aea7df9966d73245816e75733823ae2a7cf8c0"
          + "../ec2_amzn.tf"                 = "d84596bf6ed44ea2842fcaa4eb906fa88782064134620c353efb70a36739b40c"
          + "../ec2_suse.tf"                 = "a6396e711241a9e96d78e8043eaabdd8da43c28f02ea9c684fc2782b8ffe46c3"
          + "../ec2_ubuntu.tf"               = "e556fe6a98f9f24bf609c6a6b75a140a09b768e1b17b2b8c6e0bfc6f48cc2e42"
          + "../ec2_win.tf"                  = "60e948b1736871382a6a6d2ca194647cd074e07a3f94331547cff5f849f4ae50"
          + "../ec2_wordpress.tf"            = "8bc4019dfa5fc42085dfc392dbe416426b522d84b40c372b3f6b080b7300ad5f"
          + "../efs.tf"                      = "a666d055a9c26ab4269c66b62c3f0346fc10a9acaf7aa9f8cc8ffeb7fdeafc2e"
          + "../elb.tf"                      = "b020685ef7895db5e259da9c3e73610658120e2214cb362c8c05c6a829157d39"
          + "../example.tf"                  = "8a6f6e82c9abc3267b18e54eb4dd6f006ea513c41dcb6175d2603ff3960e40d9"
          + "../fargate_service.tf"          = "fdb70ea6c9d491f6e27364aa4d60f7173c1c13e2e55d8140a7468dc14e47b7fc"
          + "../inspector.tf"                = "ae59eb526122a8030a0ee03bfb219dbd64c57768d030e03da747c6feceb68dc6"
          + "../kms.tf"                      = "cbbc073e525a4c27a43cd38d4e1652674a12ff724cb2ef1e3eae4a7e90e7ae92"
          + "../lambda_function.tf"          = "de55466924c10f772d8cb5de88f611eb071e2b2c655f32a4ea8881b2f3d3aa41"
          + "../local_file.tf"               = "b8c9a3bdc25e96d5abc5e698af3b2cac56f796bd0ec2ad9c211499ad5ff134ab"
          + "../null_res.tf"                 = "fc0c2ec768cfa41a19f5b26928f04c4f23d17411fff152252942e9815886e352"
          + "../output.tf"                   = "c6aa022d66294d1ba0cab9d9dd553052e6786ff15e8a723a92d47a69c0828fa0"
          + "../s3.tf"                       = "1a268081029768971e31f795678aa17c139c713f8ba3c626f3f4de70b714aca9"
          + "../sg.tf"                       = "32ba82e3f184a5ed31900fcdb985e1e76f5aa2e8ee27e460a93e055f36bf153b"
          + "../template.tf"                 = "f0bf5c81d269c38d296e71d6a27f7224b4be133d78eef95fb737fd0a95901680"
          + "../variables.tf"                = "7fe638f0ea4e5a9165f71fd49abe3a4dcb5b4cc77d5e6578f01f7f235259ae27"
          + "../vpc.tf"                      = "88ab343e138fdc465f63985b0f84574c0a0996086fc2cb4c666338298a2510d5"
          + "../vpn.tf"                      = "0266ef4ca62e461209107af2957800b4f6fad7675a6c0e38f16c2aead0d9ea76"
        }
    

    hopefully it will be as easy as excepting a couple more files like you did for the ".DS_Store" worst case at least we will have more details on what is causing the difference

    Tests

    I tested on two machines that happen to have different version of terraform...
    The same results on both.

    Terraform v1.7.0
    on linux_amd64
    
    Terraform v1.6.2
    on darwin_amd64