Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for list of private_ip_address attributes on azurerm_private_endpoint resource #6571

Closed
markslater opened this issue Apr 21, 2020 · 13 comments · Fixed by #7246
Closed

Comments

@markslater
Copy link

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Description

The private endpoint for Azure Container Registry exposes two IP addresses, both of which are required for using ACR. The azurerm_private_endpoint should expose both, but right now, it only exposes the one, via private_ip_address.

New or Affected Resource(s)

  • azurerm_private_endpoint

Potential Terraform Configuration

resource "azurerm_resource_group" "example" {
  name     = "example-resources"
  location = "West Europe"
}

resource "azurerm_virtual_network" "example" {
  name                = "example-network"
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
}

resource "azurerm_subnet" "endpoint" {
  name                 = "endpoint"
  resource_group_name  = azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.example.name
  address_prefix       = "10.0.2.0/24"

  enforce_private_link_endpoint_network_policies = true
}

resource "azurerm_container_registry" "example" {
  name                     = "example-containerregistry"
  resource_group_name      = azurerm_resource_group.example.name
  location                 = azurerm_resource_group.example.location
  sku                      = "Premium"
  admin_enabled            = false
}

resource "azurerm_private_endpoint" "example" {
  name                = "example-endpoint"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  subnet_id           = azurerm_subnet.endpoint.id

  private_service_connection {
    name                           = "example-privateserviceconnection"
    private_connection_resource_id = azurerm_container_registry.example.id
    subresource_names              = ["registry"]
    is_manual_connection           = false
  }
}

output acr_data_private_ip {
  value = azurerm_private_endpoint.example.private_ip_address[0]
}

output acr_registry_private_ip {
  value = azurerm_private_endpoint.example.private_ip_address[1]
}

References

@poddm
Copy link

poddm commented May 15, 2020

Can this be expanded to include the data source azurerm_private_endpoint_connection?

@jeffddix
Copy link

There also needs to be a way to get what FQDN is associated with each ip address in the private endpoint. With Terraform I want to create a Private DNS Zone with a DNS entries for each of the ip addresses associated with the private endpoint. To do that, I need to know what DNS entry maps with each address.

Example: if I create the ACR called myregistry and a private endpoint to it with both in EastUS2, I would have a private IP address for myregistry.eastus2.data.privatelink.azurecr.io and myregistry.privatelink.azurecr.io.

@Dmitry1987
Copy link

I saw this option was merged in 2.1.0 but even in 2.9 it doesn't work, how come?

Error: Unsupported attribute

  on network-and-subnets.tf line 100, in output "postgres-private-endpoint":
 100:   value = azurerm_private_endpoint.postgresql.private_ip_address

This object has no argument, nested block, or exported attribute named
"private_ip_address".
##% terraform -version
Terraform v0.12.24
+ provider.azurerm v2.9.0

@Dmitry1987
Copy link

This MR was made to support that #5838
I wonder if each resource is different in terms of what you can get in attributes (storage/postgresql/docker registry/etc')

@arq-anthonyw
Copy link

arq-anthonyw commented Jun 10, 2020

Terraform v0.12.26
+ provider.azurerm v2.13.0

Yeah I saw in #5838 there should definetly be a private_ip_address attribute to reference but nope

Error: Unsupported attribute

  on private_link.tf line 26, in resource "azurerm_private_dns_a_record" "private_link":
  26:   records             = [azurerm_private_endpoint.this.private_ip_address]

This object has no argument, nested block, or exported attribute named
"private_ip_address".
resource "azurerm_private_endpoint" "this" {
  name                = "${lower(var.solution_name)}-endpoint"
  location            = azurerm_resource_group.this.location
  resource_group_name = azurerm_resource_group.this.name
  subnet_id           = azurerm_subnet.private_link_endpoint.id

  private_service_connection {
    name                           = "${lower(var.solution_name)}-privateserviceconnection"
    private_connection_resource_id = azurerm_mssql_server.this.id
    is_manual_connection           = false
    subresource_names              = ["sqlServer"]
  }
}

resource "azurerm_private_dns_zone" "private_link" {
  name                = "privatelink.database.windows.net"
  resource_group_name = azurerm_resource_group.this.name
}

resource "azurerm_private_dns_a_record" "private_link" {
  name                = azurerm_mssql_server.this.name
  zone_name           = azurerm_private_dns_zone.private_link.name
  resource_group_name = azurerm_resource_group.this.name
  ttl                 = 300
  records             = [azurerm_private_endpoint.this.private_ip_address]
}

@Dmitry1987
Copy link

I ended up just making a manual DNS record in the private zone for the IP address, after terraform completed the run. Don't have a way to reference it for now.

@arq-anthonyw
Copy link

arq-anthonyw commented Jun 11, 2020

I got around it by doing this

resource "azurerm_private_endpoint" "this" {
  name                = "${lower(var.solution_name)}-endpoint"
  location            = azurerm_resource_group.this.location
  resource_group_name = azurerm_resource_group.this.name
  subnet_id           = azurerm_subnet.private_link_endpoint.id

  private_service_connection {
    name                           = "${lower(var.solution_name)}-privateserviceconnection"
    private_connection_resource_id = azurerm_mssql_server.this.id
    is_manual_connection           = false
    subresource_names              = ["sqlServer"]
  }
}

resource "azurerm_private_dns_zone" "private_link" {
  name                = "privatelink.database.windows.net"
  resource_group_name = azurerm_resource_group.this.name
}

data "azurerm_private_endpoint_connection" "private_link" {
  name                = "${lower(var.solution_name)}-endpoint"
  resource_group_name = azurerm_resource_group.this.name
  depends_on          = [azurerm_private_endpoint.this]
}

# https://github.com/terraform-providers/terraform-provider-azurerm/issues/6571

resource "azurerm_private_dns_a_record" "private_link" {
  depends_on          = [data.azurerm_private_endpoint_connection.private_link]
  name                = azurerm_mssql_server.this.name
  zone_name           = azurerm_private_dns_zone.private_link.name
  resource_group_name = azurerm_resource_group.this.name
  ttl                 = 300
  records             = [data.azurerm_private_endpoint_connection.private_link.private_service_connection.0.private_ip_address]
}

The only downside is it wants to update the DNS record each time an apply is run

  # azurerm_private_dns_a_record.private_link will be updated in-place
  ~ resource "azurerm_private_dns_a_record" "private_link" {
        fqdn                = "nciaueast.privatelink.database.windows.net."
        id                  = "sub"
        name                = "name"
      ~ records             = [
          - "192.168.4.4",
        ] -> (known after apply)
        resource_group_name = "name"
        tags                = {}
        ttl                 = 300
        zone_name           = "privatelink.database.windows.net"
    }

But I can live with that in the short term

@WodansSon WodansSon added this to the v2.14.0 milestone Jun 11, 2020
@tombuildsstuff tombuildsstuff modified the milestones: v2.14.0, v2.15.0 Jun 11, 2020
@Dmitry1987
Copy link

found a solution, check this out (it works, I am using it now):

resource "azurerm_private_endpoint" "postgresql" {
  name                = "postgres-primary-link-${var.environment}"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  subnet_id           = azurerm_subnet.postgres_subnet.id

  private_service_connection {
    name                           = "postgres-primary-${var.environment}"
    private_connection_resource_id = azurerm_postgresql_server.postgresql.id
    subresource_names              = ["postgresqlServer"]
    is_manual_connection           = false
  }
}

resource "azurerm_private_endpoint" "links-to-postgresql-replicas" {
  count               = var.postgres.number_of_replicas
  name                = "postgres-replica-${count.index +1}-${var.environment}"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  subnet_id           = azurerm_subnet.postgres_subnet.id

  private_service_connection {
    name                           = "postgres-replica-${count.index +1}-${var.environment}"
    private_connection_resource_id = azurerm_postgresql_server.replicas[count.index].id
    subresource_names              = ["postgresqlServer"]
    is_manual_connection           = false
  }
}

output "postgres-private-link" {
  value = azurerm_private_endpoint.postgresql.private_service_connection[0].private_ip_address
}

output "postgres-replica-private-link" {
  value = azurerm_private_endpoint.links-to-postgresql-replicas[0].private_service_connection[0].private_ip_address
}

So this is what you need azurerm_private_endpoint.postgresql.private_service_connection[0].private_ip_address

(postgresql is a name in my case, but might work with all other link types, I plan to try for storage too, still don't have a link to storage account buckets, I suspect my traffic to storage is not going through optimal route, maybe even goes through external network 🙀 )

WodansSon added a commit that referenced this issue Jun 18, 2020
* Fixed requiresImport test case

* Progress exposing dns zone groups

* Work thus far redesign

* Progress thus far

* Progress

* Change data structure

* Close mostly working now

* Remove old resources

* Code complete needs docs and tests

* Add docs and example

* Added Tests and updated docs

* Fix Lint Errors

* Update azurerm/internal/services/network/parse/private_endpoint.go

Co-authored-by: Tom Harvey <tombuildsstuff@users.noreply.github.com>

* Update azurerm/internal/services/network/private_endpoint_resource.go

Co-authored-by: Tom Harvey <tombuildsstuff@users.noreply.github.com>

* Update azurerm/internal/services/network/private_endpoint_resource.go

Co-authored-by: Tom Harvey <tombuildsstuff@users.noreply.github.com>

* Changes per PR

* Fix lint error

* Requested changes per PR comment

Co-authored-by: Tom Harvey <tombuildsstuff@users.noreply.github.com>
@ghost
Copy link

ghost commented Jun 19, 2020

This has been released in version 2.15.0 of the provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading. As an example:

provider "azurerm" {
    version = "~> 2.15.0"
}
# ... other configuration ...

@mathieu-benoit
Copy link

Hi @WodansSon, since it looks like it's now supported/fixed with 2.15.0, any insights about how to use this please?

@mathieu-benoit
Copy link

mathieu-benoit commented Jun 24, 2020

Hi @WodansSon and @tombuildsstuff, not sure how the referenced PR fixes the initial ask of this issue with the example of ACR?
Today we can do:

azurerm_private_endpoint.private_endpoint_acr.private_service_connection[0].private_ip_address

But there is no [1] to grab the second IP address.
Thoughts?

@poddm
Copy link

poddm commented Jul 9, 2020

@mathieu-benoit here is an example from the PR.

How to connect a Private Endpoint to a Private DNS Group

The DNS configs can be referenced from the private_dns_zone_configs attribute.

A private_dns_zone_configs block exports:

name - The name of the Private DNS Zone that the config belongs to.
id - The ID of the Private DNS Zone Config.
private_dns_zone_id - A list of IP Addresses
record_sets - A record_sets block as defined below.

@ghost
Copy link

ghost commented Jul 19, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 hashibot-feedback@hashicorp.com. Thanks!

@hashicorp hashicorp locked and limited conversation to collaborators Jul 19, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.