diff --git a/internal/services/appservice/static_web_app_resource.go b/internal/services/appservice/static_web_app_resource.go index a297b7f9bcf6..a181045c6586 100644 --- a/internal/services/appservice/static_web_app_resource.go +++ b/internal/services/appservice/static_web_app_resource.go @@ -40,7 +40,6 @@ type StaticWebAppResourceModel struct { ConfigFileChanges bool `tfschema:"configuration_file_changes_enabled"` Identity []identity.ModelSystemAssignedUserAssigned `tfschema:"identity"` PreviewEnvironments bool `tfschema:"preview_environments_enabled"` - PublicNetworkAccess bool `tfschema:"public_network_access_enabled"` SkuTier string `tfschema:"sku_tier"` SkuSize string `tfschema:"sku_size"` Tags map[string]string `tfschema:"tags"` @@ -77,7 +76,6 @@ func (r StaticWebAppResource) Arguments() map[string]*pluginsdk.Schema { "public_network_access_enabled": { Type: pluginsdk.TypeBool, Optional: true, - Default: true, }, "sku_tier": { @@ -189,15 +187,20 @@ func (r StaticWebAppResource) Create() sdk.ResourceFunc { props := &staticsites.StaticSite{ AllowConfigFileUpdates: pointer.To(model.ConfigFileChanges), StagingEnvironmentPolicy: pointer.To(staticsites.StagingEnvironmentPolicyEnabled), - PublicNetworkAccess: pointer.To(helpers.PublicNetworkAccessEnabled), } if !model.PreviewEnvironments { props.StagingEnvironmentPolicy = pointer.To(staticsites.StagingEnvironmentPolicyDisabled) } - if !model.PublicNetworkAccess { - props.PublicNetworkAccess = pointer.To(helpers.PublicNetworkAccessDisabled) + // The public_network_access_enabled has different behavior for null, false and true. + // See: https://learn.microsoft.com/en-us/azure/templates/microsoft.web/staticsites?pivots=deployment-language-bicep#staticsite + if v := metadata.ResourceData.GetRawConfig().AsValueMap()["public_network_access_enabled"]; !v.IsNull() { + if v.False() { + props.PublicNetworkAccess = pointer.To(helpers.PublicNetworkAccessDisabled) + } else { + props.PublicNetworkAccess = pointer.To(helpers.PublicNetworkAccessEnabled) + } } envelope.Properties = props @@ -279,7 +282,6 @@ func (r StaticWebAppResource) Read() sdk.ResourceFunc { state.ConfigFileChanges = pointer.From(props.AllowConfigFileUpdates) state.DefaultHostName = pointer.From(props.DefaultHostname) state.PreviewEnvironments = pointer.From(props.StagingEnvironmentPolicy) == staticsites.StagingEnvironmentPolicyEnabled - state.PublicNetworkAccess = !strings.EqualFold(pointer.From(props.PublicNetworkAccess), helpers.PublicNetworkAccessDisabled) } if sku := model.Sku; sku != nil { @@ -321,7 +323,23 @@ func (r StaticWebAppResource) Read() sdk.ResourceFunc { } } - return metadata.Encode(&state) + if err := metadata.Encode(&state); err != nil { + return err + } + + // The public_network_access_enabled has different behavior for null, false and true. + // See: https://learn.microsoft.com/en-us/azure/templates/microsoft.web/staticsites?pivots=deployment-language-bicep#staticsite + // We need special handling here as the plugin sdk currently doesn't support null setting an attribute. + if model := staticSite.Model; model != nil { + if props := model.Properties; props != nil { + // We don't nil set the property as it is a top level property, and SDKv2 will always give it a concrete value (i.e. false) if we set it explicitly. + if props.PublicNetworkAccess != nil { + metadata.ResourceData.Set("public_network_access_enabled", strings.EqualFold(pointer.From(props.PublicNetworkAccess), helpers.PublicNetworkAccessEnabled)) + } + } + } + + return nil }, } } @@ -406,10 +424,16 @@ func (r StaticWebAppResource) Update() sdk.ResourceFunc { } if metadata.ResourceData.HasChange("public_network_access_enabled") { - if !config.PublicNetworkAccess { - model.Properties.PublicNetworkAccess = pointer.To(helpers.PublicNetworkAccessDisabled) + // The public_network_access_enabled has different behavior for null, false and true. + // See: https://learn.microsoft.com/en-us/azure/templates/microsoft.web/staticsites?pivots=deployment-language-bicep#staticsite + if v := metadata.ResourceData.GetRawConfig().AsValueMap()["public_network_access_enabled"]; v.IsNull() { + model.Properties.PublicNetworkAccess = nil } else { - model.Properties.PublicNetworkAccess = pointer.To(helpers.PublicNetworkAccessEnabled) + if v.False() { + model.Properties.PublicNetworkAccess = pointer.To(helpers.PublicNetworkAccessDisabled) + } else { + model.Properties.PublicNetworkAccess = pointer.To(helpers.PublicNetworkAccessEnabled) + } } } diff --git a/internal/services/appservice/static_web_app_resource_test.go b/internal/services/appservice/static_web_app_resource_test.go index 85bec21c0ba5..723cfff4628f 100644 --- a/internal/services/appservice/static_web_app_resource_test.go +++ b/internal/services/appservice/static_web_app_resource_test.go @@ -298,29 +298,21 @@ func TestAccAzureStaticWebApp_basicWithConfigShouldFail(t *testing.T) { }) } -func TestAccAzureStaticWebApp_publicNetworkAccessDisabled(t *testing.T) { +func TestAccAzureStaticWebApp_publicNetworkAccessUpdate(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_static_web_app", "test") r := StaticWebAppResource{} data.ResourceTest(t, r, []acceptance.TestStep{ { - Config: r.publicNetworkAccessDisabled(data), + Config: r.publicNetworkAccess(data, "null"), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), - check.That(data.ResourceName).Key("public_network_access_enabled").HasValue("false"), + check.That(data.ResourceName).Key("public_network_access_enabled").DoesNotExist(), ), }, data.ImportStep(), - }) -} - -func TestAccAzureStaticWebApp_publicNetworkAccessUpdate(t *testing.T) { - data := acceptance.BuildTestData(t, "azurerm_static_web_app", "test") - r := StaticWebAppResource{} - - data.ResourceTest(t, r, []acceptance.TestStep{ { - Config: r.basic(data), + Config: r.publicNetworkAccess(data, "true"), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), check.That(data.ResourceName).Key("public_network_access_enabled").HasValue("true"), @@ -328,21 +320,13 @@ func TestAccAzureStaticWebApp_publicNetworkAccessUpdate(t *testing.T) { }, data.ImportStep(), { - Config: r.publicNetworkAccessDisabled(data), + Config: r.publicNetworkAccess(data, "false"), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), check.That(data.ResourceName).Key("public_network_access_enabled").HasValue("false"), ), }, data.ImportStep(), - { - Config: r.basic(data), - Check: acceptance.ComposeTestCheckFunc( - check.That(data.ResourceName).ExistsInAzure(r), - check.That(data.ResourceName).Key("public_network_access_enabled").HasValue("true"), - ), - }, - data.ImportStep(), }) } @@ -692,7 +676,7 @@ resource "azurerm_static_web_app" "test" { `, data.RandomInteger, data.Locations.Primary) } -func (r StaticWebAppResource) publicNetworkAccessDisabled(data acceptance.TestData) string { +func (r StaticWebAppResource) publicNetworkAccess(data acceptance.TestData, value string) string { return fmt.Sprintf(` provider "azurerm" { features {} @@ -710,7 +694,7 @@ resource "azurerm_static_web_app" "test" { sku_size = "Free" sku_tier = "Free" - public_network_access_enabled = false + public_network_access_enabled = %s } -`, data.RandomInteger, data.Locations.Primary, data.RandomInteger) +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, value) }