Skip to content

Commit

Permalink
Update azurerm_postgresql_server - Add identity support (#8044)
Browse files Browse the repository at this point in the history
This is one of the prerequisites of CMK for postgreSQL
  • Loading branch information
ArcturusZhang authored Aug 11, 2020
1 parent c24c141 commit c571f83
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,29 @@ func dataSourcePostgreSqlServer() *schema.Resource {
Computed: true,
},

"identity": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"type": {
Type: schema.TypeString,
Computed: true,
},

"principal_id": {
Type: schema.TypeString,
Computed: true,
},

"tenant_id": {
Type: schema.TypeString,
Computed: true,
},
},
},
},

"tags": tags.SchemaDataSource(),
},
}
Expand Down Expand Up @@ -85,6 +108,10 @@ func dataSourceArmPostgreSqlServerRead(d *schema.ResourceData, meta interface{})
d.Set("location", azure.NormalizeLocation(*location))
}

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

if props := resp.ServerProperties; props != nil {
d.Set("fqdn", props.FullyQualifiedDomainName)
d.Set("version", props.Version)
Expand Down
85 changes: 75 additions & 10 deletions azurerm/internal/services/postgres/postgresql_server_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/postgres/parse"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/postgres/validate"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags"
Expand Down Expand Up @@ -217,6 +216,33 @@ func resourceArmPostgreSQLServer() *schema.Resource {
ValidateFunc: validate.PostgresServerServerID,
},

"identity": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"type": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{
string(postgresql.SystemAssigned),
}, false),
},

"principal_id": {
Type: schema.TypeString,
Computed: true,
},

"tenant_id": {
Type: schema.TypeString,
Computed: true,
},
},
},
},

"infrastructure_encryption_enabled": {
Type: schema.TypeBool,
Optional: true,
Expand Down Expand Up @@ -379,17 +405,15 @@ func resourceArmPostgreSQLServerCreate(d *schema.ResourceData, meta interface{})
location := azure.NormalizeLocation(d.Get("location").(string))
resourceGroup := d.Get("resource_group_name").(string)

if features.ShouldResourcesBeImported() {
existing, err := client.Get(ctx, resourceGroup, name)
if err != nil {
if !utils.ResponseWasNotFound(existing.Response) {
return fmt.Errorf("checking for presence of existing PostgreSQL Server %q (Resource Group %q): %+v", name, resourceGroup, err)
}
existing, err := client.Get(ctx, resourceGroup, name)
if err != nil {
if !utils.ResponseWasNotFound(existing.Response) {
return fmt.Errorf("checking for presence of existing PostgreSQL Server %q (Resource Group %q): %+v", name, resourceGroup, err)
}
}

if existing.ID != nil && *existing.ID != "" {
return tf.ImportAsExistsError("azurerm_postgresql_server", *existing.ID)
}
if existing.ID != nil && *existing.ID != "" {
return tf.ImportAsExistsError("azurerm_postgresql_server", *existing.ID)
}

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

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

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

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

if props := resp.ServerProperties; props != nil {
d.Set("administrator_login", props.AdministratorLogin)
d.Set("ssl_enforcement", string(props.SslEnforcement))
Expand Down Expand Up @@ -881,3 +911,38 @@ func flattenSecurityAlertPolicy(props *postgresql.SecurityAlertPolicyProperties,

return []interface{}{block}
}

func expandServerIdentity(input []interface{}) *postgresql.ResourceIdentity {
if len(input) == 0 {
return nil
}

v := input[0].(map[string]interface{})
return &postgresql.ResourceIdentity{
Type: postgresql.IdentityType(v["type"].(string)),
}
}

func flattenServerIdentity(input *postgresql.ResourceIdentity) []interface{} {
if input == nil {
return []interface{}{}
}

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

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

return []interface{}{
map[string]interface{}{
"type": string(input.Type),
"principal_id": principalID,
"tenant_id": tenantID,
},
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,24 @@ func TestAccAzureRMPostgreSQLServer_basicEleven(t *testing.T) {
})
}

func TestAccAzureRMPostgreSQLServer_basicWithIdentity(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_postgresql_server", "test")
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
CheckDestroy: testCheckAzureRMPostgreSQLServerDestroy,
Steps: []resource.TestStep{
{
Config: testAccAzureRMPostgreSQLServer_basicWithIdentity(data, "11"),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMPostgreSQLServerExists(data.ResourceName),
),
},
data.ImportStep("administrator_login_password"),
},
})
}

func TestAccAzureRMPostgreSQLServer_autogrowOnly(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_postgresql_server", "test")

Expand Down Expand Up @@ -481,6 +499,38 @@ func testAccAzureRMPostgreSQLServer_basic(data acceptance.TestData, version stri
return testAccAzureRMPostgreSQLServer_template(data, "B_Gen5_1", version)
}

func testAccAzureRMPostgreSQLServer_basicWithIdentity(data acceptance.TestData, version string) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "test" {
name = "acctestRG-psql-%d"
location = "%s"
}
resource "azurerm_postgresql_server" "test" {
name = "acctest-psql-server-%d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
administrator_login = "acctestun"
administrator_login_password = "H@Sh1CoR3!"
sku_name = "B_Gen5_1"
version = "%s"
storage_mb = 51200
ssl_enforcement_enabled = true
identity {
type = "SystemAssigned"
}
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, version)
}

func testAccAzureRMPostgreSQLServer_mo(data acceptance.TestData, version string) string {
return testAccAzureRMPostgreSQLServer_template(data, "MO_Gen5_2", version)
}
Expand Down
12 changes: 12 additions & 0 deletions website/docs/d/postgresql_server.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ output "postgresql_server_id" {

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

* `identity` - An `identity` block as defined below.

* `version` - The version of the PostgreSQL Server.

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

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

---

An `identity` block exports the following:

* `principal_id` - The ID of the System Managed Service Principal assigned to the PostgreSQL Server.

* `tenant_id` - The ID of the Tenant of the System Managed Service Principal assigned to the PostgreSQL Server.

* `type` - The identity type of the Managed Identity assigned to the PostgreSQL Server.

## Timeouts

The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions:
Expand Down
22 changes: 18 additions & 4 deletions website/docs/r/postgresql_server.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ Manages a PostgreSQL Server.
## Example Usage

```hcl
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "example" {
name = "example-resources"
location = "West Europe"
Expand Down Expand Up @@ -72,6 +68,8 @@ The following arguments are supported:

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

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

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

~> **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.
Expand All @@ -92,6 +90,12 @@ The following arguments are supported:

---

A `identity` block supports the following:

* `type` - (Required) The Type of Identity which should be used for this PostgreSQL Server. At this time the only possible value is `SystemAssigned`.

---

a `threat_detection_policy` block supports the following:

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

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

* `identity` - An `identity` block as documented below.

---

A `identity` block exports the following:

* `principal_id` - The Client ID of the Service Principal assigned to this PostgreSQL Server.

* `tenant_id` - The ID of the Tenant the Service Principal is assigned in.

## Timeouts

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

0 comments on commit c571f83

Please sign in to comment.