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

Redshift cluster AZ relocation support #20812

Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
af1fdb9
Changelog
nickolivera Sep 7, 2021
94fea9d
Add AZ Relocation
nickolivera Sep 7, 2021
9aa59c2
Add AZ Relocation Tests
nickolivera Sep 7, 2021
0cce54f
Add AZ Relocation Docs
nickolivera Sep 7, 2021
3bdb1bd
reformat TF test
nickolivera Sep 19, 2021
bcb7a80
Updating implementation
nickolivera Sep 19, 2021
b5fa5e2
Merge branch 'main' into f-redshift-cluster-az-relocation-issue-#19098
nickolivera Dec 12, 2021
ee2fd75
#19098 cluster: add schema
nickolivera Dec 13, 2021
005ae12
#19098 cluster_data_source: add computed schema
nickolivera Dec 13, 2021
22e5662
#19098 cluster: add zone relocation status calculator
nickolivera Dec 13, 2021
2b9abd4
#19098 cluster: add restore option
nickolivera Dec 13, 2021
55f8512
#19098 cluster: add create option
nickolivera Dec 13, 2021
bfcb642
#19098 cluster: add read option
nickolivera Dec 13, 2021
ead8044
#19098 cluster: add update option
nickolivera Dec 13, 2021
b808677
#19098 cluster_data_source: add read option
nickolivera Dec 13, 2021
91a6f01
#19098 cluster_data_source_test: check for availability_zone_relocati…
nickolivera Dec 13, 2021
ca69df9
#19098 cluster_data_source_test: website docs
nickolivera Dec 13, 2021
ddef770
#19098 cluster: test: enable/disable model
nickolivera Dec 13, 2021
0b7d66f
#19098 cluster: test: enable/disable test
nickolivera Dec 13, 2021
e39835f
#19098 cluster: changelog
nickolivera Dec 13, 2021
1783e74
#19098 cluster: remove broken merge files
nickolivera Dec 13, 2021
1b8ec10
#19098: Lint: Imports of different types are not allowed in the same …
nickolivera Dec 13, 2021
4fc4489
#19098: Lint: should use fmt.Errorf(...) instead of errors.New(fmt.S…
nickolivera Dec 13, 2021
d31e80d
Cleanup
gdavison Mar 10, 2022
df44ef1
Tweaks to acceptance tests for `availability_zone_relocation`
gdavison Mar 10, 2022
95ae866
Adds plan-time checks for incompatible settings and adds test for rel…
gdavison Mar 12, 2022
49e054f
Now waits for AvailabilityZoneRelocationStatus to be either `enabled`…
gdavison Mar 12, 2022
09900df
Corrections to CHANGELOG
gdavison Mar 12, 2022
37f9659
Renames `availability_zone_relocation` to `availability_zone_relocati…
gdavison Mar 12, 2022
510056c
Removes `availability_zone_relocation_status` since it is redundant w…
gdavison Mar 12, 2022
eaeeec7
Merge branch 'main' into f-redshift-cluster-az-relocation-issue-#19098
gdavison Mar 12, 2022
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
4 changes: 4 additions & 0 deletions .changelog/19098.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
```release-note:enhancement
internal/service/redshift/cluster: Add `availability_zone_relocation` and `availability_zone_relocation_status` attributes.
internal/service/redshift/cluster_data_source: Add `availability_zone_relocation` and `availability_zone_relocation_status` attributes.
```
28 changes: 28 additions & 0 deletions internal/service/redshift/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ func ResourceCluster() *schema.Resource {
ForceNew: true,
Computed: true,
},
"availability_zone_relocation": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"availability_zone_relocation_status": {
Type: schema.TypeString,
Computed: true,
},
"cluster_identifier": {
Type: schema.TypeString,
Required: true,
Expand Down Expand Up @@ -354,6 +363,10 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error {
restoreOpts.AvailabilityZone = aws.String(v.(string))
}

if v, ok := d.GetOk("availability_zone_relocation"); ok {
restoreOpts.AvailabilityZoneRelocation = aws.Bool(v.(bool))
}

if v, ok := d.GetOk("cluster_subnet_group_name"); ok {
restoreOpts.ClusterSubnetGroupName = aws.String(v.(string))
}
Expand Down Expand Up @@ -446,6 +459,10 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error {
createOpts.AvailabilityZone = aws.String(v.(string))
}

if v, ok := d.GetOk("availability_zone_relocation"); ok {
createOpts.AvailabilityZoneRelocation = aws.Bool(v.(bool))
}

if v, ok := d.GetOk("preferred_maintenance_window"); ok {
createOpts.PreferredMaintenanceWindow = aws.String(v.(string))
}
Expand Down Expand Up @@ -550,6 +567,12 @@ func resourceClusterRead(d *schema.ResourceData, meta interface{}) error {
d.Set("arn", arn)
d.Set("automated_snapshot_retention_period", rsc.AutomatedSnapshotRetentionPeriod)
d.Set("availability_zone", rsc.AvailabilityZone)
d.Set("availability_zone_relocation_status", rsc.AvailabilityZoneRelocationStatus)
azr, err := availabilityZoneRelocationStatus(rsc)
if err != nil {
return fmt.Errorf("error reading Redshift Cluster (%s): %w", d.Id(), err)
}
d.Set("availability_zone_relocation", azr)
d.Set("cluster_identifier", rsc.ClusterIdentifier)
if err := d.Set("cluster_nodes", flattenRedshiftClusterNodes(rsc.ClusterNodes)); err != nil {
return fmt.Errorf("error setting cluster_nodes: %w", err)
Expand Down Expand Up @@ -661,6 +684,11 @@ func resourceClusterUpdate(d *schema.ResourceData, meta interface{}) error {
requestUpdate = true
}

if d.HasChange("availability_zone_relocation") {
req.AvailabilityZoneRelocation = aws.Bool(d.Get("availability_zone_relocation").(bool))
requestUpdate = true
}

if d.HasChange("cluster_security_groups") {
req.ClusterSecurityGroups = flex.ExpandStringSet(d.Get("cluster_security_groups").(*schema.Set))
requestUpdate = true
Expand Down
16 changes: 16 additions & 0 deletions internal/service/redshift/cluster_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ func DataSourceCluster() *schema.Resource {
Computed: true,
},

"availability_zone_relocation": {
Type: schema.TypeBool,
Computed: true,
},

"availability_zone_relocation_status": {
Type: schema.TypeString,
Computed: true,
},

"bucket_name": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -196,6 +206,12 @@ func dataSourceClusterRead(d *schema.ResourceData, meta interface{}) error {
d.Set("allow_version_upgrade", rsc.AllowVersionUpgrade)
d.Set("automated_snapshot_retention_period", rsc.AutomatedSnapshotRetentionPeriod)
d.Set("availability_zone", rsc.AvailabilityZone)
d.Set("availability_zone_relocation_status", rsc.AvailabilityZoneRelocationStatus)
azr, err := availabilityZoneRelocationStatus(rsc)
if err != nil {
return fmt.Errorf("error reading Redshift Cluster (%s): %w", d.Id(), err)
}
d.Set("availability_zone_relocation", azr)
d.Set("cluster_identifier", rsc.ClusterIdentifier)

if len(rsc.ClusterParameterGroups) > 0 {
Expand Down
1 change: 1 addition & 0 deletions internal/service/redshift/cluster_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func TestAccRedshiftClusterDataSource_basic(t *testing.T) {
resource.TestCheckResourceAttrSet(dataSourceName, "port"),
resource.TestCheckResourceAttrSet(dataSourceName, "preferred_maintenance_window"),
resource.TestCheckResourceAttrSet(dataSourceName, "publicly_accessible"),
resource.TestCheckResourceAttrSet(dataSourceName, "availability_zone_relocation"),
),
},
},
Expand Down
60 changes: 60 additions & 0 deletions internal/service/redshift/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,46 @@ func TestAccRedshiftCluster_changeEncryption2(t *testing.T) {
})
}

func TestAccRedshiftCluster_availabilityZoneRelocation(t *testing.T) {
var v redshift.Cluster
rInt := sdkacctest.RandInt()

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, redshift.EndpointsID),
Providers: acctest.Providers,
CheckDestroy: testAccCheckClusterDestroy,
Steps: []resource.TestStep{
{
Config: testAccClusterConfig_availabilityZoneRelocation(rInt, true),
Check: resource.ComposeTestCheckFunc(
testAccCheckClusterExists("aws_redshift_cluster.default", &v),
resource.TestCheckResourceAttr(
"aws_redshift_cluster.default", "availability_zone_relocation", "true"),
),
},
{
ResourceName: "aws_redshift_cluster.default",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{
"final_snapshot_identifier",
"master_password",
"skip_final_snapshot",
},
},
{
Config: testAccClusterConfig_availabilityZoneRelocation(rInt, false),
Check: resource.ComposeTestCheckFunc(
testAccCheckClusterExists("aws_redshift_cluster.default", &v),
resource.TestCheckResourceAttr(
"aws_redshift_cluster.default", "availability_zone_relocation", "false"),
),
},
},
})
}

func testAccCheckClusterDestroy(s *terraform.State) error {
conn := acctest.Provider.Meta().(*conns.AWSClient).RedshiftConn

Expand Down Expand Up @@ -1278,3 +1318,23 @@ resource "aws_redshift_cluster" "test" {
}
`, rName))
}

func testAccClusterConfig_availabilityZoneRelocation(rInt int, enabled bool) string {
return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptInExclude("usw2-az2"), fmt.Sprintf(`
resource "aws_redshift_cluster" "default" {
cluster_identifier = "tf-redshift-cluster-%[1]d"
availability_zone = data.aws_availability_zones.available.names[0]
database_name = "mydb"
master_username = "foo_test"
master_password = "Mustbe8characters"
node_type = "ra3.xlplus"
number_of_nodes = 2
cluster_type = "multi-node"
availability_zone_relocation = tobool("%[2]t")
publicly_accessible = false
automated_snapshot_retention_period = 1
allow_version_upgrade = false
skip_final_snapshot = true
}
`, rInt, enabled))
}
14 changes: 14 additions & 0 deletions internal/service/redshift/status.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package redshift

import (
"fmt"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/redshift"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
Expand All @@ -22,3 +24,15 @@ func statusCluster(conn *redshift.Redshift, id string) resource.StateRefreshFunc
return output, aws.StringValue(output.ClusterStatus), nil
}
}

func availabilityZoneRelocationStatus(cluster *redshift.Cluster) (bool, error) {
// AvailabilityZoneRelocation is not returned by the API, and AvailabilityZoneRelocationStatus is not implemented as Const at this time.
switch availabilityZoneRelocationStatus := *cluster.AvailabilityZoneRelocationStatus; availabilityZoneRelocationStatus {
case "enabled", "pending_enabling":
return true, nil
case "disabled", "pending_disabling":
return false, nil
default:
return false, fmt.Errorf("unexpected AvailabilityZoneRelocationStatus attribute value: %s", availabilityZoneRelocationStatus)
}
}
2 changes: 2 additions & 0 deletions website/docs/d/redshift_cluster.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ In addition to all arguments above, the following attributes are exported:
* `allow_version_upgrade` - Whether major version upgrades can be applied during maintenance period
* `automated_snapshot_retention_period` - The backup retention period
* `availability_zone` - The availability zone of the cluster
* `availability_zone_relocation` - Relocation for an Amazon Redshift cluster between Availability Zones.
* `availability_zone_relocation_status` - The status of the Availability Zone relocation operation (enabled, disabled, pending_enabling, pending_disabling)
* `bucket_name` - The name of the S3 bucket where the log files are to be stored
* `cluster_identifier` - The cluster identifier
* `cluster_parameter_group_name` - The name of the parameter group to be associated with this cluster
Expand Down
2 changes: 2 additions & 0 deletions website/docs/r/redshift_cluster.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ string.
* `vpc_security_group_ids` - (Optional) A list of Virtual Private Cloud (VPC) security groups to be associated with the cluster.
* `cluster_subnet_group_name` - (Optional) The name of a cluster subnet group to be associated with this cluster. If this parameter is not provided the resulting cluster will be deployed outside virtual private cloud (VPC).
* `availability_zone` - (Optional) The EC2 Availability Zone (AZ) in which you want Amazon Redshift to provision the cluster. For example, if you have several EC2 instances running in a specific Availability Zone, then you might want the cluster to be provisioned in the same zone in order to decrease network latency.
* `availability_zone_relocation` - (Optional) Enable relocation for an Amazon Redshift cluster between Availability Zones. Default is false. Available for use on clusters from the RA3 instance family.
* `preferred_maintenance_window` - (Optional) The weekly time range (in UTC) during which automated cluster maintenance can occur.
Format: ddd:hh24:mi-ddd:hh24:mi
* `cluster_parameter_group_name` - (Optional) The name of the parameter group to be associated with this cluster.
Expand Down Expand Up @@ -108,6 +109,7 @@ In addition to all arguments above, the following attributes are exported:
* `node_type` - The type of nodes in the cluster
* `database_name` - The name of the default database in the Cluster
* `availability_zone` - The availability zone of the Cluster
* `availability_zone_relocation_status` - The status of the Availability Zone relocation operation (enabled, disabled, pending_enabling, pending_disabling)
* `automated_snapshot_retention_period` - The backup retention period
* `preferred_maintenance_window` - The backup window
* `endpoint` - The connection endpoint
Expand Down