diff --git a/internal/services/mssql/client/client.go b/internal/services/mssql/client/client.go index 1a9bf88afc81b..125ceb713ab79 100644 --- a/internal/services/mssql/client/client.go +++ b/internal/services/mssql/client/client.go @@ -21,6 +21,7 @@ type Client struct { ReplicationLinksClient *sql.ReplicationLinksClient RestorableDroppedDatabasesClient *sql.RestorableDroppedDatabasesClient ServerAzureADAdministratorsClient *sql.ServerAzureADAdministratorsClient + ServerAzureADOnlyAuthenticationsClient *sql.ServerAzureADOnlyAuthenticationsClient ServerConnectionPoliciesClient *sql.ServerConnectionPoliciesClient ServerExtendedBlobAuditingPoliciesClient *sql.ExtendedServerBlobAuditingPoliciesClient ServerSecurityAlertPoliciesClient *sql.ServerSecurityAlertPoliciesClient @@ -85,6 +86,9 @@ func NewClient(o *common.ClientOptions) *Client { serverAzureADAdministratorsClient := sql.NewServerAzureADAdministratorsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&serverAzureADAdministratorsClient.Client, o.ResourceManagerAuthorizer) + serverAzureADOnlyAuthenticationsClient := sql.NewServerAzureADOnlyAuthenticationsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&serverAzureADOnlyAuthenticationsClient.Client, o.ResourceManagerAuthorizer) + serversClient := sql.NewServersClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&serversClient.Client, o.ResourceManagerAuthorizer) @@ -122,6 +126,7 @@ func NewClient(o *common.ClientOptions) *Client { ReplicationLinksClient: &replicationLinksClient, RestorableDroppedDatabasesClient: &restorableDroppedDatabasesClient, ServerAzureADAdministratorsClient: &serverAzureADAdministratorsClient, + ServerAzureADOnlyAuthenticationsClient: &serverAzureADOnlyAuthenticationsClient, ServersClient: &serversClient, ServerExtendedBlobAuditingPoliciesClient: &serverExtendedBlobAuditingPoliciesClient, ServerConnectionPoliciesClient: &serverConnectionPoliciesClient, diff --git a/internal/services/mssql/mssql_server_resource.go b/internal/services/mssql/mssql_server_resource.go index e2843e03521bd..23626fa23496f 100644 --- a/internal/services/mssql/mssql_server_resource.go +++ b/internal/services/mssql/mssql_server_resource.go @@ -102,6 +102,12 @@ func resourceMsSqlServer() *pluginsdk.Resource { Computed: true, ValidateFunc: validation.IsUUID, }, + + "azuread_only_authentication": { + Type: pluginsdk.TypeBool, + Optional: true, + Computed: true, + }, }, }, }, @@ -209,6 +215,7 @@ func resourceMsSqlServerCreateUpdate(d *pluginsdk.ResourceData, meta interface{} auditingClient := meta.(*clients.Client).MSSQL.ServerExtendedBlobAuditingPoliciesClient connectionClient := meta.(*clients.Client).MSSQL.ServerConnectionPoliciesClient adminClient := meta.(*clients.Client).MSSQL.ServerAzureADAdministratorsClient + aadOnlyAuthentictionsClient := meta.(*clients.Client).MSSQL.ServerAzureADOnlyAuthenticationsClient ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d) defer cancel() @@ -282,6 +289,16 @@ func resourceMsSqlServerCreateUpdate(d *pluginsdk.ResourceData, meta interface{} d.SetId(id.ID()) if d.HasChange("azuread_administrator") { + aadOnlyDeleteFuture, err := aadOnlyAuthentictionsClient.Delete(ctx, id.ResourceGroup, id.Name) + if err != nil { + if aadOnlyDeleteFuture.Response().StatusCode != 400 { + return fmt.Errorf("deleting AD Only Authentications %s: %+v", id.String(), err) + } + log.Printf("[INFO] AD Only Authentication is not removed as AD Admin is not set for %s: %+v", id.String(), err) + } else if err = aadOnlyDeleteFuture.WaitForCompletionRef(ctx, adminClient.Client); err != nil { + return fmt.Errorf("waiting for deletion of AD Only Authentications %s: %+v", id.String(), err) + } + adminDelFuture, err := adminClient.Delete(ctx, id.ResourceGroup, id.Name) if err != nil { return fmt.Errorf("deleting AAD admin %s: %+v", id.String(), err) @@ -300,6 +317,22 @@ func resourceMsSqlServerCreateUpdate(d *pluginsdk.ResourceData, meta interface{} if err = adminFuture.WaitForCompletionRef(ctx, adminClient.Client); err != nil { return fmt.Errorf("waiting for creation of AAD admin %s: %+v", id.String(), err) } + + if aadOnlyAuthentictionsEnabled := expandMsSqlServerAADOnlyAuthentictions(d.Get("azuread_administrator").([]interface{})); aadOnlyAuthentictionsEnabled { + aadOnlyAuthentictionsParams := sql.ServerAzureADOnlyAuthentication{ + AzureADOnlyAuthProperties: &sql.AzureADOnlyAuthProperties{ + AzureADOnlyAuthentication: utils.Bool(aadOnlyAuthentictionsEnabled), + }, + } + aadOnlyEnabledFuture, err := aadOnlyAuthentictionsClient.CreateOrUpdate(ctx, id.ResourceGroup, id.Name, aadOnlyAuthentictionsParams) + if err != nil { + return fmt.Errorf("setting AAD only authentication for %s: %+v", id.String(), err) + } + + if err = aadOnlyEnabledFuture.WaitForCompletionRef(ctx, adminClient.Client); err != nil { + return fmt.Errorf("waiting for setting of AAD only authentication for %s: %+v", id.String(), err) + } + } } } @@ -494,6 +527,17 @@ func flattenSqlServerIdentity(identity *sql.ResourceIdentity) ([]interface{}, er return []interface{}{result}, nil } +func expandMsSqlServerAADOnlyAuthentictions(input []interface{}) bool { + if len(input) == 0 || input[0] == nil { + return false + } + admin := input[0].(map[string]interface{}) + if v, ok := admin["azuread_only_authentication"]; ok && v != nil { + return v.(bool) + } + return false +} + func expandMsSqlServerAdministrator(input []interface{}) *sql.ServerAzureADAdministrator { if len(input) == 0 || input[0] == nil { return nil @@ -532,11 +576,17 @@ func flatternMsSqlServerAdministrator(admin sql.ServerAzureADAdministrator) []in tid = admin.TenantID.String() } + var aadOnlyAuthentictionsEnabled bool + if admin.AzureADOnlyAuthentication != nil { + aadOnlyAuthentictionsEnabled = *admin.AzureADOnlyAuthentication + } + return []interface{}{ map[string]interface{}{ - "login_username": login, - "object_id": sid, - "tenant_id": tid, + "login_username": login, + "object_id": sid, + "tenant_id": tid, + "azuread_only_authentication": aadOnlyAuthentictionsEnabled, }, } } diff --git a/internal/services/mssql/mssql_server_resource_test.go b/internal/services/mssql/mssql_server_resource_test.go index c957eb1e87fed..030bbedd84bf0 100644 --- a/internal/services/mssql/mssql_server_resource_test.go +++ b/internal/services/mssql/mssql_server_resource_test.go @@ -618,8 +618,9 @@ resource "azurerm_mssql_server" "test" { administrator_login_password = "thisIsKat11" azuread_administrator { - login_username = "AzureAD Admin2" - object_id = data.azuread_service_principal.test.id + login_username = "AzureAD Admin2" + object_id = data.azuread_service_principal.test.id + azuread_only_authentication = true } } `, data.RandomInteger, data.Locations.Primary, os.Getenv("ARM_CLIENT_ID")) diff --git a/website/docs/r/mssql_server.html.markdown b/website/docs/r/mssql_server.html.markdown index 1bcf9b7dbfbef..cd77fa70dd47f 100644 --- a/website/docs/r/mssql_server.html.markdown +++ b/website/docs/r/mssql_server.html.markdown @@ -130,6 +130,8 @@ An `azuread_administrator` block supports the following: * `tenant_id` - (Optional) The tenant id of the Azure AD Administrator of this SQL Server. +* `azuread_only_authentication` - (Optional) Specifies whether only AD Users and administrators (like `azuread_administrator.0.login_username`) can be used to login or also local database users (like `administrator_login`). + --- An `extended_auditing_policy` block supports the following: