Skip to content

Commit

Permalink
azurerm_postgresql_flexible_server - support replication_role and…
Browse files Browse the repository at this point in the history
… new enum value `Replica` for `create_mode` (#20364)

* azurerm_postgresql_flexible_server - support for new properties replicationRole and replicaCapacity

* update code

* update code

* update code

* update code

* update code

* update code
  • Loading branch information
neil-yechenwei authored Feb 9, 2023
1 parent a78d868 commit ab4448f
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 2 deletions.
41 changes: 41 additions & 0 deletions internal/services/postgres/postgresql_flexible_server_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ func resourcePostgresqlFlexibleServer() *pluginsdk.Resource {
ValidateFunc: validation.StringInSlice([]string{
string(servers.CreateModeDefault),
string(servers.CreateModePointInTimeRestore),
string(servers.CreateModeReplica),
}, false),
},

Expand Down Expand Up @@ -248,6 +249,14 @@ func resourcePostgresqlFlexibleServer() *pluginsdk.Resource {
Computed: true,
},

"replication_role": {
Type: pluginsdk.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{
string(servers.ReplicationRoleNone),
}, false),
},

"identity": commonschema.SystemAssignedUserAssignedIdentityOptional(),

"customer_managed_key": {
Expand Down Expand Up @@ -303,6 +312,10 @@ func resourcePostgresqlFlexibleServerCreate(d *pluginsdk.ResourceData, meta inte

createMode := d.Get("create_mode").(string)

if _, ok := d.GetOk("replication_role"); ok {
return fmt.Errorf("`replication_role` cannot be set while creating")
}

if servers.CreateMode(createMode) == servers.CreateModePointInTimeRestore {
if _, ok := d.GetOk("source_server_id"); !ok {
return fmt.Errorf("`source_server_id` is required when `create_mode` is `PointInTimeRestore`")
Expand All @@ -312,6 +325,12 @@ func resourcePostgresqlFlexibleServerCreate(d *pluginsdk.ResourceData, meta inte
}
}

if servers.CreateMode(createMode) == servers.CreateModeReplica {
if _, ok := d.GetOk("source_server_id"); !ok {
return fmt.Errorf("`source_server_id` is required when `create_mode` is `Replica`")
}
}

if createMode == "" || servers.CreateMode(createMode) == servers.CreateModeDefault {
if _, ok := d.GetOk("administrator_login"); !ok {
return fmt.Errorf("`administrator_login` is required when `create_mode` is `Default`")
Expand Down Expand Up @@ -464,6 +483,9 @@ func resourcePostgresqlFlexibleServerRead(d *pluginsdk.ResourceData, meta interf
d.Set("version", props.Version)
d.Set("fqdn", props.FullyQualifiedDomainName)

// Currently, `replicationRole` is set to `Primary` when `createMode` is `Replica` and `replicationRole` is updated to `None`. Service team confirmed it should be set to `None` for this scenario. See more details from https://github.com/Azure/azure-rest-api-specs/issues/22499
d.Set("replication_role", d.Get("replication_role").(string))

if network := props.Network; network != nil {
publicNetworkAccess := false
if network.PublicNetworkAccess != nil {
Expand Down Expand Up @@ -584,6 +606,25 @@ func resourcePostgresqlFlexibleServerUpdate(d *pluginsdk.ResourceData, meta inte
}
}

if d.HasChange("replication_role") {
createMode := d.Get("create_mode").(string)
replicationRole := d.Get("replication_role").(string)
if createMode == string(servers.CreateModeReplica) && replicationRole == string(servers.ReplicationRoleNone) {
replicationRole := servers.ReplicationRoleNone
parameters := servers.ServerForUpdate{
Properties: &servers.ServerPropertiesForUpdate{
ReplicationRole: &replicationRole,
},
}

if err := client.UpdateThenPoll(ctx, *id, parameters); err != nil {
return fmt.Errorf("updating `replication_role` for %s: %+v", *id, err)
}
} else {
return fmt.Errorf("`replication_role` only can be updated to `None` for replica server")
}
}

if d.HasChange("administrator_password") {
parameters.Properties.AdministratorLoginPassword = utils.String(d.Get("administrator_password").(string))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,36 @@ func TestAccPostgresqlFlexibleServer_createWithCustomerManagedKey(t *testing.T)
})
}

func TestAccPostgresqlFlexibleServer_replica(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_postgresql_flexible_server", "test")
r := PostgresqlFlexibleServerResource{}

data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.basic(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep("administrator_password", "create_mode"),
{
PreConfig: func() { time.Sleep(15 * time.Minute) },
Config: r.replica(data),
Check: acceptance.ComposeTestCheckFunc(
check.That("azurerm_postgresql_flexible_server.replica").ExistsInAzure(r),
),
},
data.ImportStep("administrator_password", "create_mode"),
{
Config: r.updateReplicationRole(data),
Check: acceptance.ComposeTestCheckFunc(
check.That("azurerm_postgresql_flexible_server.replica").ExistsInAzure(r),
),
},
data.ImportStep("administrator_password", "create_mode"),
})
}

func (PostgresqlFlexibleServerResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) {
id, err := servers.ParseFlexibleServerID(state.ID)
if err != nil {
Expand Down Expand Up @@ -777,3 +807,34 @@ resource "azurerm_postgresql_flexible_server" "test" {
}
`, r.cmkTemplate(data), data.RandomInteger)
}

func (r PostgresqlFlexibleServerResource) replica(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
resource "azurerm_postgresql_flexible_server" "replica" {
name = "acctest-fs-replica-%d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
zone = "2"
create_mode = "Replica"
source_server_id = azurerm_postgresql_flexible_server.test.id
}
`, r.basic(data), data.RandomInteger)
}

func (r PostgresqlFlexibleServerResource) updateReplicationRole(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
resource "azurerm_postgresql_flexible_server" "replica" {
name = "acctest-fs-replica-%d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
zone = "2"
create_mode = "Replica"
source_server_id = azurerm_postgresql_flexible_server.test.id
replication_role = "None"
}
`, r.basic(data), data.RandomInteger)
}
8 changes: 6 additions & 2 deletions website/docs/r/postgresql_flexible_server.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ The following arguments are supported:

* `geo_redundant_backup_enabled` - (Optional) Is Geo-Redundant backup enabled on the PostgreSQL Flexible Server. Defaults to `false`. Changing this forces a new PostgreSQL Flexible Server to be created.

* `create_mode` - (Optional) The creation mode which can be used to restore or replicate existing servers. Possible values are `Default` and `PointInTimeRestore`. Changing this forces a new PostgreSQL Flexible Server to be created.
* `create_mode` - (Optional) The creation mode which can be used to restore or replicate existing servers. Possible values are `Default`, `PointInTimeRestore` and `Replica`. Changing this forces a new PostgreSQL Flexible Server to be created.

* `delegated_subnet_id` - (Optional) The ID of the virtual network subnet to create the PostgreSQL Flexible Server. The provided subnet should not have any other resource deployed in it and this subnet will be delegated to the PostgreSQL Flexible Server, if not already delegated. Changing this forces a new PostgreSQL Flexible Server to be created.

Expand All @@ -116,9 +116,13 @@ The following arguments are supported:

* `point_in_time_restore_time_in_utc` - (Optional) The point in time to restore from `source_server_id` when `create_mode` is `PointInTimeRestore`. Changing this forces a new PostgreSQL Flexible Server to be created.

* `replication_role` - (Optional) The replication role for the PostgreSQL Flexible Server. Possible value is `None`.

~> **NOTE:** The `replication_role` cannot be set while creating and only can be updated to `None` for replica server.

* `sku_name` - (Optional) The SKU Name for the PostgreSQL Flexible Server. The name of the SKU, follows the `tier` + `name` pattern (e.g. `B_Standard_B1ms`, `GP_Standard_D2s_v3`, `MO_Standard_E4s_v3`).

* `source_server_id` - (Optional) The resource ID of the source PostgreSQL Flexible Server to be restored. Required when `create_mode` is `PointInTimeRestore`. Changing this forces a new PostgreSQL Flexible Server to be created.
* `source_server_id` - (Optional) The resource ID of the source PostgreSQL Flexible Server to be restored. Required when `create_mode` is `PointInTimeRestore` or `Replica`. Changing this forces a new PostgreSQL Flexible Server to be created.

* `storage_mb` - (Optional) The max storage allowed for the PostgreSQL Flexible Server. Possible values are `32768`, `65536`, `131072`, `262144`, `524288`, `1048576`, `2097152`, `4194304`, `8388608`, and `16777216`.

Expand Down

0 comments on commit ab4448f

Please sign in to comment.