Skip to content

Commit 4b6a688

Browse files
authored
azurerm_mysql_flexible_server - add administrator_password_wo and administrator_password_wo_version (#28799)
* add administrator_password_wo to mysql flexible server * add wo attribute to docs * import ordering * review comments
1 parent e9ae9f3 commit 4b6a688

File tree

3 files changed

+136
-10
lines changed

3 files changed

+136
-10
lines changed

internal/services/mysql/mysql_flexible_server_resource.go

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ import (
2020
"github.com/hashicorp/go-azure-sdk/resource-manager/mysql/2023-12-30/serverfailover"
2121
"github.com/hashicorp/go-azure-sdk/resource-manager/mysql/2023-12-30/servers"
2222
"github.com/hashicorp/go-azure-sdk/resource-manager/privatedns/2024-06-01/privatezones"
23+
"github.com/hashicorp/go-cty/cty"
24+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
25+
pluginSdkValidation "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
2326
"github.com/hashicorp/terraform-provider-azurerm/helpers/tf"
2427
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
2528
keyVaultValidate "github.com/hashicorp/terraform-provider-azurerm/internal/services/keyvault/validate"
@@ -56,6 +59,10 @@ func resourceMysqlFlexibleServer() *pluginsdk.Resource {
5659
return err
5760
}),
5861

62+
ValidateRawResourceConfigFuncs: []schema.ValidateRawResourceConfigFunc{
63+
pluginSdkValidation.PreferWriteOnlyAttribute(cty.GetAttrPath("administrator_password"), cty.GetAttrPath("administrator_password_wo")),
64+
},
65+
5966
Schema: map[string]*pluginsdk.Schema{
6067
"name": {
6168
Type: pluginsdk.TypeString,
@@ -77,10 +84,26 @@ func resourceMysqlFlexibleServer() *pluginsdk.Resource {
7784
},
7885

7986
"administrator_password": {
80-
Type: pluginsdk.TypeString,
87+
Type: pluginsdk.TypeString,
88+
Optional: true,
89+
Sensitive: true,
90+
ValidateFunc: validate.FlexibleServerAdministratorPassword,
91+
ConflictsWith: []string{"administrator_password_wo"},
92+
},
93+
94+
"administrator_password_wo": {
95+
Type: pluginsdk.TypeString,
96+
Optional: true,
97+
WriteOnly: true,
98+
ConflictsWith: []string{"administrator_password"},
99+
RequiredWith: []string{"administrator_password_wo_version"},
100+
ValidateFunc: validate.FlexibleServerAdministratorPassword,
101+
},
102+
103+
"administrator_password_wo_version": {
104+
Type: pluginsdk.TypeInt,
81105
Optional: true,
82-
Sensitive: true,
83-
ValidateFunc: validate.FlexibleServerAdministratorPassword,
106+
RequiredWith: []string{"administrator_password_wo"},
84107
},
85108

86109
"backup_retention_days": {
@@ -338,6 +361,11 @@ func resourceMysqlFlexibleServerCreate(d *pluginsdk.ResourceData, meta interface
338361
return tf.ImportAsExistsError("azurerm_mysql_flexible_server", id.ID())
339362
}
340363

364+
woPassword, err := pluginsdk.GetWriteOnly(d, "administrator_password_wo", cty.String)
365+
if err != nil {
366+
return err
367+
}
368+
341369
createMode := servers.CreateMode(d.Get("create_mode").(string))
342370

343371
if _, ok := d.GetOk("replication_role"); ok {
@@ -360,9 +388,11 @@ func resourceMysqlFlexibleServerCreate(d *pluginsdk.ResourceData, meta interface
360388
if _, ok := d.GetOk("administrator_login"); !ok {
361389
return fmt.Errorf("`administrator_login` is required when `create_mode` is `Default`")
362390
}
363-
if _, ok := d.GetOk("administrator_password"); !ok {
364-
return fmt.Errorf("`administrator_password` is required when `create_mode` is `Default`")
391+
392+
if _, ok := d.GetOk("administrator_password"); !ok && woPassword.IsNull() {
393+
return fmt.Errorf("`administrator_password_wo` or `administrator_password` is required when `create_mode` is `Default`")
365394
}
395+
366396
if _, ok := d.GetOk("sku_name"); !ok {
367397
return fmt.Errorf("`sku_name` is required when `create_mode` is `Default`")
368398
}
@@ -404,6 +434,10 @@ func resourceMysqlFlexibleServerCreate(d *pluginsdk.ResourceData, meta interface
404434
parameters.Properties.AdministratorLoginPassword = utils.String(v.(string))
405435
}
406436

437+
if !woPassword.IsNull() {
438+
parameters.Properties.AdministratorLoginPassword = pointer.To(woPassword.AsString())
439+
}
440+
407441
if v, ok := d.GetOk("zone"); ok && v.(string) != "" {
408442
parameters.Properties.AvailabilityZone = utils.String(v.(string))
409443
}
@@ -557,6 +591,8 @@ func resourceMysqlFlexibleServerRead(d *pluginsdk.ResourceData, meta interface{}
557591
}
558592
d.Set("sku_name", sku)
559593

594+
d.Set("administrator_password_wo_version", d.Get("administrator_password_wo_version").(int))
595+
560596
return tags.FlattenAndSet(d, model.Tags)
561597
}
562598

@@ -674,6 +710,16 @@ func resourceMysqlFlexibleServerUpdate(d *pluginsdk.ResourceData, meta interface
674710
parameters.Properties.AdministratorLoginPassword = utils.String(d.Get("administrator_password").(string))
675711
}
676712

713+
if d.HasChange("administrator_password_wo_version") {
714+
woPassword, err := pluginsdk.GetWriteOnly(d, "administrator_password_wo", cty.String)
715+
if err != nil {
716+
return err
717+
}
718+
if !woPassword.IsNull() {
719+
parameters.Properties.AdministratorLoginPassword = pointer.To(woPassword.AsString())
720+
}
721+
}
722+
677723
if d.HasChange("backup_retention_days") || d.HasChange("geo_redundant_backup_enabled") {
678724
parameters.Properties.Backup = expandArmServerBackup(d)
679725
}

internal/services/mysql/mysql_flexible_server_resource_test.go

Lines changed: 78 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,16 @@ import (
1010
"testing"
1111
"time"
1212

13+
"github.com/hashicorp/go-azure-helpers/lang/pointer"
1314
"github.com/hashicorp/go-azure-sdk/resource-manager/mysql/2023-12-30/servers"
15+
"github.com/hashicorp/go-version"
16+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
17+
"github.com/hashicorp/terraform-plugin-testing/tfversion"
1418
"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance"
1519
"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check"
1620
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
21+
"github.com/hashicorp/terraform-provider-azurerm/internal/provider/framework"
1722
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
18-
"github.com/hashicorp/terraform-provider-azurerm/utils"
1923
)
2024

2125
type MySqlFlexibleServerResource struct{}
@@ -473,7 +477,7 @@ func TestAccMySqlFlexibleServer_updateToCustomerManagedKey(t *testing.T) {
473477
})
474478
}
475479

476-
// this test can fail with a uninformative error, tracked here https://github.com/Azure/azure-rest-api-specs/issues/22980
480+
// this test can fail with an uninformative error, tracked here https://github.com/Azure/azure-rest-api-specs/issues/22980
477481
func TestAccMySqlFlexibleServer_enableGeoRedundantBackup(t *testing.T) {
478482
data := acceptance.BuildTestData(t, "azurerm_mysql_flexible_server", "test")
479483
r := MySqlFlexibleServerResource{}
@@ -511,6 +515,59 @@ func TestAccMySqlFlexibleServer_identity(t *testing.T) {
511515
})
512516
}
513517

518+
func TestAccMySqlFlexibleServer_writeOnlyPassword(t *testing.T) {
519+
data := acceptance.BuildTestData(t, "azurerm_mysql_flexible_server", "test")
520+
r := MySqlFlexibleServerResource{}
521+
522+
resource.ParallelTest(t, resource.TestCase{
523+
TerraformVersionChecks: []tfversion.TerraformVersionCheck{
524+
tfversion.SkipBelow(version.Must(version.NewVersion("1.11.0"))),
525+
},
526+
ProtoV5ProviderFactories: framework.ProtoV5ProviderFactoriesInit(context.Background(), "azurerm"),
527+
Steps: []resource.TestStep{
528+
{
529+
Config: r.writeOnlyPassword(data, "a-secret-from-kv", 1),
530+
Check: check.That(data.ResourceName).ExistsInAzure(r),
531+
},
532+
data.ImportStep("administrator_password_wo_version"),
533+
{
534+
Config: r.writeOnlyPassword(data, "a-secret-from-kv-updated", 2),
535+
Check: check.That(data.ResourceName).ExistsInAzure(r),
536+
},
537+
data.ImportStep("administrator_password_wo_version"),
538+
},
539+
})
540+
}
541+
542+
func TestAccMySqlFlexibleServer_updateToWriteOnlyPassword(t *testing.T) {
543+
data := acceptance.BuildTestData(t, "azurerm_mysql_flexible_server", "test")
544+
r := MySqlFlexibleServerResource{}
545+
546+
resource.ParallelTest(t, resource.TestCase{
547+
TerraformVersionChecks: []tfversion.TerraformVersionCheck{
548+
tfversion.SkipBelow(version.Must(version.NewVersion("1.11.0"))),
549+
},
550+
ProtoV5ProviderFactories: framework.ProtoV5ProviderFactoriesInit(context.Background(), "azurerm"),
551+
Steps: []resource.TestStep{
552+
{
553+
Config: r.basic(data),
554+
Check: check.That(data.ResourceName).ExistsInAzure(r),
555+
},
556+
data.ImportStep("administrator_password"),
557+
{
558+
Config: r.writeOnlyPassword(data, "a-secret-from-kv", 1),
559+
Check: check.That(data.ResourceName).ExistsInAzure(r),
560+
},
561+
data.ImportStep("administrator_password", "administrator_password_wo_version"),
562+
{
563+
Config: r.basic(data),
564+
Check: check.That(data.ResourceName).ExistsInAzure(r),
565+
},
566+
data.ImportStep("administrator_password"),
567+
},
568+
})
569+
}
570+
514571
func (MySqlFlexibleServerResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) {
515572
id, err := servers.ParseFlexibleServerID(state.ID)
516573
if err != nil {
@@ -522,7 +579,7 @@ func (MySqlFlexibleServerResource) Exists(ctx context.Context, clients *clients.
522579
return nil, fmt.Errorf("retrieving %s: %+v", id.ID(), err)
523580
}
524581

525-
return utils.Bool(resp.Model != nil && resp.Model.Properties != nil), nil
582+
return pointer.To(resp.Model != nil && resp.Model.Properties != nil), nil
526583
}
527584

528585
func (MySqlFlexibleServerResource) template(data acceptance.TestData) string {
@@ -549,7 +606,6 @@ resource "azurerm_mysql_flexible_server" "test" {
549606
administrator_login = "_admin_Terraform_892123456789312"
550607
administrator_password = "QAZwsx123"
551608
sku_name = "B_Standard_B1s"
552-
zone = "1"
553609
}
554610
`, r.template(data), data.RandomInteger)
555611
}
@@ -1285,3 +1341,21 @@ resource "azurerm_mysql_flexible_server" "test" {
12851341
}
12861342
`, r.template(data), data.RandomString, data.RandomInteger)
12871343
}
1344+
1345+
func (r MySqlFlexibleServerResource) writeOnlyPassword(data acceptance.TestData, secret string, version int) string {
1346+
return fmt.Sprintf(`
1347+
%s
1348+
1349+
%s
1350+
1351+
resource "azurerm_mysql_flexible_server" "test" {
1352+
name = "acctest-fs-%[3]d"
1353+
resource_group_name = azurerm_resource_group.test.name
1354+
location = azurerm_resource_group.test.location
1355+
administrator_login = "_admin_Terraform_892123456789312"
1356+
administrator_password_wo = ephemeral.azurerm_key_vault_secret.test.value
1357+
administrator_password_wo_version = %[4]d
1358+
sku_name = "B_Standard_B1s"
1359+
}
1360+
`, r.template(data), acceptance.WriteOnlyKeyVaultSecretTemplate(data, secret), data.RandomInteger, version)
1361+
}

website/docs/r/mysql_flexible_server.html.markdown

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,13 @@ The following arguments are supported:
8585

8686
* `administrator_login` - (Optional) The Administrator login for the MySQL Flexible Server. Required when `create_mode` is `Default`. Changing this forces a new MySQL Flexible Server to be created.
8787

88-
* `administrator_password` - (Optional) The Password associated with the `administrator_login` for the MySQL Flexible Server. Required when `create_mode` is `Default`.
88+
* `administrator_password` - (Optional) The Password associated with the `administrator_login` for the MySQL Flexible Server.
89+
90+
* `administrator_password_wo` - (Optional, Write-Only) The Password associated with the `administrator_login` for the MySQL Flexible Server.
91+
92+
* `administrator_password_wo_version` - (Optional) An integer value used to trigger an update for `administrator_password_wo`. This property should be incremented when updating `administrator_password_wo`.
93+
94+
~> **Note:** Either `administrator_password` or `administrator_password_wo` is required when `create_mode` is `Default`.
8995

9096
* `backup_retention_days` - (Optional) The backup retention days for the MySQL Flexible Server. Possible values are between `1` and `35` days. Defaults to `7`.
9197

0 commit comments

Comments
 (0)