Archiving files in terraform using fileset()

I have Lambda function below directory structure:

-src/
   --lambda/
      test.py
   --shared/
      constants.py
      utils.py
      exceptions.py
      random.py (do not want in lambda)
      something.py (do not want in lambda)
   --dummyjsons/
      <100 json files>

I am trying to deploy this to AWS using Terraform and I am trying to use archive_file to archive all of these files.

The data block in terraform currently looks like:

data "archive_file" "test"{
  type        = "zip"
  output_path = ".terrafrom/test.zip"

  source {
  content = file("src/lambda/test.py")
  filename = "test.py"
  }

  source {
  content = file("src/shared/constants.py")
  filename = "src/shared/constants.py"
  }

  source {
  content = file("src/shared/utils.py")
  filename = "src/shared/utils.py"
  }

  source {
  content = file("src/shared/exceptions.py")
  filename = "src/shared/exceptions.py"
  }

  # Include all dummyjsons
  for_each = fileset("src/dummyjsons", "*.json")
  source {
    content  = file("src/dummyjsons/${each.value}")
    filename = "src/dummyjsons/${each.value}"
  }
}

The lambda block looks like:

resource "aws_lambda_function" "test" {
  # Other attributes 

  filename = data.archive_file.test.output_path
  source_code_hash = data.archive_file.test.output_base64sha256

  # Other attributes
}

Attempt 1:

I got the below error upon trying the above code for lines filename and source_code_hash from lambda block:

│ Error: Missing resource instance key
│ Because data.archive_file.test has "for_each" set, its
│ attributes must be accessed on specific instances.
│ 
│ For example, to correlate with indices of a referring resource, use:
│     data.archive_file.test[each.key]

Attempt 2:

I updated my lambda terraform block to below:

resource "aws_lambda_function" "test" {
  # Other attributes 

  filename = data.archive_file.test[each.key].output_path
  source_code_hash = data.archive_file.test[each.key].output_base64sha256

  # Other attributes
}

And got the below error for the same lines:

│ Error: Reference to "each" in context without for_each
│ 
│ The "each" object can be used only in "module" or "resource" blocks, and
│ only when the "for_each" argument is set.

Do you know how else to make this work?

1

I’m assuming that your goal is to add each of the files matched by *.json under src/dummyjsons to your archive.

That means that you’d need to have one source block for each of those files. Your first attempt failed because you instead declared one entire archive_file per source file: if that had worked, the many separate instances of archive_file.test would have all tried to write to the same output file, with each write containing only one of the source files.

You can ask Terraform to dynamically generate zero or more nested source blocks using a dynamic block:

data "archive_file" "test"{
  type        = "zip"
  output_path = "${path.module}/test.zip"

  source {
    content  = file("${path.module}/src/lambda/test.py")
    filename = "test.py"
  }

  # (...and all of the other hard-coded ones...)

  # Include all dummyjsons
  dynamic "source" {
    for_each = fileset("${path.module}/src/dummyjsons", "*.json")
    content {
      content  = file("${path.module}/src/dummyjsons/${source.value}")
      filename = "src/dummyjsons/${source.value}"
    }
  }
}

Notice that the for_each argument is now inside the dynamic block, and so the repetition is limited only to that block. dynamic blocks are slightly different to resource-level for_each in that Terraform literally generates multiple separate source blocks based on the given specification, so from the perspective of the hashicorp/archive provider (which is the one implementing this archive_file data source) this is indistinguishable from you having written out multiple source blocks directly.

Because the dynamic block has a smaller scope than for_each directly inside your data block, you refer to the value of the current element using source.value instead of each.value. The “source” identifier there is named after the block type.

I think your biggest problem is the generation of the archive.

Consider the following folder structure inside a Terraform module named terra03:

Assuming that you want to create an archive with all .py and .json files, with the exception of random.py and something.py you can create the archive like this:

locals {
  files_path = "${path.module}/src"

  # Filter by .py and .json extension
  files_to_include = fileset(local.files_path, "**/*.{json,py}")

  # Exclude random.py and something.py files
  files_to_exclude = fileset(local.files_path, "**/{random,something}.py")

  archive_files = setsubtract(local.files_to_include, local.files_to_exclude)
}

data "archive_file" "test" {
  type        = "zip"
  output_path = "test.zip"

  dynamic "source" {
    for_each = local.archive_files
    content {
      filename = source.value
      content  = file("${local.files_path}/${source.value}")
    }
  }
}

output "files_to_include" {
  value       = local.archive_files
  description = "Files to be included in the archive"
}

output "files_to_exclude" {
  value       = local.files_to_exclude
  description = "Files to be excluded from the archive"
}

Running terraform plan:

data.archive_file.test: Reading...
data.archive_file.test: Read complete after 0s [id=9a6c88d83866aeea36d380a28dc5a1b6a0270690]

Changes to Outputs:
  + files_to_exclude = [
      + "shared/random.py",
      + "shared/something.py",
    ]
  + files_to_include = [
      + "dummyjsons/dummy01.json",
      + "dummyjsons/dummy02.json",
      + "dummyjsons/dummy03.json",
      + "dummyjsons/dummy04.json",
      + "lambda/test.py",
      + "shared/constants.py",
      + "shared/exceptions.py",
      + "shared/utils.py",
    ]

For more details see fileset function and dynamic blocks

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật