diff --git a/internal/services/network/vpn_server_configuration_resource.go b/internal/services/network/vpn_server_configuration_resource.go index daae3e1e4b05..0dcae37fb6b1 100644 --- a/internal/services/network/vpn_server_configuration_resource.go +++ b/internal/services/network/vpn_server_configuration_resource.go @@ -25,9 +25,9 @@ import ( func resourceVPNServerConfiguration() *pluginsdk.Resource { return &pluginsdk.Resource{ - Create: resourceVPNServerConfigurationCreateUpdate, + Create: resourceVPNServerConfigurationCreate, Read: resourceVPNServerConfigurationRead, - Update: resourceVPNServerConfigurationCreateUpdate, + Update: resourceVPNServerConfigurationUpdate, Delete: resourceVPNServerConfigurationDelete, Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { _, err := virtualwans.ParseVpnServerConfigurationID(id) @@ -269,26 +269,24 @@ func resourceVPNServerConfiguration() *pluginsdk.Resource { } } -func resourceVPNServerConfigurationCreateUpdate(d *pluginsdk.ResourceData, meta interface{}) error { +func resourceVPNServerConfigurationCreate(d *pluginsdk.ResourceData, meta interface{}) error { client := meta.(*clients.Client).Network.VirtualWANs subscriptionId := meta.(*clients.Client).Account.SubscriptionId - ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d) + ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d) defer cancel() id := virtualwans.NewVpnServerConfigurationID(subscriptionId, d.Get("resource_group_name").(string), d.Get("name").(string)) - if d.IsNewResource() { - existing, err := client.VpnServerConfigurationsGet(ctx, id) - if err != nil { - if !response.WasNotFound(existing.HttpResponse) { - return fmt.Errorf("checking for presence of existing %s: %+v", id, err) - } - } - + existing, err := client.VpnServerConfigurationsGet(ctx, id) + if err != nil { if !response.WasNotFound(existing.HttpResponse) { - return tf.ImportAsExistsError("azurerm_vpn_server_configuration", id.ID()) + return fmt.Errorf("checking for presence of existing %s: %+v", id, err) } } + if !response.WasNotFound(existing.HttpResponse) { + return tf.ImportAsExistsError("azurerm_vpn_server_configuration", id.ID()) + } + aadAuthenticationRaw := d.Get("azure_active_directory_authentication").([]interface{}) aadAuthentication := expandVpnServerConfigurationAADAuthentication(aadAuthenticationRaw) @@ -460,6 +458,129 @@ func resourceVPNServerConfigurationRead(d *pluginsdk.ResourceData, meta interfac return nil } +func resourceVPNServerConfigurationUpdate(d *pluginsdk.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).Network.VirtualWANs + ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d) + defer cancel() + + id, err := virtualwans.ParseVpnServerConfigurationID(d.Id()) + if err != nil { + return err + } + + existing, err := client.VpnServerConfigurationsGet(ctx, *id) + if err != nil { + return fmt.Errorf("retrieving %s: %+v", id, err) + } + + if existing.Model == nil { + return fmt.Errorf("retrieving %s: `model` was nil", id) + } + + if existing.Model.Properties == nil { + return fmt.Errorf("retrieving %s: `properties` was nil", id) + } + + payload := existing.Model + + if d.HasChange("azure_active_directory_authentication") { + payload.Properties.AadAuthenticationParameters = expandVpnServerConfigurationAADAuthentication(d.Get("azure_active_directory_authentication").([]interface{})) + } + + if d.HasChange("client_revoked_certificate") { + payload.Properties.VpnClientRevokedCertificates = expandVpnServerConfigurationClientRevokedCertificates(d.Get("client_revoked_certificate").(*pluginsdk.Set).List()) + } + + if d.HasChange("client_root_certificate") { + payload.Properties.VpnClientRootCertificates = expandVpnServerConfigurationClientRootCertificates(d.Get("client_root_certificate").(*pluginsdk.Set).List()) + } + + if d.HasChange("ipsec_policy") { + payload.Properties.VpnClientIPsecPolicies = expandVpnServerConfigurationIPSecPolicies(d.Get("ipsec_policy").([]interface{})) + } + + if d.HasChange("vpn_protocols") { + payload.Properties.VpnProtocols = expandVpnServerConfigurationVPNProtocols(d.Get("vpn_protocols").(*pluginsdk.Set).List()) + } + + supportsAAD := false + supportsCertificates := false + supportsRadius := false + + vpnAuthenticationTypesRaw := d.Get("vpn_authentication_types").([]interface{}) + vpnAuthenticationTypes := make([]virtualwans.VpnAuthenticationType, 0) + for _, v := range vpnAuthenticationTypesRaw { + authType := virtualwans.VpnAuthenticationType(v.(string)) + + switch authType { + case virtualwans.VpnAuthenticationTypeAAD: + supportsAAD = true + + case virtualwans.VpnAuthenticationTypeCertificate: + supportsCertificates = true + + case virtualwans.VpnAuthenticationTypeRadius: + supportsRadius = true + + default: + return fmt.Errorf("Unsupported `vpn_authentication_type`: %q", authType) + } + + vpnAuthenticationTypes = append(vpnAuthenticationTypes, authType) + } + + if d.HasChange("vpn_authentication_types") { + payload.Properties.VpnAuthenticationTypes = &vpnAuthenticationTypes + } + + if d.HasChange("radius") { + // if radius has changed, we'll nil out the radius attributes and update them to new values if needed + payload.Properties.RadiusServerAddress = nil + payload.Properties.RadiusServerSecret = nil + payload.Properties.RadiusClientRootCertificates = nil + payload.Properties.RadiusServerRootCertificates = nil + payload.Properties.RadiusServers = nil + + radius := expandVpnServerConfigurationRadius(d.Get("radius").([]interface{})) + if supportsRadius { + if radius == nil { + return fmt.Errorf("`radius` must be specified when `vpn_authentication_type` is set to `Radius`") + } + + if radius.servers != nil && len(*radius.servers) != 0 { + payload.Properties.RadiusServers = radius.servers + } + + payload.Properties.RadiusServerAddress = utils.String(radius.address) + payload.Properties.RadiusServerSecret = utils.String(radius.secret) + + payload.Properties.RadiusClientRootCertificates = radius.clientRootCertificates + payload.Properties.RadiusServerRootCertificates = radius.serverRootCertificates + } + } + + if supportsAAD && payload.Properties.AadAuthenticationParameters == nil { + return fmt.Errorf("`azure_active_directory_authentication` must be specified when `vpn_authentication_type` is set to `AAD`") + } + + // parameter:VpnServerConfigVpnClientRootCertificates is not specified when VpnAuthenticationType as Certificate is selected. + if supportsCertificates && payload.Properties.VpnClientRootCertificates != nil && len(*payload.Properties.VpnClientRootCertificates) == 0 { + return fmt.Errorf("`client_root_certificate` must be specified when `vpn_authentication_type` is set to `Certificate`") + } + + if d.HasChange("tags") { + payload.Tags = tags.Expand(d.Get("tags").(map[string]interface{})) + } + + if err := client.VpnServerConfigurationsCreateOrUpdateThenPoll(ctx, *id, *payload); err != nil { + return fmt.Errorf("updating %s: %+v", id, err) + } + + d.SetId(id.ID()) + + return resourceVPNServerConfigurationRead(d, meta) +} + func resourceVPNServerConfigurationDelete(d *pluginsdk.ResourceData, meta interface{}) error { client := meta.(*clients.Client).Network.VirtualWANs ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d)