From c75dcdb3ba532fe00f4ad8e42835165c74e5ce47 Mon Sep 17 00:00:00 2001 From: Aris van Ommeren Date: Fri, 15 Oct 2021 12:27:42 +0200 Subject: [PATCH] `azurerm_mssql_server`: Set `azuread_administrator` inline on creation --- .../services/mssql/mssql_server_resource.go | 61 ++++++++++++------- .../mssql/mssql_server_resource_test.go | 15 +++++ 2 files changed, 55 insertions(+), 21 deletions(-) diff --git a/internal/services/mssql/mssql_server_resource.go b/internal/services/mssql/mssql_server_resource.go index e2843e03521bd..04dca154e60f5 100644 --- a/internal/services/mssql/mssql_server_resource.go +++ b/internal/services/mssql/mssql_server_resource.go @@ -266,6 +266,10 @@ func resourceMsSqlServerCreateUpdate(d *pluginsdk.ResourceData, meta interface{} props.ServerProperties.MinimalTLSVersion = utils.String(v.(string)) } + if azureADAdministrator, ok := d.GetOk("azuread_administrator"); d.IsNewResource() && ok { + props.ServerProperties.Administrators = expandMsSqlServerAdministrators(azureADAdministrator.([]interface{})) + } + future, err := client.CreateOrUpdate(ctx, id.ResourceGroup, id.Name, props) if err != nil { return fmt.Errorf("issuing create/update request for %s: %+v", id.String(), err) @@ -281,15 +285,7 @@ func resourceMsSqlServerCreateUpdate(d *pluginsdk.ResourceData, meta interface{} d.SetId(id.ID()) - if d.HasChange("azuread_administrator") { - adminDelFuture, err := adminClient.Delete(ctx, id.ResourceGroup, id.Name) - if err != nil { - return fmt.Errorf("deleting AAD admin %s: %+v", id.String(), err) - } - - if err = adminDelFuture.WaitForCompletionRef(ctx, adminClient.Client); err != nil { - return fmt.Errorf("waiting for deletion of AAD admin %s: %+v", id.String(), err) - } + if d.HasChange("azuread_administrator") && !d.IsNewResource() { if adminParams := expandMsSqlServerAdministrator(d.Get("azuread_administrator").([]interface{})); adminParams != nil { adminFuture, err := adminClient.CreateOrUpdate(ctx, id.ResourceGroup, id.Name, *adminParams) @@ -300,6 +296,15 @@ 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) } + } else { + adminDelFuture, err := adminClient.Delete(ctx, id.ResourceGroup, id.Name) + if err != nil { + return fmt.Errorf("deleting AAD admin %s: %+v", id.String(), err) + } + + if err = adminDelFuture.WaitForCompletionRef(ctx, adminClient.Client); err != nil { + return fmt.Errorf("waiting for deletion of AAD admin %s: %+v", id.String(), err) + } } } @@ -332,7 +337,6 @@ func resourceMsSqlServerRead(d *pluginsdk.ResourceData, meta interface{}) error client := meta.(*clients.Client).MSSQL.ServersClient auditingClient := meta.(*clients.Client).MSSQL.ServerExtendedBlobAuditingPoliciesClient connectionClient := meta.(*clients.Client).MSSQL.ServerConnectionPoliciesClient - adminClient := meta.(*clients.Client).MSSQL.ServerAzureADAdministratorsClient restorableDroppedDatabasesClient := meta.(*clients.Client).MSSQL.RestorableDroppedDatabasesClient ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() @@ -382,17 +386,10 @@ func resourceMsSqlServerRead(d *pluginsdk.ResourceData, meta interface{}) error primaryUserAssignedIdentityID = parsedPrimaryUserAssignedIdentityID.ID() } d.Set("primary_user_assigned_identity_id", primaryUserAssignedIdentityID) - } - - adminResp, err := adminClient.Get(ctx, id.ResourceGroup, id.Name) - if err != nil { - if !utils.ResponseWasNotFound(adminResp.Response) { - return fmt.Errorf("reading AAD admin %s: %v", id.Name, err) - } - } else { - if err := d.Set("azuread_administrator", flatternMsSqlServerAdministrator(adminResp)); err != nil { - return fmt.Errorf("setting `azuread_administrator`: %+v", err) + if props.Administrators != nil { + d.Set("azuread_administrator", flatternMsSqlServerAdministrators(*props.Administrators)) } + } connection, err := connectionClient.Get(ctx, id.ResourceGroup, id.Name) @@ -518,7 +515,29 @@ func expandMsSqlServerAdministrator(input []interface{}) *sql.ServerAzureADAdmin return &adminParams } -func flatternMsSqlServerAdministrator(admin sql.ServerAzureADAdministrator) []interface{} { +func expandMsSqlServerAdministrators(input []interface{}) *sql.ServerExternalAdministrator { + if len(input) == 0 || input[0] == nil { + return nil + } + + admin := input[0].(map[string]interface{}) + sid, _ := uuid.FromString(admin["object_id"].(string)) + + adminParams := sql.ServerExternalAdministrator{ + AdministratorType: sql.AdministratorTypeActiveDirectory, + Login: utils.String(admin["login_username"].(string)), + Sid: &sid, + } + + if v, ok := admin["tenant_id"]; ok && v != "" { + tid, _ := uuid.FromString(v.(string)) + adminParams.TenantID = &tid + } + + return &adminParams +} + +func flatternMsSqlServerAdministrators(admin sql.ServerExternalAdministrator) []interface{} { var login, sid, tid string if admin.Login != nil { login = *admin.Login diff --git a/internal/services/mssql/mssql_server_resource_test.go b/internal/services/mssql/mssql_server_resource_test.go index c957eb1e87fed..47f1a9bafbae2 100644 --- a/internal/services/mssql/mssql_server_resource_test.go +++ b/internal/services/mssql/mssql_server_resource_test.go @@ -132,6 +132,21 @@ func TestAccMsSqlServer_azureadAdmin(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_mssql_server", "test") r := MsSqlServerResource{} + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.aadAdmin(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("administrator_login_password"), + }) +} + +func TestAccMsSqlServer_azureadAdminUpdate(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_mssql_server", "test") + r := MsSqlServerResource{} + data.ResourceTest(t, r, []acceptance.TestStep{ { Config: r.basic(data),