Create 2 resource with for_each where one of resource 2 elements needs to refer to instance1

Hi,

I have 2 resources each created using “for_each” as shown below in a generic fashion.

Each of the instances of the 2nd resource has an element (of type string) whose value needs to be the full reference to one of the instances of resource 1.

The issue I face is that the reference needs to include a key surrounded with " " such as “key”. This is required for reference to be resolved and removing the quotes will fail to reference the instance with the specific key.

my current implementation does not seem to work as resource1_instance_ref is a string so it can’t contain another string to surround the resourec1 keys. I tired escapes but it does not help and it resulted in urlencoded value for " being passed to API.

I was wondering if there is a solution to this scenario?

resource “resource_type1” “type1_instances”
for_each = dataset1
element1a = …
element1b = …

}

resource “resource_type2” “type2_instances”
for_each = dataset2
resource1_instance_ref = resource_type1.type1_instances[“resource1_instance_key”]
element2a=…
element2b=…
}

where one of the elements of dataset2 is resource1_instance defined as a string.

variable “dataset2” {
type = map(object({
resource1_key = string
resource1_instance_ref = string

}))

Referring to this document, specifically the for_each part


I am interested to know know if it is possible to dynmically make reference and construct multiple adresses as opposed to hard-coding the “key” part.

Thanks

Hi @qjqdave1,

Unfortunately with your examples generalized this much I can’t understand exactly what you are asking. :confounded:

Would you be able to share a more complete version of what you’ve tried, and of exactly what error message Terraform produced when you tried it? Hopefully then I can see better what your goal is and what we can change in your configuration to meet that goal. Thanks!

Thanks you. i provide details from provider followed by by specific case
The “artifactory_single_replication_config” needs to be associated with an artifactory resource.

Terraform jfrog provider:

Create a replication between two artifactory local repositories

resource “artifactory_local_repository” “provider_test_source” {
key = “provider_test_source”
package_type = “maven”
}

resource “artifactory_local_repository” “provider_test_dest” {
key = “provider_test_dest”
package_type = “maven”
}

resource “” “foo-rep” {
repo_key = “{artifactorartifactory_single_replication_configy_local_repository.provider_test_source.key}" cron_exp = "0 0 * * * ?" enable_event_replication = true url = "{var.artifactory_url}”
username = “{var.artifactory_username}" password = "{var.artifactory_password}”
}

The key item is repo_key which works in this csse as it is a single instance and does not need a key surrounded by “” to dereference the

My example:
I would like to create multiple instances using for_each applied using replications_cofig data

replications_config -->
{
“replications_config”: {
“test-docker-repo”: {
“repo_key”: “artifactory_repository.docker-repos[test-docker-repo].key”,
“cron_exp”: “0 0 10 * * *”,
“enable_event_replication”: true,
“username”: “user”,
“password”: “passwd”,
},
“dev-docker-repo”: {
“repo_key”: “artifactory_repository.docker-repos[dev-docker-repo].key”,
“cron_exp”: “0 0 10 * * *”,
“enable_event_replication”: true,
“username”: “user”,
“password”: “passwd”,
},

}

}

resource “artifactory_single_replication_config” “pull-replications” {
for_each = var.replications_config

repo_key = each.value.repo_key
cron_exp = each.value.cron_exp
enable_event_replication = each.value.enable_event_replication
username = each.value.username
password = each.value.password
}

module.test_artifactory.artifactory_single_replication_config.pull-replications[“test-docker-repo”] will be created

  • resource “artifactory_single_replication_config” “pull-replications” {

    • cron_exp = “0 0 10 * * *”
    • enable_event_replication = true
    • enabled = (known after apply)
    • id = (known after apply)
    • password = (sensitive value)
    • repo_key = “artifactory_repository.docker-repos[test-docker-repo].key” <--------------

    }


Error: PUT https://…/artifactory/api/replications/artifactory_repository.docker-repos[test-docker-repo].key: 400 [{Status:400 Message:Could not find repository}]
… in resource “artifactory_single_replication_config” “pull-replications”:
resource “artifactory_single_replication_config” “pull-replications”

Test 2

If trying to use format to create repo_key using " ->
“key_template”: “artifactory_repository.docker-repos%s%s%s].key”,

results in
+ repo_key = “artifactory_repository.docker-repos[“test-docker-repo”].key”

and upon apply

PUT https://…/artifactory/api/replications/artifactory_repository.docker-repos%5B%22test-docker-repo%22%5D.key: 400 [{Status:400 Message:Could not find repository}]

due to url encoding.

Test 3

And if trying to format using “”" for formatting results in error
A comma is required to separate each
function argument from the next.

Is there a way to use for_each with the above resource.
Thanks

I replied to your query. Thanks.

Hi @qjqdave1,

Could you edit this comment to mark all of the code and console output parts as code, using the <> icon in the editor toolbar? Unfortunately right now the forum seems to think it’s normal text and so it’s interpreted a lot of your Terraform language syntax as formatting commands, and so I can’t read it all. :confounded:

Based on what I can read there, you’re going to have difficulty doing what you are doing. Your replications_config variable has attributes which contain Terraform variable/attribute names, but you can’t evaluate variable names which come from strings. What you are seeing is that the provider is being given the name of the variable, not its value.

The first thing you could do is to unquote the values you provide to repo_key in your replications_config object, so that they get evaluated instead of stored as strings. I suspect though that you need to reconsider the way you are doing this. Unfortunately wrapping everything in a module wouldn’t help, because for_each isn’t available for creating modules (yet).

Thanks. I realize for_each is not supported for modules and i am not using it. The for_each is used inside a module.

The first example i provided does not use [“key”] and that is the issue as referencing the specific instance referenced with the key value does not resolve the for-each instance intended. The user of “”, etc was just an attempt to try things out and see if it helps which did not.

Preformatted text[quote=“qjqdave1, post:3, topic:7881”]

Terraform jfrog provider:

Create a replication between two artifactory local repositories

resource “artifactory_local_repository” “provider_test_source” {
key = “provider_test_source”
package_type = “maven”
}

resource “artifactory_local_repository” “provider_test_dest” {
key = “provider_test_dest”
package_type = “maven”
}

resource “” “foo-rep” {
repo_key = “ artifactorartifactorysinglereplicationconfigylocalrepository.providertestsource.key"cronexp=“00∗∗∗?“enableeventreplication=trueurl=”{artifactorartifactory_single_replication_configy_local_repository.provider_test_source.key}” cron_exp = “0 0 * * * ?” enable_event_replication = true url = " {var.artifactory_url}”
username = “ var.artifactoryusername"password="{var.artifactory_username}" password = " {var.artifactory_password}”
}

The key item is repo_key which works in this csse as it is a single instance and does not need a key surrounded by “” to dereference the

My example:
I would like to create multiple instances using for_each applied using replications_cofig data

replications_config -->
{
“replications_config”: {
“test-docker-repo”: {
“repo_key”: “artifactory_repository.docker-repos[test-docker-repo].key”,
“cron_exp”: “0 0 10 * * *”,
“enable_event_replication”: true,
“username”: “user”,
“password”: “passwd”,
},
“dev-docker-repo”: {
“repo_key”: “artifactory_repository.docker-repos[dev-docker-repo].key”,
“cron_exp”: “0 0 10 * * *”,
“enable_event_replication”: true,
“username”: “user”,
“password”: “passwd”,
},

}

}

resource “artifactory_single_replication_config” “pull-replications” {
for_each = var.replications_config

repo_key = each.value.repo_key
cron_exp = each.value.cron_exp
enable_event_replication = each.value.enable_event_replication
username = each.value.username
password = each.value.password
}

module.test_artifactory.artifactory_single_replication_config.pull-replications[“test-docker-repo”] will be created

  • resource “artifactory_single_replication_config” “pull-replications” {
    • cron_exp = “0 0 10 * * *”
    • enable_event_replication = true
    • enabled = (known after apply)
    • id = (known after apply)
    • password = (sensitive value)
    • repo_key = “artifactory_repository.docker-repos[test-docker-repo].key” <--------------}


Error: PUT https://…/artifactory/api/replications/artifactory_repository.docker-repos[test-docker-repo].key: 400 [{Status:400 Message:Could not find repository}]
… in resource “artifactory_single_replication_config” “pull-replications”:
resource “artifactory_single_replication_config” “pull-replications”

Test 2

If trying to use format to create repo_key using " ->
“key_template”: “artifactory_repository.docker-repos%s%s%s].key”,

results in

  • repo_key = “artifactory_repository.docker-repos[“test-docker-repo”].key”

and upon apply

PUT https://…/artifactory/api/replications/artifactory_repository.docker-repos%5B%22test-docker-repo%22%5D.key: 400 [{Status:400 Message:Could not find repository}]

due to url encoding.

Test 3

And if trying to format using “”" for formatting results in error
A comma is required to separate each
function argument from the next.Preformatted text

Is there a way to use for_each with the above resource.
Thanks
[/quote]

indent preformatted text by 4 spaces

That is still almost unreadable…

It is first time i am using this so it seems it didn’t work. I am trying again. Thanks for your patience.

The question is if I want to create multiple instances of this resource using for_each

resource “artifactory_single_replication_config” “pull-replications” {
for_each = var.replications_config

**repo_key = each.value.repo_key**
cron_exp = each.value.cron_exp
enable_event_replication = each.value.enable_event_replication
username = each.value.username
password = each.value.password
}

Using data such as the following

replications_config -->
{
“replications_config”: {
“test-docker-repo”: {
“repo_key”: “artifactory_repository.docker-repos[**test-docker-repo**].key”,
“cron_exp”: “0 0 10 * * *”,
“enable_event_replication”: true,
“username”: “user”,
“password”: “passwd”,
},
“dev-docker-repo”: {
“repo_key”: “artifactory_repository.docker-repos[**dev-docker-repo**].key”,
“cron_exp”: “0 0 10 * * *”,
“enable_event_replication”: true,
“username”: “user”,
“password”: “passwd”,
},

where the repo_key is a reference to instances of another resource also created with for _each.

Since the dependent resource is itself created with for_each, it needs to be referenced with its key as [“key”] and not [key] as per Terraform documentation link I included earlier. It is not created with count so we can’t use count index to reference its instances.

if i don’t put the double-quotes in the repo_key value I get this error

Error: PUT https://…/artifactory/api/replications/artifactory_repository.docker-repos[test-docker-repo].key: 400 [{Status:400 Message:Could not find repository}]
… in resource “artifactory_single_replication_config” “pull-replications”:
resource “artifactory_single_replication_config” “pull-replications”

My question is how can I create my dataset to satisfy the double-quote requirement to be placed aruond the key. It seems in effect I need to have a substring defined within a string which won’t work.

I believe your first repo_key setting should be specified as:

"repo_key": artifactory_repository.docker-repos["**test-docker-repo**"].key

The double-quotes go around the value used to look up the resource, not the entire resource attribute.

I realize that and that is exactly the core of the problem. It is not possible to define what you mentioned in Terraform

“replications_config”: {
“test-docker-repo”: {
“repo_key”: artifactory_repository.docker-repos["test-docker-repo"].key,
“cron_exp”: “0 0 10 * * *”,
“enable_event_replication”: true,
“username”: “user”,
“password”: “passwd”,
},
“dev-docker-repo”: {
“repo_key”: artifactory_repository.docker-repos["dev-docker-repo"].key,
“cron_exp”: “0 0 10 * * *”,
“enable_event_replication”: true,
“username”: “user”,
“password”: “passwd”,
},

because the value for repo_key needs to be a string and the following is not a string

artifactory_repository.docker-repos['test-docker-repo"].key

The run will fail; Terraform has 3 primitive types (boolean, number and string). To reference the resource associated with repo_key in essence we need to say
repo_key = some_string
where some_string = some_chars"some_other_string"some_more_chars

It is a reference to a string attribute of a resource, but you are right because I don’t think it is evaluated at that point. You might be able to use the old interpolation syntax to force Terraform to evaluate the reference right there and turn it into a string, have you tried that?