pulumi / pulumi-azure

A Microsoft Azure Pulumi resource package, providing multi-language access to Azure
Apache License 2.0
131 stars 50 forks source link

Non-empty refresh for VirtualNetwork subnets #1569

Open t0yv0 opened 8 months ago

t0yv0 commented 8 months ago

What happened?

There is a problem when adding subnets to VirtualNetwork and then refreshing. The docs state this:

    // Can be specified multiple times to define multiple subnets. Each `subnet` block supports fields documented below.
    //
    // > **NOTE** Since `subnet` can be configured both inline and via the separate `network.Subnet` resource, we have to explicitly set it to empty slice (`[]`) to remove it.
    Subnets VirtualNetworkSubnetArrayInput
    // A mapping of tags to assign to the resource.

This is very likely related to https://github.com/pulumi/pulumi-azure/issues/736 which seems to be more serious than just a cosmetic issue.

Example

Calling pulumi up followed by pulumi refresh on examples/network.go produces a non-empty diff.

Although the subnet was created using a resource instead of setting subnets property, Pulumi refresh wants to edit the subnets output property:

  pulumi:pulumi:Stack: (same)
    [urn=urn:pulumi:networkgoazuretest::network-go::pulumi:pulumi:Stack::network-go-networkgoazuretest]
    ~ azure:network/virtualNetwork:VirtualNetwork: (update)
        [id=/subscriptions/0282681f-7a9e-424b-80b2-96babd57a8a1/resourceGroups/server-rg8613fe9b/providers/Microsoft.Network/virtualNetworks/server-network3a1505bd]
        [urn=urn:pulumi:networkgoazuretest::network-go::azure:network/virtualNetwork:VirtualNetwork::server-network]
        --outputs:--
      ~ subnets             : [
          + [0]: {
                  + addressPrefix: "10.0.0.0/16"
                  + id           : "/subscriptions/0282681f-7a9e-424b-80b2-96babd57a8a1/resourceGroups/server-rg8613fe9b/providers/Microsoft.Network/virtualNetworks/server-network3a1505bd/subnets/subnetd44f4f85"
                  + name         : "subnetd44f4f85"
                  + securityGroup: ""
                }
        ]

Output of pulumi about

CLI
Version 3.97.0 Go Version go1.21.4 Go Compiler gc

Plugins NAME VERSION azure 5.45.0 go unknown

Host
OS darwin Version 14.1.1 Arch x86_64

This project is written in go: executable='/Users/t0yv0/bin/go' version='go version go1.21.3 darwin/amd64'

Current Stack: t0yv0/network-go/networkgoazuretest

TYPE URN pulumi:pulumi:Stack urn:pulumi:networkgoazuretest::network-go::pulumi:pulumi:Stack::network-go-networkgoazuretest pulumi:providers:azure urn:pulumi:networkgoazuretest::network-go::pulumi:providers:azure::default azure:core/resourceGroup:ResourceGroup urn:pulumi:networkgoazuretest::network-go::azure:core/resourceGroup:ResourceGroup::server-rg azure:network/virtualNetwork:VirtualNetwork urn:pulumi:networkgoazuretest::network-go::azure:network/virtualNetwork:VirtualNetwork::server-network azure:network/subnet:Subnet urn:pulumi:networkgoazuretest::network-go::azure:network/subnet:Subnet::subnet

Found no pending operations associated with networkgoazuretest

Backend
Name pulumi.com URL https://app.pulumi.com/t0yv0 User t0yv0 Organizations t0yv0, pulumi Token type personal

Dependencies: NAME VERSION github.com/pulumi/pulumi-azure/sdk/v5 5.45.0 github.com/pulumi/pulumi/sdk/v3 3.50.1

Pulumi locates its logs in /var/folders/gk/cchgxh512m72f_dmkcc3d09h0000gp/T/com.apple.shortcuts.mac-helper// by default

Additional context

This issue was discovered when trying to make the default test settings stricter.

Contributing

Vote on this issue by adding a 👍 reaction. To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).

t0yv0 commented 8 months ago

I was curious so I went further to try this out in TF and see if this reproduces.

infra.tf:


resource "azurerm_resource_group" "example" {
  name     = "example-resources"
  location = "East US"
}

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

provider "azurerm" {
  features {}
}
$ terraform apply
$ terraform state show azurerm_virtual_network.example

resource "azurerm_virtual_network" "example" {
    address_space           = [
        "10.0.0.0/16",
    ]
    dns_servers             = []
    flow_timeout_in_minutes = 0
    guid                    = "9eb72708-cf31-4e4d-9287-96731ace7d8e"
    id                      = "/subscriptions/0282681f-7a9e-424b-80b2-96babd57a8a1/resourceGroups/example-resources/providers/Microsoft.Network/virtualNetworks/example-vnet"
    location                = "eastus"
    name                    = "example-vnet"
    resource_group_name     = "example-resources"
    subnet                  = []
    tags                    = {}
}

infra.tf:

resource "azurerm_resource_group" "example" {
  name     = "example-resources"
  location = "East US"
}

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

resource "azurerm_subnet" "example" {
  name                 = "example-subnet"
  resource_group_name  = azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.example.name
  address_prefixes     = ["10.0.1.0/24"]

  delegation {
    name = "delegation"

    service_delegation {
      name    = "Microsoft.ContainerInstance/containerGroups"
      actions = ["Microsoft.Network/virtualNetworks/subnets/join/action", "Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action"]
    }
  }
}

provider "azurerm" {
  features {}
}
$ terraform apply
$ terraform state show azurerm_virtual_network.example

resource "azurerm_virtual_network" "example" {
    address_space           = [
        "10.0.0.0/16",
    ]
    dns_servers             = []
    flow_timeout_in_minutes = 0
    guid                    = "9eb72708-cf31-4e4d-9287-96731ace7d8e"
    id                      = "/subscriptions/0282681f-7a9e-424b-80b2-96babd57a8a1/resourceGroups/example-resources/providers/Microsoft.Network/virtualNetworks/example-vnet"
    location                = "eastus"
    name                    = "example-vnet"
    resource_group_name     = "example-resources"
    subnet                  = []
    tags                    = {}
}
$ terraform refresh
$ terraform state show azurerm_virtual_network.example

# azurerm_virtual_network.example:
resource "azurerm_virtual_network" "example" {
    address_space           = [
        "10.0.0.0/16",
    ]
    dns_servers             = []
    flow_timeout_in_minutes = 0
    guid                    = "9eb72708-cf31-4e4d-9287-96731ace7d8e"
    id                      = "/subscriptions/0282681f-7a9e-424b-80b2-96babd57a8a1/resourceGroups/example-resources/providers/Microsoft.Network/virtualNetworks/example-vnet"
    location                = "eastus"
    name                    = "example-vnet"
    resource_group_name     = "example-resources"
    subnet                  = [
        {
            address_prefix = "10.0.1.0/24"
            id             = "/subscriptions/0282681f-7a9e-424b-80b2-96babd57a8a1/resourceGroups/example-resources/providers/Microsoft.Network/virtualNetworks/example-vnet/subnets/example-subnet"
            name           = "example-subnet"
            security_group = ""
        },
    ]
    tags                    = {}
}

The subnet gets linked up into the subnets property only after explicit refresh. It feels a little surprising but not obviously harmful especially as Pulumi marks these as output values not input values in the state.