Skip to content

Commit c571f83

Browse files
Update azurerm_postgresql_server - Add identity support (#8044)
This is one of the prerequisites of CMK for postgreSQL
1 parent c24c141 commit c571f83

5 files changed

+182
-14
lines changed

azurerm/internal/services/postgres/postgresql_server_data_source.go

+27
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,29 @@ func dataSourcePostgreSqlServer() *schema.Resource {
5353
Computed: true,
5454
},
5555

56+
"identity": {
57+
Type: schema.TypeList,
58+
Computed: true,
59+
Elem: &schema.Resource{
60+
Schema: map[string]*schema.Schema{
61+
"type": {
62+
Type: schema.TypeString,
63+
Computed: true,
64+
},
65+
66+
"principal_id": {
67+
Type: schema.TypeString,
68+
Computed: true,
69+
},
70+
71+
"tenant_id": {
72+
Type: schema.TypeString,
73+
Computed: true,
74+
},
75+
},
76+
},
77+
},
78+
5679
"tags": tags.SchemaDataSource(),
5780
},
5881
}
@@ -85,6 +108,10 @@ func dataSourceArmPostgreSqlServerRead(d *schema.ResourceData, meta interface{})
85108
d.Set("location", azure.NormalizeLocation(*location))
86109
}
87110

111+
if err := d.Set("identity", flattenServerIdentity(resp.Identity)); err != nil {
112+
return fmt.Errorf("setting `identity`: %+v", err)
113+
}
114+
88115
if props := resp.ServerProperties; props != nil {
89116
d.Set("fqdn", props.FullyQualifiedDomainName)
90117
d.Set("version", props.Version)

azurerm/internal/services/postgres/postgresql_server_resource.go

+75-10
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import (
1717
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress"
1818
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
1919
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
20-
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features"
2120
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/postgres/parse"
2221
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/postgres/validate"
2322
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags"
@@ -217,6 +216,33 @@ func resourceArmPostgreSQLServer() *schema.Resource {
217216
ValidateFunc: validate.PostgresServerServerID,
218217
},
219218

219+
"identity": {
220+
Type: schema.TypeList,
221+
Optional: true,
222+
MaxItems: 1,
223+
Elem: &schema.Resource{
224+
Schema: map[string]*schema.Schema{
225+
"type": {
226+
Type: schema.TypeString,
227+
Required: true,
228+
ValidateFunc: validation.StringInSlice([]string{
229+
string(postgresql.SystemAssigned),
230+
}, false),
231+
},
232+
233+
"principal_id": {
234+
Type: schema.TypeString,
235+
Computed: true,
236+
},
237+
238+
"tenant_id": {
239+
Type: schema.TypeString,
240+
Computed: true,
241+
},
242+
},
243+
},
244+
},
245+
220246
"infrastructure_encryption_enabled": {
221247
Type: schema.TypeBool,
222248
Optional: true,
@@ -379,17 +405,15 @@ func resourceArmPostgreSQLServerCreate(d *schema.ResourceData, meta interface{})
379405
location := azure.NormalizeLocation(d.Get("location").(string))
380406
resourceGroup := d.Get("resource_group_name").(string)
381407

382-
if features.ShouldResourcesBeImported() {
383-
existing, err := client.Get(ctx, resourceGroup, name)
384-
if err != nil {
385-
if !utils.ResponseWasNotFound(existing.Response) {
386-
return fmt.Errorf("checking for presence of existing PostgreSQL Server %q (Resource Group %q): %+v", name, resourceGroup, err)
387-
}
408+
existing, err := client.Get(ctx, resourceGroup, name)
409+
if err != nil {
410+
if !utils.ResponseWasNotFound(existing.Response) {
411+
return fmt.Errorf("checking for presence of existing PostgreSQL Server %q (Resource Group %q): %+v", name, resourceGroup, err)
388412
}
413+
}
389414

390-
if existing.ID != nil && *existing.ID != "" {
391-
return tf.ImportAsExistsError("azurerm_postgresql_server", *existing.ID)
392-
}
415+
if existing.ID != nil && *existing.ID != "" {
416+
return tf.ImportAsExistsError("azurerm_postgresql_server", *existing.ID)
393417
}
394418

395419
mode := postgresql.CreateMode(d.Get("create_mode").(string))
@@ -492,6 +516,7 @@ func resourceArmPostgreSQLServerCreate(d *schema.ResourceData, meta interface{})
492516
}
493517

494518
server := postgresql.ServerForCreate{
519+
Identity: expandServerIdentity(d.Get("identity").([]interface{})),
495520
Location: &location,
496521
Properties: props,
497522
Sku: sku,
@@ -566,6 +591,7 @@ func resourceArmPostgreSQLServerUpdate(d *schema.ResourceData, meta interface{})
566591
}
567592

568593
properties := postgresql.ServerUpdateParameters{
594+
Identity: expandServerIdentity(d.Get("identity").([]interface{})),
569595
ServerUpdateParametersProperties: &postgresql.ServerUpdateParametersProperties{
570596
AdministratorLoginPassword: utils.String(d.Get("administrator_login_password").(string)),
571597
PublicNetworkAccess: publicAccess,
@@ -638,6 +664,10 @@ func resourceArmPostgreSQLServerRead(d *schema.ResourceData, meta interface{}) e
638664
tier = sku.Tier
639665
}
640666

667+
if err := d.Set("identity", flattenServerIdentity(resp.Identity)); err != nil {
668+
return fmt.Errorf("setting `identity`: %+v", err)
669+
}
670+
641671
if props := resp.ServerProperties; props != nil {
642672
d.Set("administrator_login", props.AdministratorLogin)
643673
d.Set("ssl_enforcement", string(props.SslEnforcement))
@@ -881,3 +911,38 @@ func flattenSecurityAlertPolicy(props *postgresql.SecurityAlertPolicyProperties,
881911

882912
return []interface{}{block}
883913
}
914+
915+
func expandServerIdentity(input []interface{}) *postgresql.ResourceIdentity {
916+
if len(input) == 0 {
917+
return nil
918+
}
919+
920+
v := input[0].(map[string]interface{})
921+
return &postgresql.ResourceIdentity{
922+
Type: postgresql.IdentityType(v["type"].(string)),
923+
}
924+
}
925+
926+
func flattenServerIdentity(input *postgresql.ResourceIdentity) []interface{} {
927+
if input == nil {
928+
return []interface{}{}
929+
}
930+
931+
principalID := ""
932+
if input.PrincipalID != nil {
933+
principalID = input.PrincipalID.String()
934+
}
935+
936+
tenantID := ""
937+
if input.TenantID != nil {
938+
tenantID = input.TenantID.String()
939+
}
940+
941+
return []interface{}{
942+
map[string]interface{}{
943+
"type": string(input.Type),
944+
"principal_id": principalID,
945+
"tenant_id": tenantID,
946+
},
947+
}
948+
}

azurerm/internal/services/postgres/tests/postgresql_server_resource_test.go

+50
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,24 @@ func TestAccAzureRMPostgreSQLServer_basicEleven(t *testing.T) {
145145
})
146146
}
147147

148+
func TestAccAzureRMPostgreSQLServer_basicWithIdentity(t *testing.T) {
149+
data := acceptance.BuildTestData(t, "azurerm_postgresql_server", "test")
150+
resource.ParallelTest(t, resource.TestCase{
151+
PreCheck: func() { acceptance.PreCheck(t) },
152+
Providers: acceptance.SupportedProviders,
153+
CheckDestroy: testCheckAzureRMPostgreSQLServerDestroy,
154+
Steps: []resource.TestStep{
155+
{
156+
Config: testAccAzureRMPostgreSQLServer_basicWithIdentity(data, "11"),
157+
Check: resource.ComposeTestCheckFunc(
158+
testCheckAzureRMPostgreSQLServerExists(data.ResourceName),
159+
),
160+
},
161+
data.ImportStep("administrator_login_password"),
162+
},
163+
})
164+
}
165+
148166
func TestAccAzureRMPostgreSQLServer_autogrowOnly(t *testing.T) {
149167
data := acceptance.BuildTestData(t, "azurerm_postgresql_server", "test")
150168

@@ -481,6 +499,38 @@ func testAccAzureRMPostgreSQLServer_basic(data acceptance.TestData, version stri
481499
return testAccAzureRMPostgreSQLServer_template(data, "B_Gen5_1", version)
482500
}
483501

502+
func testAccAzureRMPostgreSQLServer_basicWithIdentity(data acceptance.TestData, version string) string {
503+
return fmt.Sprintf(`
504+
provider "azurerm" {
505+
features {}
506+
}
507+
508+
resource "azurerm_resource_group" "test" {
509+
name = "acctestRG-psql-%d"
510+
location = "%s"
511+
}
512+
513+
resource "azurerm_postgresql_server" "test" {
514+
name = "acctest-psql-server-%d"
515+
location = azurerm_resource_group.test.location
516+
resource_group_name = azurerm_resource_group.test.name
517+
518+
administrator_login = "acctestun"
519+
administrator_login_password = "H@Sh1CoR3!"
520+
521+
sku_name = "B_Gen5_1"
522+
version = "%s"
523+
storage_mb = 51200
524+
525+
ssl_enforcement_enabled = true
526+
527+
identity {
528+
type = "SystemAssigned"
529+
}
530+
}
531+
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, version)
532+
}
533+
484534
func testAccAzureRMPostgreSQLServer_mo(data acceptance.TestData, version string) string {
485535
return testAccAzureRMPostgreSQLServer_template(data, "MO_Gen5_2", version)
486536
}

website/docs/d/postgresql_server.html.markdown

+12
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ output "postgresql_server_id" {
3535

3636
* `fqdn` - The fully qualified domain name of the PostgreSQL Server.
3737

38+
* `identity` - An `identity` block as defined below.
39+
3840
* `version` - The version of the PostgreSQL Server.
3941

4042
* `administrator_login` - The administrator username of the PostgreSQL Server.
@@ -43,6 +45,16 @@ output "postgresql_server_id" {
4345

4446
* `tags` - A mapping of tags assigned to the resource.
4547

48+
---
49+
50+
An `identity` block exports the following:
51+
52+
* `principal_id` - The ID of the System Managed Service Principal assigned to the PostgreSQL Server.
53+
54+
* `tenant_id` - The ID of the Tenant of the System Managed Service Principal assigned to the PostgreSQL Server.
55+
56+
* `type` - The identity type of the Managed Identity assigned to the PostgreSQL Server.
57+
4658
## Timeouts
4759

4860
The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions:

website/docs/r/postgresql_server.html.markdown

+18-4
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@ Manages a PostgreSQL Server.
1313
## Example Usage
1414

1515
```hcl
16-
provider "azurerm" {
17-
features {}
18-
}
19-
2016
resource "azurerm_resource_group" "example" {
2117
name = "example-resources"
2218
location = "West Europe"
@@ -72,6 +68,8 @@ The following arguments are supported:
7268

7369
* `geo_redundant_backup_enabled` - (Optional) Turn Geo-redundant server backups on/off. This allows you to choose between locally redundant or geo-redundant backup storage in the General Purpose and Memory Optimized tiers. When the backups are stored in geo-redundant backup storage, they are not only stored within the region in which your server is hosted, but are also replicated to a paired data center. This provides better protection and ability to restore your server in a different region in the event of a disaster. This is not support for the Basic tier.
7470

71+
* `identity` - (Optional) An `identity` block as defined below.
72+
7573
* `infrastructure_encryption_enabled` - (Optional) Whether or not infrastructure is encrypted for this server. Defaults to `false`. Changing this forces a new resource to be created.
7674

7775
~> **NOTE:** This property is currently still in development and not supported by Microsoft. If the `infrastructure_encryption_enabled` attribute is set to `true` the postgreSQL instance will incur a substantial performance degradation due to a second encryption pass on top of the existing default encryption that is already provided by Azure Storage. It is strongly suggested to leave this value `false` as not doing so can lead to unclear error messages.
@@ -92,6 +90,12 @@ The following arguments are supported:
9290

9391
---
9492

93+
A `identity` block supports the following:
94+
95+
* `type` - (Required) The Type of Identity which should be used for this PostgreSQL Server. At this time the only possible value is `SystemAssigned`.
96+
97+
---
98+
9599
a `threat_detection_policy` block supports the following:
96100

97101
* `enabled` - (Required) Is the policy enabled?
@@ -117,6 +121,16 @@ The following attributes are exported:
117121

118122
* `fqdn` - The FQDN of the PostgreSQL Server.
119123

124+
* `identity` - An `identity` block as documented below.
125+
126+
---
127+
128+
A `identity` block exports the following:
129+
130+
* `principal_id` - The Client ID of the Service Principal assigned to this PostgreSQL Server.
131+
132+
* `tenant_id` - The ID of the Tenant the Service Principal is assigned in.
133+
120134
## Timeouts
121135

122136
The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions:

0 commit comments

Comments
 (0)