How to set service_endpoints and delegation in subnet part of vnet in azure using terraform?

I have a working block of terraform vnet,subnet and NSG of it.

provider "azurerm" {
  features {}
}

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

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

resource "azurerm_subnet" "example" {
  name                 = "example-sn"
  resource_group_name  = azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.example.name
  address_prefixes     = ["10.0.2.0/24"]
  service_endpoints    = ["Microsoft.Storage"]
  delegation {
    name = "fs"
    service_delegation {
      name = "Microsoft.DBforPostgreSQL/flexibleServers"
      actions = [
        "Microsoft.Network/virtualNetworks/subnets/join/action",
      ]
    }
  }
}
resource "azurerm_private_dns_zone" "example" {
  name                = "example.postgres.database.azure.com"
  resource_group_name = azurerm_resource_group.example.name
}

resource "azurerm_private_dns_zone_virtual_network_link" "example" {
  name                  = "exampleVnetZone.com"
  private_dns_zone_name = azurerm_private_dns_zone.example.name
  virtual_network_id    = azurerm_virtual_network.example.id
  resource_group_name   = azurerm_resource_group.example.name
}

resource "azurerm_postgresql_flexible_server" "example" {
  name                   = "example-psqlflexibleserver2022"
  resource_group_name    = azurerm_resource_group.example.name
  location               = azurerm_resource_group.example.location
  version                = "13"
  delegated_subnet_id    = azurerm_subnet.example.id
  private_dns_zone_id    = azurerm_private_dns_zone.example.id
  administrator_login    = "postgres"
  administrator_password = "password@2020"
  zone                   = "1"

  storage_mb = 131072

  sku_name   = "GP_Standard_D2s_v3"
  depends_on = [azurerm_private_dns_zone_virtual_network_link.example]

}

But I am getting create nsg before subnet policy error, so changed the subnet creation as below.

# Create Virtual Network
resource "azurerm_virtual_network" "aksvnet" {
  name                = "aks-network"
  location            = azurerm_resource_group.aks_rg.location
  resource_group_name = azurerm_resource_group.aks_rg.name
  address_space       = ["10.0.0.0/8"]

  subnet {
    name           = "aks-default-subnet"
    address_prefix = "10.240.0.0/16"
    security_group = azurerm_network_security_group.example.id
  }
  subnet {
    name           = "aks-postgres-subnet"
    address_prefix = "10.230.2.0/24"
    security_group = azurerm_network_security_group.example.id
    service_endpoints    = ["Microsoft.Storage"]
       delegation {
     name = "fs"
     service_delegation {
       name = "Microsoft.DBforPostgreSQL/flexibleServers"
       actions = [
         "Microsoft.Network/virtualNetworks/subnets/join/action",
       ]
     }
   }
  }

}

resource "azurerm_network_security_group" "example" {
  name                = "example-nsg"
  location            = azurerm_resource_group.aks_rg.location
  resource_group_name = azurerm_resource_group.aks_rg.name
  security_rule {
    name                       = "test123"
    priority                   = 100
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "*"
    source_address_prefix      = "*"
    destination_address_prefix = "*"
  }
}

But getting below errors.

Please suggest how to fix that.

 Error: Unsupported argument
│
│   on 11-virtual-network.tf line 17, in resource "azurerm_virtual_network" "aksvnet":
│   17:     service_endpoints    = ["Microsoft.Storage"]
│
│ An argument named "service_endpoints" is not expected here.
╵
╷
│ Error: Unsupported block type
│
│   on 11-virtual-network.tf line 18, in resource "azurerm_virtual_network" "aksvnet":
│   18:        delegation {
│
│ Blocks of type "delegation" are not expected here.

Even with below approach, I am getting policy error.

# Create Virtual Network
resource "azurerm_virtual_network" "aksvnet" {
  name                = "aks-network"
  location            = azurerm_resource_group.aks_rg.location
  resource_group_name = azurerm_resource_group.aks_rg.name
  address_space       = ["10.0.0.0/8"]

  subnet {
    name           = "aks-default-subnet"
    address_prefix = "10.240.0.0/16"
    security_group = azurerm_network_security_group.example.id
  }
}

resource "azurerm_network_security_group" "example" {
  name                = "example-nsg"
  location            = azurerm_resource_group.aks_rg.location
  resource_group_name = azurerm_resource_group.aks_rg.name
  security_rule {
    name                       = "test123"
    priority                   = 100
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "*"
    source_address_prefix      = "*"
    destination_address_prefix = "*"
  }
}

resource "azurerm_subnet_network_security_group_association" "example" {
  subnet_id                 = azurerm_subnet.example.id
  network_security_group_id = azurerm_network_security_group.example.id
}

resource "azurerm_subnet" "example" {

  virtual_network_name = azurerm_virtual_network.aksvnet.name
  name                 = "aks-postgres-subnet"
  resource_group_name  = azurerm_resource_group.aks_rg.name
  address_prefixes     = ["10.230.2.0/24"]
  service_endpoints    = ["Microsoft.Storage"]
  delegation {
    name = "fs"
    service_delegation {
      name = "Microsoft.DBforPostgreSQL/flexibleServers"
      actions = [
        "Microsoft.Network/virtualNetworks/subnets/join/action",
      ]
    }
  }
  depends_on = [azurerm_virtual_network.aksvnet, azurerm_network_security_group.example]
}

I am getting error as below.

er-delete-dev"): network.SubnetsClient#CreateOrUpdate: Failure sending request: StatusCode=403 -- Original Error:

Code=“RequestDisallowedByPolicy” Message=“Resource
‘aks-postgres-subnet’ was disallowed by policy. Policy identifiers:
'[{“policyAssignment”:{“name”:“Deny-Subnet-Without-Nsg”,“id”:”/providers/Microsoft.Management/managementGroups/QSFT-landingzones/providers/Microsoft.Authorization/policyAssignments/Deny-Subnet-Without-Nsg"},“policyDefinition”:{“name”:“Subnets
should have a Network Security Group
“,“id”:”/providers/Microsoft.Management/managementGroups/QSFT/providers/Microsoft.Authorization/policyDefinitions/Deny-Subnet-Without-Nsg”}}]’."
Target=“aks-postgres-subnet”
AdditionalInfo=[{“info”:{“evaluationDetails”:{“evaluatedExpressions”:[{“expression”:“type”,“expressionKind”:“Field”,“expressionValue”:“Microsoft.Network/virtualNetworks/subnets”,“operator”:“Equals”,“path”:“type”,“result”:“True”,“targetValue”:“Microsoft.Network/virtualNetworks/subnets”},{“expression”:“Microsoft.Network/virtualNetworks/subnets/networkSecurityGroup.id”,“expressionKind”:“Field”,“operator”:“Exists”,“path”:“properties.networkSecurityGroup.id”,“result”:“True”,“targetValue”:“false”}]},“policyAssignmentDisplayName”:“Deny-Subnet-Without-Nsg”,“policyAssignmentId”:"/providers/Microsoft.Management/managementGroups/QSFT-landingzones/providers/Microsoft.Authorization/policyAssignments/Deny-Subnet-Without-Nsg",“policyAssignmentName”:“Deny-Subnet-Without-Nsg”,“policyAssignmentScope”:"/providers/Microsoft.Management/managementGroups/QSFT-landingzones",“policyDefinitionDisplayName”:“Subnets
should have a Network Security Group
“,“policyDefinitionEffect”:“Deny”,“policyDefinitionId”:”/providers/Microsoft.Management/managementGroups/QSFT/providers/Microsoft.Authorization/policyDefinitions/Deny-Subnet-Without-Nsg”,“policyDefinitionName”:“Deny-Subnet-Without-Nsg”},“type”:“PolicyViolation”}]

│ with azurerm_subnet.example,
│ on 11-virtual-network.tf line 37, in resource “azurerm_subnet” “example”:
│ 37: resource “azurerm_subnet” “example” {

The policy is applied in organization level, and can’t disable that. could you Please let me know if any other options

is there anyway to apply service_delegation to a subnet after creating the subnet first? So that I would create subnet along with vnet and apply the delegation as separate block

As per my understanding you have to transition those settings into the dedicated subnet resource instead of using the inline definition.
Although it indeed looks like, either resource lacks a configuration detail.

So it doesn’t seem to be feasible without changing the policy.