Skip to content

Commit

Permalink
azurerm_postgresql_server - Fixed issue with creating Postgres serv…
Browse files Browse the repository at this point in the history
…er in `Replica` mode (#18805)
  • Loading branch information
dkuzmenok authored Oct 24, 2022
1 parent f0935aa commit 67cf9ad
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 15 deletions.
9 changes: 7 additions & 2 deletions internal/services/postgres/postgresql_server_key_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ func resourcePostgreSQLServerKeyCreateUpdate(d *pluginsdk.ResourceData, meta int
locks.ByName(serverId.ServerName, postgreSQLServerResourceName)
defer locks.UnlockByName(serverId.ServerName, postgreSQLServerResourceName)

id := serverkeys.NewKeyID(serverId.SubscriptionId, serverId.ResourceGroupName, serverId.ServerName, *name)

if d.IsNewResource() {
// This resource is a singleton, but its name can be anything.
// If you create a new key with different name with the old key, the service will not give you any warning but directly replace the old key with the new key.
Expand All @@ -112,7 +114,11 @@ func resourcePostgreSQLServerKeyCreateUpdate(d *pluginsdk.ResourceData, meta int
return fmt.Errorf("parsing existing Server Key ID %q: %+v", *rawId, err)
}

return tf.ImportAsExistsError("azurerm_postgresql_server_key", id.ID())
// API allows adding same key again with Create action, which would trigger revalidation of the key on the server.
// This is required to revalidate Replica server after creation.
if *rawId != id.ID() {
return tf.ImportAsExistsError("azurerm_postgresql_server_key", id.ID())
}
}
}
}
Expand All @@ -124,7 +130,6 @@ func resourcePostgreSQLServerKeyCreateUpdate(d *pluginsdk.ResourceData, meta int
},
}

id := serverkeys.NewKeyID(serverId.SubscriptionId, serverId.ResourceGroupName, serverId.ServerName, *name)
if err = keysClient.CreateOrUpdateThenPoll(ctx, id, param); err != nil {
return fmt.Errorf("creating/updating %s: %+v", id, err)
}
Expand Down
74 changes: 62 additions & 12 deletions internal/services/postgres/postgresql_server_key_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,22 @@ func TestAccPostgreSQLServerKey_requiresImport(t *testing.T) {
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.RequiresImportErrorStep(r.requiresImport),
data.ImportStep(),
})
}

func TestAccPostgreSQLServerKey_replica(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_postgresql_server_key", "test")
r := PostgreSQLServerKeyResource{}

data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.replica(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
})
}

Expand Down Expand Up @@ -171,17 +186,6 @@ resource "azurerm_postgresql_server_key" "test" {
`, r.template(data))
}

func (r PostgreSQLServerKeyResource) requiresImport(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
resource "azurerm_postgresql_server_key" "import" {
server_id = azurerm_postgresql_server_key.test.server_id
key_vault_key_id = azurerm_postgresql_server_key.test.key_vault_key_id
}
`, r.basic(data))
}

func (r PostgreSQLServerKeyResource) updated(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
Expand All @@ -205,3 +209,49 @@ resource "azurerm_postgresql_server_key" "test" {
}
`, r.template(data))
}

func (r PostgreSQLServerKeyResource) replica(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
resource "azurerm_postgresql_server_key" "test" {
server_id = azurerm_postgresql_server.test.id
key_vault_key_id = azurerm_key_vault_key.first.id
}
resource "azurerm_key_vault_access_policy" "replica" {
key_vault_id = azurerm_key_vault.test.id
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = azurerm_postgresql_server.replica.identity.0.principal_id
key_permissions = ["Get", "UnwrapKey", "WrapKey"]
secret_permissions = ["Get"]
}
resource "azurerm_resource_group" "replica" {
name = "acctestRG-psql-%d-replica"
location = "%s"
}
resource "azurerm_postgresql_server" "replica" {
name = "acctest-postgre-replica-%d"
location = azurerm_resource_group.replica.location
resource_group_name = azurerm_resource_group.replica.name
create_mode = "Replica"
creation_source_server_id = azurerm_postgresql_server.test.id
sku_name = "GP_Gen5_2"
version = "11"
storage_mb = 51200
ssl_enforcement_enabled = true
identity {
type = "SystemAssigned"
}
}
`, r.template(data), data.RandomInteger, data.Locations.Primary, data.RandomInteger)
}
12 changes: 11 additions & 1 deletion internal/services/postgres/postgresql_server_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -519,8 +519,9 @@ func resourcePostgreSQLServerCreate(d *pluginsdk.ResourceData, meta interface{})

// Issue tracking the REST API update failure: https://github.com/Azure/azure-rest-api-specs/issues/14117
if mode == servers.CreateModeReplica {
log.Printf("[INFO] updating `public_network_access_enabled` for %s", id)
log.Printf("[INFO] updating `public_network_access_enabled` and `identity` for %s", id)
properties := servers.ServerUpdateParameters{
Identity: expandedIdentity,
Properties: &servers.ServerUpdateParametersProperties{
PublicNetworkAccess: &publicAccess,
},
Expand Down Expand Up @@ -994,6 +995,15 @@ func postgreSqlStateRefreshFunc(ctx context.Context, client *servers.ServersClie
return nil, "", fmt.Errorf("retrieving status of %s: %+v", id, err)
}

// For Replica servers, with enabled BYOK, state would be reported as 'Inaccessible', even when deployment was in 'Succeeded' state.
// It is caused by a need to revalidate the key.
if res.Model != nil && res.Model.Properties != nil &&
res.Model.Properties.ReplicationRole != nil && *res.Model.Properties.ReplicationRole == "Replica" &&
res.Model.Properties.ByokEnforcement != nil && *res.Model.Properties.ByokEnforcement == "Enabled" &&
res.Model.Properties.UserVisibleState != nil && *res.Model.Properties.UserVisibleState == servers.ServerStateInaccessible {
return res, string(servers.ServerStateReady), nil
}

// This is an issue with the RP, there is a 10 to 15 second lag before the
// service will actually return the server
if response.WasNotFound(res.HttpResponse) {
Expand Down

0 comments on commit 67cf9ad

Please sign in to comment.