terraform-provider-artifactory: Not able to use artifactory_file data source as the input to a lambda

Describe the bug Artifactory provider not downloading file from artifactory upon correctly identifying it.

Requirements for and issue

  • A fully functioning terraform snippet that can be copy&pasted (no outside files or ENV vars unless that’s part of the issue)
  • Your version of artifactory (you can curl it at $host/artifactory/api/system/version
  • Your version of terraform

Expected behavior The data source should be accepted in the lambda resource.

Furthermore, I have checked the pipeline artifacts (Running in GitLab) and the package (.zip) cannot be found anywhere, which leads me to think it never got downloaded.

Additional context

  • Terraform version: 1.0.11
  • jfrog/artifactory v2.19.1
  • hashicorp/aws v4.1.0

Terraform code:

provider "artifactory" {
  url           = "https://artifactory.net/artifactory/"
  check_license = false
}

data "artifactory_file" "artifact" {
  repository     = "generic-local"
  path             = "/test/test.2070511.86d15eb7.zip"
  output_path = "${path.module}/source_classifier.zip"
}

resource "aws_lambda_function" "main" {
  function_name    = "test"
  role                 = aws_iam_role.lambda_role.arn
  handler          = "counter.handler"
  runtime          = "python3.8"
  filename         = data.artifactory_file.artifact.output_path
  source_code_hash = base64encode(data.artifactory_file.artifact.sha256)
  # source_code_hash = filebase64sha256(data.artifactory_file.artifact.output_path)
  memory_size      = 1024
  timeout          = 900
  architectures    = ["x86_64"]
  description      = ""
}

Error:

image

Looking at the .tfstate, I can see that this artifact was correctly located and information about it was fetched (redacted):

{
      "module": "module.service",
      "mode": "data",
      "type": "artifactory_file",
      "name": "artifact",
      "provider": "module.service.provider[\"registry.terraform.io/jfrog/artifactory\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "created": "2022-02-17T22:03:03.666Z",
            "created_by": "user",
            "download_uri": "https://artifactory.net/artifactory/test/test.2070511.86d15eb7.zip",
            "force_overwrite": false,
            "id": "https://artifactory.net/artifactory/test/test.2070511.86d15eb7.zip",
            "last_modified": "2022-02-17T22:03:03.632Z",
            "last_updated": "2022-02-17T22:03:03.667Z",
            "md5": "b08f1be060830908b46f5d4205d7a10e",
            "mimetype": "application/zip",
            "modified_by": "user",
            "output_path": "../../../source.zip",
            "path": "/test/test.2070511.86d15eb7.zip",
            "repository": "generic-local",
            "sha1": "a1e8907c72f9efb77f9578c76bff73cf62[549]()f41",
            "sha256": "11efb4a005ffa9c91c0c364d69a4b44e35e98d7403bb9c6167a274a2d603a13d",
            "size": 484
          },
          "sensitive_attributes": []
        }
      ]
    },

Additionally, I tried using the username and password attribute initially, and got the following:

image

Then attempted to simply use the api_key, but same error as above. Really confusing. Sourced from docs

What am I doing wrong?

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 16 (3 by maintainers)

Most upvoted comments

Hi everyone,

Interestingly, I’ve landed on the same problem with a similar scenario where we have nested child modules that are referenced in an intermediate and root module. I’m currently stumped as well because I can reproduce this locally where I get a similar error and issues described: image

Our workflow looks this like:

root/
├── (references intermediate module)
├── (deploys a slew of other resources)

intermediate/
├── (references child module)
├── (additional resources related to the functionality of the lambda)
└── (calls additional helper child modules for vpc details, etc)

child-module/
├── (near exact same implementation as the tf code above at its core)
└── (where the data resource is defined)

child-module.tf (snippet)
#--- Artifactory --------------------------------------------------------------
data "artifactory_file" "artifact" {
  count = module.this.enabled ? 1 : 0

  repository      = var.artifactory_repository
  path            = var.artifactory_path
  output_path     = "tmp/${basename(var.artifactory_path)}"
  force_overwrite = var.artifactory_force_overwrite
}

#--- Lambda ----------------------------------------------------------------
resource "aws_lambda_function" "default" {
  count = module.this.enabled ? 1 : 0

  function_name = module.this.id
  role          = var.lambda_iam_role_arn
  description   = local.description

  filename         = data.artifactory_file.artifact[0].output_path
  source_code_hash = filebase64sha256(data.artifactory_file.artifact[0].output_path)
#-- Settings -----------------------------------------------------------------
...

}

I can see the zip file is never downloaded locally. What’s interesting is that this only happens on clean runs (the state is clean and no .zip exists already). Whenever we run our tests for the first time from the root module. It isn’t to ever able to evaluate the data resource (artifactory_file) in the child module and download the zip. If the zip already exists, then it’s no problem. The issue is that it’ll never pass in the CICD the first time.

Also to add, because we have a toggle for most of our resources in tf with a count. If I specifically disable the child module to deploy the lambda and its resources for a first run without deploying/calling the child module, then toggle the child module to deploy. The entire TF plan and apply succeed and our tests pass, which feels like a dependency/timing issue. I’ve tried to add depends_on, waits, null triggers on the child module and within the intermediate modules and no luck.

A workaround is if I split up the child module and build the lambda resource in the intermediate module. I can have the artifactory data resource on the root level, and pass the path down to the intermediate which works fine, except we don’t have a reusable lambda child module 😭 …

Open to any thoughts, my next steps are to try using a curl to artifactory to rule out any provider/resource issues to grab the zip file in the child module. I’ve tested the child module by itself and nested and it’s behaving correctly… I still feel like it’s a dependency issue that I could be missing as we get into more nesting and toggles. 😞