vmware / terraform-provider-vcd

Terraform VMware Cloud Director provider
https://www.terraform.io/docs/providers/vcd/
Mozilla Public License 2.0
146 stars 112 forks source link

data source vcd_catalog_access_control needed to share a catalog with more orgs #1209

Open carmine73 opened 5 months ago

carmine73 commented 5 months ago

Description

My use case is the following: I have a catalog shared to some orgs, I would like to share this catalog to more orgs.

I have a similar need for plugins, and I do:

## lookup plugin
data "vcd_ui_plugin" "my_plugin" {
  . . .
}

locals {
  org_ids = setunion(data.vcd_ui_plugin.my_plugin.tenant_ids, [data.vcd_org.org.id]) # new org added
}

## import plugin
import {
  to = vcd_ui_plugin.my_plugin
  id = local.my_plugin_id
}

# publish plugin
resource "vcd_ui_plugin" "bck_plugin" {
  . . .
  tenant_ids = local.org_ids # merge between current orgs list and org to add
}

Is there a way to do the same things with shared catalogs?

New or Affected Resource(s)

dataclouder commented 5 months ago

You don't need a data source to solve this problem.

I have a catalog shared to some orgs, I would like to share this catalog to more orgs.

Let's start with:

data "vcd_org" "org1" {
  name = var.org1
}

data "vcd_org" "org2" {
  name = var.org2
}

data "vcd_org" "org3" {
  name = var.org3
}

data "vcd_catalog" "cat1" {
  org  = var.org1
  name = var.catalog1
}

resource "vcd_catalog_access_control" "cat-ac" {
  catalog_id = data.vcd_catalog.cat1.id

  shared_with_everyone = false

  shared_with {
    org_id       = data.vcd_org.org2.id
    access_level = "ReadOnly"
  }
}

This code shares the catalog from org1 to org2. If we want to share it to org3 as well, we add it:

data "vcd_org" "org1" {
  name = var.org1
}

data "vcd_org" "org2" {
  name = var.org2
}

data "vcd_org" "org3" {
  name = var.org3
}

data "vcd_catalog" "cat1" {
  org  = var.org1
  name = var.catalog1
}

resource "vcd_catalog_access_control" "cat-ac" {
  catalog_id = data.vcd_catalog.cat1.id

  shared_with_everyone = false

  shared_with {
    org_id       = data.vcd_org.org2.id
    access_level = "ReadOnly"
  }
  shared_with {
    org_id       = data.vcd_org.org3.id
    access_level = "ReadOnly"
  }
}
carmine73 commented 5 months ago

How can I get the list of organizations with which the catalog is already shared? The catalog I working with has been created outside terraform

dataclouder commented 5 months ago

In your example you are using import. Using that syntax, you could generate the resource with its data, and then run it.

(remove the resource from the previous script)

#  import.tf
import {
  to = vcd_catalog_access_control.cat-ac
  id = "${var.org1}.${var.catalog1}"
}

then run:

$ terraform plan -generate-config-out=generated.tf

And the file generated.tf will have the resource with all the organizations it has been shared with.

Note that a data source would not make things clearer, as the internal data for the shared organizations is resolved with IDs.

# file generated.tf
# __generated__ by Terraform
# Please review these resources and move them into your main configuration files.

# __generated__ by Terraform from "*****.*****"
resource "vcd_catalog_access_control" "cat-ac" {
  catalog_id                     = "urn:vcloud:catalog:03f54fc1-5453-4dfc-a00f-3977bd60fbd3"
  everyone_access_level          = null
  org                            = "*****"
  read_only_shared_with_all_orgs = false
  shared_with_everyone           = false
  shared_with {
    access_level = "ReadOnly"
    group_id     = null
    org_id       = "urn:vcloud:org:979f95cc-6a2c-44ef-9f43-ffce29ad7d74"
    user_id      = null
  }
  shared_with {
    access_level = "ReadOnly"
    group_id     = null
    org_id       = "urn:vcloud:org:f571ce05-d1bd-497f-9fbc-8ca3ae7155e0"
    user_id      = null
  }
}
carmine73 commented 5 months ago

thanks, I have to see if I can use this approach without manual editing tf files

Normally I do something like that:

  dynamic "shared_with" {
    for_each = local.list_orgs

    content {
      access_level = "ReadOnly"
      org_id       = shared_with.value.id
    }
  }

where local.list_orgs is a list/set I get using data source.

carmine73 commented 3 months ago

I found a way, but it's a bit tricky because I have to work with files instead of using Terraform. I don't agree with you when you say:

Note that a data source would not make things clearer, as the internal data for the shared organizations is resolved with IDs. because I can work with terraform function on collections:

new_orgs_with_shared_catalog = setunion(local.orgs_with_shared_catalog, [data.vcd_org.org.id])

Is there a reason why the data source vcd_catalog_access_control is missing?