Skip to content

Commit 5d9df60

Browse files
authored
azurerm_sql_managed_instance: Support for identity (hashicorp#14052)
Fixes hashicorp#14049
1 parent f0b3431 commit 5d9df60

File tree

3 files changed

+141
-5
lines changed

3 files changed

+141
-5
lines changed

internal/services/sql/sql_managed_instance_resource.go

+65-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/hashicorp/terraform-provider-azurerm/helpers/azure"
1414
"github.com/hashicorp/terraform-provider-azurerm/helpers/tf"
1515
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
16+
"github.com/hashicorp/terraform-provider-azurerm/internal/identity"
1617
"github.com/hashicorp/terraform-provider-azurerm/internal/services/mssql/validate"
1718
"github.com/hashicorp/terraform-provider-azurerm/internal/services/sql/parse"
1819
"github.com/hashicorp/terraform-provider-azurerm/internal/tags"
@@ -22,6 +23,8 @@ import (
2223
"github.com/hashicorp/terraform-provider-azurerm/utils"
2324
)
2425

26+
type managedInstanceIdentity = identity.SystemAssigned
27+
2528
func resourceArmSqlMiServer() *schema.Resource {
2629
return &schema.Resource{
2730
Create: resourceArmSqlMiServerCreateUpdate,
@@ -169,13 +172,22 @@ func resourceArmSqlMiServer() *schema.Resource {
169172
ValidateFunc: azure.ValidateResourceID,
170173
},
171174

175+
"identity": managedInstanceIdentity{}.Schema(),
176+
172177
"tags": tags.Schema(),
173178
},
174179

175-
CustomizeDiff: pluginsdk.ForceNewIfChange("dns_zone_partner_id", func(ctx context.Context, old, new, _ interface{}) bool {
180+
CustomizeDiff: pluginsdk.CustomDiffWithAll(
176181
// dns_zone_partner_id can only be set on init
177-
return old.(string) == "" && new.(string) != ""
178-
}),
182+
pluginsdk.ForceNewIfChange("dns_zone_partner_id", func(ctx context.Context, old, new, _ interface{}) bool {
183+
return old.(string) == "" && new.(string) != ""
184+
}),
185+
186+
// identity.0.type can be set to SystemAssigned, but not removed or set to None in this SDK version
187+
pluginsdk.ForceNewIfChange("identity.0.type", func(ctx context.Context, old, new, _ interface{}) bool {
188+
return old.(string) == "SystemAssigned" && new.(string) != "SystemAssigned"
189+
}),
190+
),
179191
}
180192
}
181193

@@ -227,6 +239,12 @@ func resourceArmSqlMiServerCreateUpdate(d *schema.ResourceData, meta interface{}
227239
},
228240
}
229241

242+
identity, err := expandManagedInstanceIdentity(d.Get("identity").([]interface{}))
243+
if err != nil {
244+
return fmt.Errorf(`expanding "identity": %v`, err)
245+
}
246+
parameters.Identity = identity
247+
230248
future, err := client.CreateOrUpdate(ctx, resGroup, name, parameters)
231249
if err != nil {
232250
return err
@@ -277,6 +295,10 @@ func resourceArmSqlMiServerRead(d *schema.ResourceData, meta interface{}) error
277295
d.Set("sku_name", sku.Name)
278296
}
279297

298+
if err := d.Set("identity", flattenManagedInstanceIdentity(resp.Identity)); err != nil {
299+
return fmt.Errorf("setting `identity`: %+v", err)
300+
}
301+
280302
if props := resp.ManagedInstanceProperties; props != nil {
281303
d.Set("license_type", props.LicenseType)
282304
d.Set("administrator_login", props.AdministratorLogin)
@@ -336,3 +358,43 @@ func expandManagedInstanceSkuName(skuName string) (*sql.Sku, error) {
336358
Family: utils.String(parts[1]),
337359
}, nil
338360
}
361+
362+
func expandManagedInstanceIdentity(input []interface{}) (*sql.ResourceIdentity, error) {
363+
config, err := managedInstanceIdentity{}.Expand(input)
364+
if err != nil {
365+
return nil, err
366+
}
367+
368+
if config.Type == identity.Type("None") {
369+
return nil, nil
370+
}
371+
372+
return &sql.ResourceIdentity{
373+
Type: sql.IdentityType(config.Type),
374+
}, nil
375+
}
376+
377+
func flattenManagedInstanceIdentity(input *sql.ResourceIdentity) []interface{} {
378+
var config *identity.ExpandedConfig
379+
380+
if input == nil {
381+
return []interface{}{}
382+
}
383+
384+
principalId := ""
385+
if input.PrincipalID != nil {
386+
principalId = input.PrincipalID.String()
387+
}
388+
389+
tenantId := ""
390+
if input.TenantID != nil {
391+
tenantId = input.TenantID.String()
392+
}
393+
394+
config = &identity.ExpandedConfig{
395+
Type: identity.Type(string(input.Type)),
396+
PrincipalId: principalId,
397+
TenantId: tenantId,
398+
}
399+
return managedInstanceIdentity{}.Flatten(config)
400+
}

internal/services/sql/sql_managed_instance_resource_test.go

+60-2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,31 @@ func TestAccAzureRMSqlMiServer_basic(t *testing.T) {
3131
})
3232
}
3333

34+
func TestAccAzureRMSqlMiServer_identity(t *testing.T) {
35+
data := acceptance.BuildTestData(t, "azurerm_sql_managed_instance", "test")
36+
r := SqlManagedInstanceResource{}
37+
38+
data.ResourceTest(t, r, []resource.TestStep{
39+
{
40+
Config: r.basic(data),
41+
Check: resource.ComposeTestCheckFunc(
42+
check.That(data.ResourceName).ExistsInAzure(r),
43+
check.That(data.ResourceName).Key("identity.#").HasValue("0"),
44+
),
45+
},
46+
data.ImportStep("administrator_login_password"),
47+
{
48+
Config: r.identity(data),
49+
Check: resource.ComposeTestCheckFunc(
50+
check.That(data.ResourceName).ExistsInAzure(r),
51+
check.That(data.ResourceName).Key("identity.#").HasValue("1"),
52+
check.That(data.ResourceName).Key("identity.0.type").HasValue("SystemAssigned"),
53+
),
54+
},
55+
data.ImportStep("administrator_login_password"),
56+
})
57+
}
58+
3459
func TestAccAzureRMSqlMiServer_update(t *testing.T) {
3560
data := acceptance.BuildTestData(t, "azurerm_sql_managed_instance", "test")
3661
r := SqlManagedInstanceResource{}
@@ -164,6 +189,39 @@ resource "azurerm_sql_managed_instance" "test" {
164189
`, r.template(data), data.RandomInteger)
165190
}
166191

192+
func (r SqlManagedInstanceResource) identity(data acceptance.TestData) string {
193+
return fmt.Sprintf(`
194+
%s
195+
196+
resource "azurerm_sql_managed_instance" "test" {
197+
name = "acctestsqlserver%d"
198+
resource_group_name = azurerm_resource_group.test.name
199+
location = azurerm_resource_group.test.location
200+
administrator_login = "mradministrator"
201+
administrator_login_password = "thisIsDog11"
202+
license_type = "BasePrice"
203+
subnet_id = azurerm_subnet.test.id
204+
sku_name = "GP_Gen5"
205+
vcores = 4
206+
storage_size_in_gb = 32
207+
208+
depends_on = [
209+
azurerm_subnet_network_security_group_association.test,
210+
azurerm_subnet_route_table_association.test,
211+
]
212+
213+
identity {
214+
type = "SystemAssigned"
215+
}
216+
217+
tags = {
218+
environment = "staging"
219+
database = "test"
220+
}
221+
}
222+
`, r.template(data), data.RandomInteger)
223+
}
224+
167225
func (r SqlManagedInstanceResource) update(data acceptance.TestData) string {
168226
return fmt.Sprintf(`
169227
%s
@@ -455,7 +513,7 @@ resource "azurerm_subnet" "test" {
455513
name = "subnet-%[1]d"
456514
resource_group_name = azurerm_resource_group.test.name
457515
virtual_network_name = azurerm_virtual_network.test.name
458-
address_prefix = "10.0.0.0/24"
516+
address_prefixes = ["10.0.0.0/24"]
459517
460518
delegation {
461519
name = "managedinstancedelegation"
@@ -1479,7 +1537,7 @@ resource "azurerm_subnet" "test1" {
14791537
name = "subnet2-%[1]d"
14801538
resource_group_name = azurerm_resource_group.test1.name
14811539
virtual_network_name = azurerm_virtual_network.test1.name
1482-
address_prefix = "10.1.0.0/24"
1540+
address_prefixes = ["10.1.0.0/24"]
14831541
14841542
delegation {
14851543
name = "managedinstancedelegation"

website/docs/r/sql_managed_instance.html.markdown

+16
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,8 @@ The following arguments are supported:
237237

238238
* `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.
239239

240+
* `identity` - (Optional) An `identity` block as defined below.
241+
240242
* `tags` - (Optional) A mapping of tags to assign to the resource.
241243

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

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

250+
---
251+
252+
An `identity` block supports the following:
253+
254+
* `type` - (Required) The identity type of the SQL Managed Instance. Only possible values is `SystemAssigned`.
255+
248256
## Attributes Reference
249257

250258
The following attributes are exported:
@@ -253,6 +261,14 @@ The following attributes are exported:
253261

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

264+
---
265+
266+
The `identity` block exports the following:
267+
268+
* `principal_id` - The Principal ID for the Service Principal associated with the Identity of this SQL Managed Instance.
269+
270+
* `tenant_id` - The Tenant ID for the Service Principal associated with the Identity of this SQL Managed Instance.
271+
256272
## Import
257273

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

0 commit comments

Comments
 (0)