Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

azurerm_postgresql_flexible_server - support replication_role and new enum value Replica for create_mode #20364

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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") {
catriona-m marked this conversation as resolved.
Show resolved Hide resolved
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