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

Support replication specification for aws keyspaces #36331

40 changes: 40 additions & 0 deletions internal/service/keyspaces/keyspace.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,26 @@ func resourceKeyspace() *schema.Resource {
"The name can have up to 48 characters. It must begin with an alpha-numeric character and can only contain alpha-numeric characters and underscores.",
),
},
"replication_specification": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"replication_strategy": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{
string(types.RsSingleRegion),
string(types.RsMultiRegion)}, false),
},
"region_list": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
},
names.AttrTags: tftags.TagsSchema(),
names.AttrTagsAll: tftags.TagsSchemaComputed(),
},
Expand All @@ -76,6 +96,17 @@ func resourceKeyspaceCreate(ctx context.Context, d *schema.ResourceData, meta in
Tags: getTagsIn(ctx),
}

if v, ok := d.GetOk("replication_specification"); ok {
replicationSpecification := v.([]interface{})[0].(map[string]interface{})
replicationStrategy := replicationSpecification["replication_strategy"].(string)
if replicationStrategy == string(types.RsMultiRegion) {
input.ReplicationSpecification = &types.ReplicationSpecification{
ReplicationStrategy: types.Rs(replicationStrategy),
RegionList: listToStringSlice(replicationSpecification["region_list"].([]interface{})),
}
}
}

_, err := conn.CreateKeyspace(ctx, input)

if err != nil {
Expand Down Expand Up @@ -180,3 +211,12 @@ func findKeyspaceByName(ctx context.Context, conn *keyspaces.Client, name string

return output, nil
}

// converts a interface of regions to a string slice
func listToStringSlice(regions []interface{}) []string {
result := make([]string, len(regions))
for i, region := range regions {
result[i] = region.(string)
}
return result
}
62 changes: 62 additions & 0 deletions internal/service/keyspaces/keyspace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"fmt"
"testing"

"github.com/aws/aws-sdk-go-v2/service/keyspaces/types"
"github.com/aws/aws-sdk-go/aws/endpoints"
sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
Expand Down Expand Up @@ -52,6 +53,44 @@ func TestAccKeyspacesKeyspace_basic(t *testing.T) {
})
}

func TestAccKeyspacesKeyspace_replicationSpecificationMulti(t *testing.T) {
ctx := acctest.Context(t)
rName := "tf_acc_test_" + sdkacctest.RandString(20)
resourceName := "aws_keyspaces_keyspace.test"
region1 := acctest.Region()
region2 := acctest.AlternateRegion()

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, names.KeyspacesServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckKeyspaceDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccKeyspaceConfig_replicationSpecification(rName, string(types.RsSingleRegion)),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckKeyspaceExists(ctx, resourceName),
acctest.CheckResourceAttrRegionalARN(resourceName, "arn", "cassandra", "/keyspace/"+rName+"/"),
resource.TestCheckResourceAttr(resourceName, "name", rName),
resource.TestCheckResourceAttr(resourceName, "tags.%", "0"),
resource.TestCheckResourceAttr(resourceName, "replication_specification.0.replication_strategy", string(types.RsSingleRegion)),
),
},
{
Config: testAccKeyspaceConfig_multiReplicationSpecification(rName, string(types.RsMultiRegion), region1, region2),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckKeyspaceExists(ctx, resourceName),
acctest.CheckResourceAttrRegionalARN(resourceName, "arn", "cassandra", "/keyspace/"+rName+"/"),
resource.TestCheckResourceAttr(resourceName, "name", rName),
resource.TestCheckResourceAttr(resourceName, "tags.%", "0"),
resource.TestCheckResourceAttr(resourceName, "replication_specification.0.replication_strategy", string(types.RsMultiRegion)),
resource.TestCheckResourceAttr(resourceName, "replication_specification.0.region_list.#", "2"),
),
},
},
})
}

func TestAccKeyspacesKeyspace_disappears(t *testing.T) {
ctx := acctest.Context(t)
rName := "tf_acc_test_" + sdkacctest.RandString(20)
Expand Down Expand Up @@ -197,3 +236,26 @@ resource "aws_keyspaces_keyspace" "test" {
}
`, rName, tag1Key, tag1Value, tag2Key, tag2Value)
}

func testAccKeyspaceConfig_replicationSpecification(rName, rSpecification string) string {
return fmt.Sprintf(`
resource "aws_keyspaces_keyspace" "test" {
name = %[1]q
replication_specification {
replication_strategy = %[2]q
}
}
`, rName, rSpecification)
}

func testAccKeyspaceConfig_multiReplicationSpecification(rName, rSpecification, region1, region2 string) string {
return fmt.Sprintf(`
resource "aws_keyspaces_keyspace" "test" {
name = %[1]q
replication_specification {
replication_strategy = %[2]q
region_list = [%[3]q, %[4]q]
}
}
`, rName, rSpecification, region1, region2)
}
Loading