From e5021c94ce1d2abc366fc86f0fab2ee07485dabb Mon Sep 17 00:00:00 2001 From: Hugo Joubert Date: Tue, 10 Dec 2024 11:34:43 +0100 Subject: [PATCH 1/2] feat:added warning for a/b deployment on opensearch --- internal/service/opensearch/domain.go | 51 +++++++++++++----- internal/service/opensearch/domain_test.go | 60 ++++++++++++++++++++++ launch.json | 20 ++++++++ private.env | 6 +++ 4 files changed, 125 insertions(+), 12 deletions(-) create mode 100644 launch.json create mode 100644 private.env diff --git a/internal/service/opensearch/domain.go b/internal/service/opensearch/domain.go index 3d864706eec..0241d0f5e66 100644 --- a/internal/service/opensearch/domain.go +++ b/internal/service/opensearch/domain.go @@ -835,7 +835,6 @@ func resourceDomainCreate(ctx context.Context, d *schema.ResourceData, meta inte func resourceDomainRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics conn := meta.(*conns.AWSClient).OpenSearchClient(ctx) - ds, err := findDomainByName(ctx, conn, d.Get(names.AttrDomainName).(string)) if !d.IsNewResource() && tfresource.NotFound(err) { @@ -855,7 +854,6 @@ func resourceDomainRead(ctx context.Context, d *schema.ResourceData, meta interf if err != nil { return sdkdiag.AppendErrorf(diags, "reading OpenSearch Domain (%s): %s", d.Id(), err) } - dc := outDescribeDomainConfig.DomainConfig if ds.AccessPolicies != nil && aws.ToString(ds.AccessPolicies) != "" { @@ -1002,22 +1000,30 @@ func resourceDomainUpdate(ctx context.Context, d *schema.ResourceData, meta inte } } - if d.HasChange("advanced_options") { - input.AdvancedOptions = flex.ExpandStringValueMap(d.Get("advanced_options").(map[string]interface{})) - } - if d.HasChange("advanced_security_options") { input.AdvancedSecurityOptions = expandAdvancedSecurityOptions(d.Get("advanced_security_options").([]interface{})) + if (d.Get("advanced_security_options.0.enabled")).(bool) { + diags = sdkdiag.AppendWarningf(diags, "One of the updated attribute may cause a blue/green deployment on the cluster") + } } if d.HasChange("auto_tune_options") { input.AutoTuneOptions = expandAutoTuneOptions(d.Get("auto_tune_options").([]interface{})[0].(map[string]interface{})) + if (d.Get("auto_tune_options.0.desired_state")).(string) == "DISABLED" { + diags = sdkdiag.AppendWarningf(diags, "One of the updated attribute may cause a blue/green deployment on the cluster") + } } - if d.HasChange("cognito_options") { input.CognitoOptions = expandCognitoOptions(d.Get("cognito_options").([]interface{})) } + if d.HasChange("cluster_config.0.dedicated_master_count") { + o, n := d.GetChange("cluster_config.0.dedicated_master_count") + if o.(int) > n.(int) && o.(int) >= 2 { + diags = sdkdiag.AppendWarningf(diags, "One of the updated attribute may cause a blue/green deployment on the cluster") + } + } + if d.HasChange("domain_endpoint_options") { input.DomainEndpointOptions = expandDomainEndpointOptions(d.Get("domain_endpoint_options").([]interface{})) } @@ -1036,7 +1042,6 @@ func resourceDomainUpdate(ctx context.Context, d *schema.ResourceData, meta inte if d.HasChange("cluster_config") { config := d.Get("cluster_config").([]interface{}) - if len(config) == 1 { m := config[0].(map[string]interface{}) input.ClusterConfig = expandClusterConfig(m) @@ -1056,10 +1061,19 @@ func resourceDomainUpdate(ctx context.Context, d *schema.ResourceData, meta inte } else { log.Printf("[WARN] %s", err) } + if d.HasChange("cluster_config.0.multi_az_with_standby_enabled") { + diags = sdkdiag.AppendWarningf(diags, "One of the updated attribute may cause a blue/green deployment on the cluster") + } } } } + if d.HasChange("ebs_options") { + o, n := d.GetChange("ebs_options.0.volume_size") + if o.(int) > n.(int) { + diags = sdkdiag.AppendWarningf(diags, "One of the updated attribute may cause a blue/green deployment on the cluster") + } + } if d.HasChange("encrypt_at_rest") { input.EncryptionAtRestOptions = nil if v, ok := d.GetOk("encrypt_at_rest"); ok { @@ -1067,7 +1081,6 @@ func resourceDomainUpdate(ctx context.Context, d *schema.ResourceData, meta inte if options[0] == nil { return sdkdiag.AppendErrorf(diags, "at least one field is expected inside encrypt_at_rest") } - s := options[0].(map[string]interface{}) input.EncryptionAtRestOptions = expandEncryptAtRestOptions(s) } @@ -1075,13 +1088,15 @@ func resourceDomainUpdate(ctx context.Context, d *schema.ResourceData, meta inte if d.HasChange("log_publishing_options") { input.LogPublishingOptions = expandLogPublishingOptions(d.Get("log_publishing_options").(*schema.Set)) + if d.Get("log_publishing_options.0.enabled").(bool) { + diags = sdkdiag.AppendWarningf(diags, "One of the updated attribute may cause a blue/green deployment on the cluster") + } } if d.HasChange("node_to_node_encryption") { input.NodeToNodeEncryptionOptions = nil if v, ok := d.GetOk("node_to_node_encryption"); ok { options := v.([]interface{}) - s := options[0].(map[string]interface{}) input.NodeToNodeEncryptionOptions = expandNodeToNodeEncryptionOptions(s) } @@ -1107,6 +1122,7 @@ func resourceDomainUpdate(ctx context.Context, d *schema.ResourceData, meta inte if d.HasChange("software_update_options") { input.SoftwareUpdateOptions = expandSoftwareUpdateOptions(d.Get("software_update_options").([]interface{})) + diags = sdkdiag.AppendWarningf(diags, "One of the updated attribute may cause a blue/green deployment on the cluster") } if d.HasChange("vpc_options") { @@ -1132,7 +1148,13 @@ func resourceDomainUpdate(ctx context.Context, d *schema.ResourceData, meta inte DomainName: aws.String(d.Get(names.AttrDomainName).(string)), TargetVersion: aws.String(d.Get(names.AttrEngineVersion).(string)), } + o, n := d.GetChange(names.AttrEngineVersion) + _, oldVersion, _ := parseEngineVersion(o.(string)) + _, newVersion, _ := parseEngineVersion(n.(string)) + if semver.GreaterThanOrEqual(newVersion, oldVersion) { + diags = sdkdiag.AppendWarningf(diags, "One of the updated attribute may cause a blue/green deployment on the cluster") + } _, err := conn.UpgradeDomain(ctx, &upgradeInput) if err != nil { return sdkdiag.AppendErrorf(diags, "updating OpenSearch Domain (%s): upgrading: %s", d.Id(), err) @@ -1142,8 +1164,14 @@ func resourceDomainUpdate(ctx context.Context, d *schema.ResourceData, meta inte return sdkdiag.AppendErrorf(diags, "updating OpenSearch Domain (%s): upgrading: waiting for completion: %s", d.Id(), err) } } + // All changes that can cause a blue/green deployment + if d.HasChanges("cluster_config.0.instance_type", "cluster_config.0.warm_enabled", "cluster_config.0.cold_storage_options.enabled", + "cluster_config.0.dedicated_master_enabled", "vpc_options.0.subnet_ids", "vpc_options.0.security_group_ids", + "cognito_options.0.enabled", "cognito_options.0.identity_pool_id", "cognito_options.0.user_pool_id", + "advanced_options", "log_publishing_options", "encrypt_at_rest", "node_to_node_encryption") { + diags = sdkdiag.AppendWarningf(diags, "One of the updated attribute may cause a blue/green deployment on the cluster") + } } - return append(diags, resourceDomainRead(ctx, d, meta)...) } @@ -1151,7 +1179,6 @@ func resourceDomainDelete(ctx context.Context, d *schema.ResourceData, meta inte var diags diag.Diagnostics conn := meta.(*conns.AWSClient).OpenSearchClient(ctx) domainName := d.Get(names.AttrDomainName).(string) - log.Printf("[DEBUG] Deleting OpenSearch Domain: %q", domainName) _, err := conn.DeleteDomain(ctx, &opensearch.DeleteDomainInput{ DomainName: aws.String(domainName), diff --git a/internal/service/opensearch/domain_test.go b/internal/service/opensearch/domain_test.go index 46de6b161f2..6dedecbbb2e 100644 --- a/internal/service/opensearch/domain_test.go +++ b/internal/service/opensearch/domain_test.go @@ -73,6 +73,45 @@ func TestEBSVolumeTypePermitsThroughputInput(t *testing.T) { } } +func TestAccAWSOpenSearchDomain_InstanceTypeUpdate(t *testing.T) { + ctx := acctest.Context(t) + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + var input awstypes.DomainStatus + rName := testAccRandomDomainName() + resourceName := "aws_opensearch_domain.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheckIAMServiceLinkedRole(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.OpenSearchServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckDomainDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccDomainConfig_instanceType(rName, "t2.small.search"), + Check: resource.ComposeTestCheckFunc( + testAccCheckDomainExists(ctx, resourceName, &input), + resource.TestCheckResourceAttr(resourceName, "instance_type", "t2.small.search"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateId: rName, + ImportStateVerify: true, + }, + { + Config: testAccDomainConfig_instanceType(rName, "m5.large.search"), + Check: resource.ComposeTestCheckFunc( + testAccCheckDomainExists(ctx, resourceName, &input), + resource.TestCheckResourceAttr(resourceName, "instance_type", "m5.large.search"), + ), + }, + }, + }) +} func TestParseEngineVersion(t *testing.T) { t.Parallel() @@ -3830,3 +3869,24 @@ resource "aws_opensearch_domain" "test" { } `, rName, option) } + +func testAccDomainConfig_instanceType(rName, instanceType string) string { + return fmt.Sprintf(` +resource "aws_opensearch_domain" "test" { + domain_name = %[1]q + + engine_version = "Elasticsearch_7.1" + +ebs_options { + ebs_enabled = true + volume_size = 10 + } + + cluster_config { + instance_count = 2 + zone_awareness_enabled = true + instance_type = %[2]q + } +} +`, rName, instanceType) +} diff --git a/launch.json b/launch.json new file mode 100644 index 00000000000..a9f5b0dffa8 --- /dev/null +++ b/launch.json @@ -0,0 +1,20 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug Selected Test", + "request": "launch", + "type": "go", + "args": [ + "-test.v", + "-test.run", + "^${selectedText}$" + ], + "mode": "auto", + "program": "${fileDirname}", + "env": {"PKG_NAME": "${relativeFileDirname}"}, + "envFile": "${workspaceFolder}/.vscode/private.env", + "showLog": true + } + ] + } \ No newline at end of file diff --git a/private.env b/private.env new file mode 100644 index 00000000000..36a09222ffe --- /dev/null +++ b/private.env @@ -0,0 +1,6 @@ +TF_ACC=1 +TF_LOG=info +GOFLAGS='-mod=readonly' +AWS_PROFILE=ippon_aws +AWS_DEFAULT_REGION=eu-west-3 +ACM_CERTIFICATE_ROOT_DOMAIN=terraform-provider-aws-acctest-acm.com From fc0935fa866f1954869739f696e2a601002b8ed5 Mon Sep 17 00:00:00 2001 From: Hugo Joubert Date: Tue, 10 Dec 2024 11:41:59 +0100 Subject: [PATCH 2/2] fix:removed unused test and var env --- internal/service/opensearch/domain.go | 3 ++ internal/service/opensearch/domain_test.go | 60 ---------------------- launch.json | 20 -------- private.env | 6 --- 4 files changed, 3 insertions(+), 86 deletions(-) delete mode 100644 launch.json delete mode 100644 private.env diff --git a/internal/service/opensearch/domain.go b/internal/service/opensearch/domain.go index 0241d0f5e66..af501cbd0f6 100644 --- a/internal/service/opensearch/domain.go +++ b/internal/service/opensearch/domain.go @@ -1000,6 +1000,9 @@ func resourceDomainUpdate(ctx context.Context, d *schema.ResourceData, meta inte } } + if d.HasChange("advanced_options") { + input.AdvancedOptions = flex.ExpandStringValueMap(d.Get("advanced_options").(map[string]interface{})) + } if d.HasChange("advanced_security_options") { input.AdvancedSecurityOptions = expandAdvancedSecurityOptions(d.Get("advanced_security_options").([]interface{})) if (d.Get("advanced_security_options.0.enabled")).(bool) { diff --git a/internal/service/opensearch/domain_test.go b/internal/service/opensearch/domain_test.go index 6dedecbbb2e..46de6b161f2 100644 --- a/internal/service/opensearch/domain_test.go +++ b/internal/service/opensearch/domain_test.go @@ -73,45 +73,6 @@ func TestEBSVolumeTypePermitsThroughputInput(t *testing.T) { } } -func TestAccAWSOpenSearchDomain_InstanceTypeUpdate(t *testing.T) { - ctx := acctest.Context(t) - if testing.Short() { - t.Skip("skipping long-running test in short mode") - } - - var input awstypes.DomainStatus - rName := testAccRandomDomainName() - resourceName := "aws_opensearch_domain.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheckIAMServiceLinkedRole(ctx, t) }, - ErrorCheck: acctest.ErrorCheck(t, names.OpenSearchServiceID), - ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, - CheckDestroy: testAccCheckDomainDestroy(ctx), - Steps: []resource.TestStep{ - { - Config: testAccDomainConfig_instanceType(rName, "t2.small.search"), - Check: resource.ComposeTestCheckFunc( - testAccCheckDomainExists(ctx, resourceName, &input), - resource.TestCheckResourceAttr(resourceName, "instance_type", "t2.small.search"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateId: rName, - ImportStateVerify: true, - }, - { - Config: testAccDomainConfig_instanceType(rName, "m5.large.search"), - Check: resource.ComposeTestCheckFunc( - testAccCheckDomainExists(ctx, resourceName, &input), - resource.TestCheckResourceAttr(resourceName, "instance_type", "m5.large.search"), - ), - }, - }, - }) -} func TestParseEngineVersion(t *testing.T) { t.Parallel() @@ -3869,24 +3830,3 @@ resource "aws_opensearch_domain" "test" { } `, rName, option) } - -func testAccDomainConfig_instanceType(rName, instanceType string) string { - return fmt.Sprintf(` -resource "aws_opensearch_domain" "test" { - domain_name = %[1]q - - engine_version = "Elasticsearch_7.1" - -ebs_options { - ebs_enabled = true - volume_size = 10 - } - - cluster_config { - instance_count = 2 - zone_awareness_enabled = true - instance_type = %[2]q - } -} -`, rName, instanceType) -} diff --git a/launch.json b/launch.json deleted file mode 100644 index a9f5b0dffa8..00000000000 --- a/launch.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Debug Selected Test", - "request": "launch", - "type": "go", - "args": [ - "-test.v", - "-test.run", - "^${selectedText}$" - ], - "mode": "auto", - "program": "${fileDirname}", - "env": {"PKG_NAME": "${relativeFileDirname}"}, - "envFile": "${workspaceFolder}/.vscode/private.env", - "showLog": true - } - ] - } \ No newline at end of file diff --git a/private.env b/private.env deleted file mode 100644 index 36a09222ffe..00000000000 --- a/private.env +++ /dev/null @@ -1,6 +0,0 @@ -TF_ACC=1 -TF_LOG=info -GOFLAGS='-mod=readonly' -AWS_PROFILE=ippon_aws -AWS_DEFAULT_REGION=eu-west-3 -ACM_CERTIFICATE_ROOT_DOMAIN=terraform-provider-aws-acctest-acm.com