hashicorp / terraform-provider-azurerm

Terraform provider for Azure Resource Manager
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs
Mozilla Public License 2.0
4.52k stars 4.6k forks source link

Support for configuring public access for mysql_flexible_server #26156

Open kingsleyadam opened 3 months ago

kingsleyadam commented 3 months ago

Is there an existing issue for this?

Community Note

Description

Recreating issue since existing issue was closed pre-maturely #24641

Currently public_network_access_enabled is set to computed, hence the value cannot be configured. This value can be configured when using public access connectivity method, to disable public access and use private link instead.

I think these are the required changes but I can't run the acceptance tests to check. https://github.com/JBodkin-Amphora/terraform-provider-azurerm/commit/41bc37d9504a65e77d0c5f29b788da859316e710

image

New or Affected Resource(s)/Data Source(s)

azurerm_mysql_flexible_server

Potential Terraform Configuration

resource "mysql_flexible_server" "this" {
  public_network_access_enabled = false
}

References

No response

Bv-Lucas commented 2 months ago

Hello Any news regarding this ? The workarounds are not ideal as they add providers to the configuration Do you have an ETA for this addition ? Thanks !

iuvooneill commented 2 months ago

I came here for a related issue - and it is to explicitly turn public access ON so that the firewall rules can be applied. I created a mysql flexible server via terraform, and created a firewall rule, but the firewall rule is ignored as the attribute "public_network_access_enabled" is still false, and I can't find a way to enable it outside of direct CLI call.

kingsleyadam commented 2 months ago

I came here for a related issue - and it is to explicitly turn public access ON so that the firewall rules can be applied. I created a mysql flexible server via terraform, and created a firewall rule, but the firewall rule is ignored as the attribute "public_network_access_enabled" is still false, and I can't find a way to enable it outside of direct CLI call.

For @iuvooneill and others that may need a work-around. The best alternative is to us the azapi provider.

variable "public_access_enabled" {
  description = "Whether or not public access is allowed for this server."
  type        = bool
  default     = false
}

resource "azapi_resource_action" "set_public_access" {
  type        = "Microsoft.DBforMySQL/flexibleServers@2023-06-30"
  resource_id = azurerm_mysql_flexible_server.mysql_flexible_server.id
  method      = "PATCH"

  body = {
    properties = {
      network = {
        publicNetworkAccess = var.public_access_enabled ? "Enabled" : "Disabled"
      }
    }
  }

  depends_on = [
    azurerm_private_endpoint.private_endpoint,
    azurerm_mysql_flexible_server_configuration.config
  ]
}
iuvooneill commented 2 months ago

For @iuvooneill and others that may need a work-around. The best alternative is to us the azapi provider.

Alas, this doesn't seem to have worked. The "public_network_access_enabled" attribute still reports as false and the DNS name doesn't resolve externally, even though the azapi_resource_action appeared to be successful.

katbyte commented 3 weeks ago

It does appear the API is ignoring the request to change public network access enabled:

------- Stdout: -------
=== RUN   TestAccMySqlFlexibleServer_publicNetworkAccessDisabled
=== PAUSE TestAccMySqlFlexibleServer_publicNetworkAccessDisabled
=== CONT  TestAccMySqlFlexibleServer_publicNetworkAccessDisabled
    testcase.go:130: Step 1/3 error: After applying this test step, the non-refresh plan was not empty.
        stdout:

        Terraform used the selected providers to generate the following execution
        plan. Resource actions are indicated with the following symbols:
        -/+ destroy and then create replacement

        Terraform will perform the following actions:

          # azurerm_mysql_flexible_server.test must be replaced
        -/+ resource "azurerm_mysql_flexible_server" "test" {
              ~ fqdn                          = "acctest-fs-240821194320628889.mysql.database.azure.com" -> (known after apply)
              ~ id                            = "/subscriptions/*******/resourceGroups/acctestRG-mysql-240821194320628889/providers/Microsoft.DBforMySQL/flexibleServers/acctest-fs-240821194320628889" -> (known after apply)
                name                          = "acctest-fs-240821194320628889"
              ~ public_network_access_enabled = true -> false # forces replacement
              ~ replica_capacity              = 10 -> (known after apply)
              ~ replication_role              = "None" -> (known after apply)
              ~ version                       = "5.7" -> (known after apply)
                # (8 unchanged attributes hidden)

              - storage {
                  - auto_grow_enabled  = true -> null
                  - io_scaling_enabled = false -> null
                  - iops               = 360 -> null
                  - size_gb            = 20 -> null
                }

                # (1 unchanged block hidden)
            }

        Plan: 1 to add, 0 to change, 1 to destroy.
--- FAIL: TestAccMySqlFlexibleServer_publicNetworkAccessDisabled (525.81s)
FAIL

as such at this time i am going to close my PR and wait for the API to be fixed

brettnf commented 3 weeks ago

It does appear the API is ignoring the request to change public network access enabled: [...] as such at this time i am going to close my PR and wait for the API to be fixed

The API version 2022-01-01 does not support the network.publicNetworkAccess option, you have to increase the api version for mysql in the module to make it work.

simaotwx commented 4 days ago

I second this. image

There is an attribute (see https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mysql_flexible_server#public_network_access_enabled):

image

But the resource does not support this. We're using a private endpoint and a firewall rule with the vnet address range, but to me this does not look like it's the way it should be done:

resource "azurerm_mysql_flexible_server_firewall_rule" "vnet_only" {
  name                = "vnet_only"
  resource_group_name = azurerm_resource_group.rg.name
  server_name         = azurerm_mysql_flexible_server.db.name
  start_ip_address    = cidrhost(azurerm_virtual_network.vnet.address_space.0, 1)
  end_ip_address      = cidrhost(azurerm_virtual_network.vnet.address_space.0, 254)
}

EDIT: I can confirm that the workaround @kingsleyadam proposed works fine.