Skip to content

Commit

Permalink
azurerm_postgresql_flexible_server - support creation without enabl…
Browse files Browse the repository at this point in the history
…ing password authtication (#20578)
  • Loading branch information
ziyeqf authored Feb 24, 2023
1 parent 73d1e56 commit 4b56bb7
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 34 deletions.
97 changes: 78 additions & 19 deletions internal/services/postgres/postgresql_flexible_server_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ func resourcePostgresqlFlexibleServer() *pluginsdk.Resource {
Type: pluginsdk.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ValidateFunc: validation.All(validation.StringIsNotWhiteSpace, validate.AdminUsernames),
},

Expand Down Expand Up @@ -288,7 +287,7 @@ func resourcePostgresqlFlexibleServer() *pluginsdk.Resource {
"tags": commonschema.Tags(),
},

CustomizeDiff: pluginsdk.CustomizeDiffShim(func(ctx context.Context, d *pluginsdk.ResourceDiff, v interface{}) error {
CustomizeDiff: pluginsdk.CustomDiffWithAll(func(ctx context.Context, d *pluginsdk.ResourceDiff, v interface{}) error {
createModeVal := d.Get("create_mode").(string)

if createModeVal == string(servers.CreateModeUpdate) {
Expand All @@ -315,7 +314,14 @@ func resourcePostgresqlFlexibleServer() *pluginsdk.Resource {
d.ForceNew("version")

return nil
}),
}, func(ctx context.Context, diff *pluginsdk.ResourceDiff, v interface{}) error {
oldLoginName, _ := diff.GetChange("administrator_login")
if oldLoginName != "" {
diff.ForceNew("administrator_login")
}
return nil
},
),
}
}

Expand Down Expand Up @@ -362,12 +368,28 @@ func resourcePostgresqlFlexibleServerCreate(d *pluginsdk.ResourceData, meta inte
}

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`")
_, adminLoginSet := d.GetOk("administrator_login")
_, adminPwdSet := d.GetOk("administrator_password")

pwdEnabled := true // it defaults to true
if authRaw, authExist := d.GetOk("authentication"); authExist {
authConfig := expandFlexibleServerAuthConfig(authRaw.([]interface{}))
if authConfig.PasswordAuth != nil {
pwdEnabled = *authConfig.PasswordAuth == servers.PasswordAuthEnumEnabled
}
}
if _, ok := d.GetOk("administrator_password"); !ok {
return fmt.Errorf("`administrator_password` is required when `create_mode` is `Default`")

if pwdEnabled {
if !adminLoginSet {
return fmt.Errorf("`administrator_login` is required when `create_mode` is `Default` and `authentication.password_auth_enabled` is set to `true`")
}
if !adminPwdSet {
return fmt.Errorf("`administrator_password` is required when `create_mode` is `Default` and `authentication.password_auth_enabled` is set to `true`")
}
} else if adminLoginSet || adminPwdSet {
return fmt.Errorf("`administrator_login` and `administrator_password` cannot be set when `authentication.password_auth_enabled` is set to `false`")
}

if _, ok := d.GetOk("sku_name"); !ok {
return fmt.Errorf("`sku_name` is required when `create_mode` is `Default`")
}
Expand Down Expand Up @@ -432,12 +454,8 @@ func resourcePostgresqlFlexibleServerCreate(d *pluginsdk.ResourceData, meta inte
parameters.Properties.PointInTimeUTC = utils.String(v.Format(time.RFC3339))
}

// if create with `password_auth_enabled` set to `false`, the service will not accept `administrator_login`.
// so we create it with `password_auth_enabled` set to `true`, then set it to `false` in an additional update.
if authRaw, ok := d.GetOk("authentication"); ok {
authConfig := expandFlexibleServerAuthConfig(authRaw.([]interface{}))
passwordAuthEnabled := servers.PasswordAuthEnumEnabled
authConfig.PasswordAuth = &passwordAuthEnabled
parameters.Properties.AuthConfig = authConfig
}

Expand All @@ -453,14 +471,6 @@ func resourcePostgresqlFlexibleServerCreate(d *pluginsdk.ResourceData, meta inte

requireAdditionalUpdate := false
updateProperties := servers.ServerPropertiesForUpdate{}
if authRaw, ok := d.GetOk("authentication"); ok {
authConfig := expandFlexibleServerAuthConfig(authRaw.([]interface{}))
if authConfig != nil && authConfig.PasswordAuth != nil && *authConfig.PasswordAuth == servers.PasswordAuthEnumDisabled {
requireAdditionalUpdate = true
updateProperties.AuthConfig = authConfig
}
}

// `maintenance_window` could only be updated with, could not be created with
if v, ok := d.GetOk("maintenance_window"); ok {
requireAdditionalUpdate = true
Expand Down Expand Up @@ -596,6 +606,38 @@ func resourcePostgresqlFlexibleServerUpdate(d *pluginsdk.ResourceData, meta inte
Properties: &servers.ServerPropertiesForUpdate{},
}

requireUpdateOnLogin := false // it's required to call Create with `createMode` set to `Update` to update login name.

createMode := d.Get("create_mode").(string)
if createMode == "" || servers.CreateMode(createMode) == servers.CreateModeDefault {

_, adminLoginSet := d.GetOk("administrator_login")
_, adminPwdSet := d.GetOk("administrator_password")

pwdEnabled := true // it defaults to true
if authRaw, authExist := d.GetOk("authentication"); authExist {
authConfig := expandFlexibleServerAuthConfig(authRaw.([]interface{}))
if authConfig.PasswordAuth != nil {
pwdEnabled = *authConfig.PasswordAuth == servers.PasswordAuthEnumEnabled
}
}

if pwdEnabled {
if !adminLoginSet {
return fmt.Errorf("`administrator_login` is required when `authentication.password_auth_enabled` is set to `true`")
}
if !adminPwdSet {
return fmt.Errorf("`administrator_password` is required when `authentication.password_auth_enabled` is set to `true`")
}
} else if adminLoginSet || adminPwdSet {
return fmt.Errorf("`administrator_login` and `administrator_password` cannot be set when `authentication.password_auth_enabled` is set to `false`")
}

if d.HasChange("administrator_login") {
requireUpdateOnLogin = true
}
}

var requireFailover bool
// failover is only supported when `zone` and `high_availability.0.standby_availability_zone` are exchanged with each other
if d.HasChanges("zone", "high_availability") {
Expand Down Expand Up @@ -713,6 +755,23 @@ func resourcePostgresqlFlexibleServerUpdate(d *pluginsdk.ResourceData, meta inte
parameters.Properties.Version = &version
}

if requireUpdateOnLogin {
updateMode := servers.CreateModeUpdate
loginParameters := servers.Server{
Location: location.Normalize(d.Get("location").(string)),
Properties: &servers.ServerProperties{
CreateMode: &updateMode,
AuthConfig: expandFlexibleServerAuthConfig(d.Get("authentication").([]interface{})),
AdministratorLogin: utils.String(d.Get("administrator_login").(string)),
AdministratorLoginPassword: utils.String(d.Get("administrator_password").(string)),
Network: expandArmServerNetwork(d),
},
}
if err = client.CreateThenPoll(ctx, *id, loginParameters); err != nil {
return fmt.Errorf("updating %s: %+v", id, err)
}
}

if err = client.UpdateThenPoll(ctx, *id, parameters); err != nil {
return fmt.Errorf("updating %s: %+v", id, err)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ func TestAccPostgresqlFlexibleServer_authConfig(t *testing.T) {
r := PostgresqlFlexibleServerResource{}
data.ResourceTest(t, r, []acceptance.TestStep{
{
// stats from pwdEnabled set to `false` to test add `admininistrator_login`
Config: r.authConfig(data, true, false),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
Expand Down Expand Up @@ -711,31 +712,38 @@ func (r PostgresqlFlexibleServerResource) authConfig(data acceptance.TestData, a
tenantIdBlock = "tenant_id = data.azurerm_client_config.current.tenant_id"
}

pwdBlock := ""
if pwdEnabled {
pwdBlock = `
administrator_login = "adminTerraform"
administrator_password = "QAZwsx123"
`
}

return fmt.Sprintf(`
%s
data "azurerm_client_config" "current" {
}
resource "azurerm_postgresql_flexible_server" "test" {
name = "acctest-fs-%d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
administrator_login = "adminTerraform"
administrator_password = "QAZwsx123"
storage_mb = 32768
version = "12"
sku_name = "GP_Standard_D2s_v3"
zone = "2"
name = "acctest-fs-%d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
%[3]s
storage_mb = 32768
version = "12"
sku_name = "GP_Standard_D2s_v3"
zone = "2"
authentication {
active_directory_auth_enabled = %[3]t
password_auth_enabled = %[4]t
%[5]s
active_directory_auth_enabled = %[4]t
password_auth_enabled = %[5]t
%[6]s
}
}
`, r.template(data), data.RandomInteger, aadEnabled, pwdEnabled, tenantIdBlock)
`, r.template(data), data.RandomInteger, pwdBlock, aadEnabled, pwdEnabled, tenantIdBlock)
}

func (r PostgresqlFlexibleServerResource) cmkTemplate(data acceptance.TestData) string {
Expand Down
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 @@ -88,9 +88,11 @@ The following arguments are supported:

* `location` - (Required) The Azure Region where the PostgreSQL Flexible Server should exist. Changing this forces a new PostgreSQL Flexible Server to be created.

* `administrator_login` - (Optional) The Administrator login for the PostgreSQL Flexible Server. Required when `create_mode` is `Default`. Changing this forces a new PostgreSQL Flexible Server to be created.
* `administrator_login` - (Optional) The Administrator login for the PostgreSQL Flexible Server. Required when `create_mode` is `Default` and `authentication.password_auth_enabled` is `true`.

* `administrator_password` - (Optional) The Password associated with the `administrator_login` for the PostgreSQL Flexible Server. Required when `create_mode` is `Default`.
-> **Note:** Once `administrator_login` is specified, changing this forces a new PostgreSQL Flexible Server to be created.

* `administrator_password` - (Optional) The Password associated with the `administrator_login` for the PostgreSQL Flexible Server. Required when `create_mode` is `Default` and `authentication.password_auth_enabled` is `true`.

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

Expand Down Expand Up @@ -148,6 +150,8 @@ An `authentication` block supports the following:

* `password_auth_enabled` - (Optional) Whether or not password authentication is allowed to access the PostgreSQL Flexible Server. Defaults to `true`.

-> **NOTE:** When `password_auth_enabled` is set to `false`, `administrator_login` and `administrator_password` must not be specified.

* `tenant_id` - (Optional) The Tenant ID of the Azure Active Directory which is used by the Active Directory authentication. `active_directory_auth_enabled` must be set to `true`.

-> **Note:** Setting `active_directory_auth_enabled` to `true` requires a Service Principal for the Postgres Flexible Server. For more details see [this document](https://learn.microsoft.com/en-us/azure/postgresql/flexible-server/how-to-configure-sign-in-azure-ad-authentication).
Expand Down

0 comments on commit 4b56bb7

Please sign in to comment.