Skip to content

Commit

Permalink
azurerm_sql_managed_instance: Support for identity (hashicorp#14052)
Browse files Browse the repository at this point in the history
  • Loading branch information
aristosvo authored Nov 12, 2021
1 parent f0b3431 commit 5d9df60
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 5 deletions.
68 changes: 65 additions & 3 deletions internal/services/sql/sql_managed_instance_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/hashicorp/terraform-provider-azurerm/helpers/azure"
"github.com/hashicorp/terraform-provider-azurerm/helpers/tf"
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/identity"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/mssql/validate"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/sql/parse"
"github.com/hashicorp/terraform-provider-azurerm/internal/tags"
Expand All @@ -22,6 +23,8 @@ import (
"github.com/hashicorp/terraform-provider-azurerm/utils"
)

type managedInstanceIdentity = identity.SystemAssigned

func resourceArmSqlMiServer() *schema.Resource {
return &schema.Resource{
Create: resourceArmSqlMiServerCreateUpdate,
Expand Down Expand Up @@ -169,13 +172,22 @@ func resourceArmSqlMiServer() *schema.Resource {
ValidateFunc: azure.ValidateResourceID,
},

"identity": managedInstanceIdentity{}.Schema(),

"tags": tags.Schema(),
},

CustomizeDiff: pluginsdk.ForceNewIfChange("dns_zone_partner_id", func(ctx context.Context, old, new, _ interface{}) bool {
CustomizeDiff: pluginsdk.CustomDiffWithAll(
// dns_zone_partner_id can only be set on init
return old.(string) == "" && new.(string) != ""
}),
pluginsdk.ForceNewIfChange("dns_zone_partner_id", func(ctx context.Context, old, new, _ interface{}) bool {
return old.(string) == "" && new.(string) != ""
}),

// identity.0.type can be set to SystemAssigned, but not removed or set to None in this SDK version
pluginsdk.ForceNewIfChange("identity.0.type", func(ctx context.Context, old, new, _ interface{}) bool {
return old.(string) == "SystemAssigned" && new.(string) != "SystemAssigned"
}),
),
}
}

Expand Down Expand Up @@ -227,6 +239,12 @@ func resourceArmSqlMiServerCreateUpdate(d *schema.ResourceData, meta interface{}
},
}

identity, err := expandManagedInstanceIdentity(d.Get("identity").([]interface{}))
if err != nil {
return fmt.Errorf(`expanding "identity": %v`, err)
}
parameters.Identity = identity

future, err := client.CreateOrUpdate(ctx, resGroup, name, parameters)
if err != nil {
return err
Expand Down Expand Up @@ -277,6 +295,10 @@ func resourceArmSqlMiServerRead(d *schema.ResourceData, meta interface{}) error
d.Set("sku_name", sku.Name)
}

if err := d.Set("identity", flattenManagedInstanceIdentity(resp.Identity)); err != nil {
return fmt.Errorf("setting `identity`: %+v", err)
}

if props := resp.ManagedInstanceProperties; props != nil {
d.Set("license_type", props.LicenseType)
d.Set("administrator_login", props.AdministratorLogin)
Expand Down Expand Up @@ -336,3 +358,43 @@ func expandManagedInstanceSkuName(skuName string) (*sql.Sku, error) {
Family: utils.String(parts[1]),
}, nil
}

func expandManagedInstanceIdentity(input []interface{}) (*sql.ResourceIdentity, error) {
config, err := managedInstanceIdentity{}.Expand(input)
if err != nil {
return nil, err
}

if config.Type == identity.Type("None") {
return nil, nil
}

return &sql.ResourceIdentity{
Type: sql.IdentityType(config.Type),
}, nil
}

func flattenManagedInstanceIdentity(input *sql.ResourceIdentity) []interface{} {
var config *identity.ExpandedConfig

if input == nil {
return []interface{}{}
}

principalId := ""
if input.PrincipalID != nil {
principalId = input.PrincipalID.String()
}

tenantId := ""
if input.TenantID != nil {
tenantId = input.TenantID.String()
}

config = &identity.ExpandedConfig{
Type: identity.Type(string(input.Type)),
PrincipalId: principalId,
TenantId: tenantId,
}
return managedInstanceIdentity{}.Flatten(config)
}
62 changes: 60 additions & 2 deletions internal/services/sql/sql_managed_instance_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,31 @@ func TestAccAzureRMSqlMiServer_basic(t *testing.T) {
})
}

func TestAccAzureRMSqlMiServer_identity(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_sql_managed_instance", "test")
r := SqlManagedInstanceResource{}

data.ResourceTest(t, r, []resource.TestStep{
{
Config: r.basic(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
check.That(data.ResourceName).Key("identity.#").HasValue("0"),
),
},
data.ImportStep("administrator_login_password"),
{
Config: r.identity(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
check.That(data.ResourceName).Key("identity.#").HasValue("1"),
check.That(data.ResourceName).Key("identity.0.type").HasValue("SystemAssigned"),
),
},
data.ImportStep("administrator_login_password"),
})
}

func TestAccAzureRMSqlMiServer_update(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_sql_managed_instance", "test")
r := SqlManagedInstanceResource{}
Expand Down Expand Up @@ -164,6 +189,39 @@ resource "azurerm_sql_managed_instance" "test" {
`, r.template(data), data.RandomInteger)
}

func (r SqlManagedInstanceResource) identity(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
resource "azurerm_sql_managed_instance" "test" {
name = "acctestsqlserver%d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
administrator_login = "mradministrator"
administrator_login_password = "thisIsDog11"
license_type = "BasePrice"
subnet_id = azurerm_subnet.test.id
sku_name = "GP_Gen5"
vcores = 4
storage_size_in_gb = 32
depends_on = [
azurerm_subnet_network_security_group_association.test,
azurerm_subnet_route_table_association.test,
]
identity {
type = "SystemAssigned"
}
tags = {
environment = "staging"
database = "test"
}
}
`, r.template(data), data.RandomInteger)
}

func (r SqlManagedInstanceResource) update(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
Expand Down Expand Up @@ -455,7 +513,7 @@ resource "azurerm_subnet" "test" {
name = "subnet-%[1]d"
resource_group_name = azurerm_resource_group.test.name
virtual_network_name = azurerm_virtual_network.test.name
address_prefix = "10.0.0.0/24"
address_prefixes = ["10.0.0.0/24"]
delegation {
name = "managedinstancedelegation"
Expand Down Expand Up @@ -1479,7 +1537,7 @@ resource "azurerm_subnet" "test1" {
name = "subnet2-%[1]d"
resource_group_name = azurerm_resource_group.test1.name
virtual_network_name = azurerm_virtual_network.test1.name
address_prefix = "10.1.0.0/24"
address_prefixes = ["10.1.0.0/24"]
delegation {
name = "managedinstancedelegation"
Expand Down
16 changes: 16 additions & 0 deletions website/docs/r/sql_managed_instance.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@ The following arguments are supported:

* `dns_zone_partner_id` - (Optional) The ID of the Managed Instance which will share the DNS zone. This is a prerequisite for creating a failover group, although creation of a failover group is not yet possible in `azurerm`. Setting this after creation forces a new resource to be created.

* `identity` - (Optional) An `identity` block as defined below.

* `tags` - (Optional) A mapping of tags to assign to the resource.

---
Expand All @@ -245,6 +247,12 @@ A `sku` block supports the following:

* `name` - (Required) Sku of the managed instance. Values can be `GP_Gen4`, `GP_Gen5`, `BC_Gen4`, or `BC_Gen5`.

---

An `identity` block supports the following:

* `type` - (Required) The identity type of the SQL Managed Instance. Only possible values is `SystemAssigned`.

## Attributes Reference

The following attributes are exported:
Expand All @@ -253,6 +261,14 @@ The following attributes are exported:

* `fqdn` - The fully qualified domain name of the Azure Managed SQL Instance

---

The `identity` block exports the following:

* `principal_id` - The Principal ID for the Service Principal associated with the Identity of this SQL Managed Instance.

* `tenant_id` - The Tenant ID for the Service Principal associated with the Identity of this SQL Managed Instance.

## Import

SQL Servers can be imported using the `resource id`, e.g.
Expand Down

0 comments on commit 5d9df60

Please sign in to comment.