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

service/elasticache: Support longer Cluster and Replication Group identifiers #9941

Merged
merged 3 commits into from
Sep 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 9 additions & 2 deletions aws/resource_aws_dax_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package aws
import (
"fmt"
"log"
"regexp"
"sort"
"strings"
"time"
Expand All @@ -11,6 +12,7 @@ import (
"github.com/aws/aws-sdk-go/service/dax"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
)

func resourceAwsDaxCluster() *schema.Resource {
Expand Down Expand Up @@ -41,8 +43,13 @@ func resourceAwsDaxCluster() *schema.Resource {
StateFunc: func(val interface{}) string {
return strings.ToLower(val.(string))
},
// DAX follows the same naming convention as ElastiCache clusters
ValidateFunc: validateElastiCacheClusterId,
ValidateFunc: validation.All(
validation.StringLenBetween(1, 20),
validation.StringMatch(regexp.MustCompile(`^[0-9a-z-]+$`), "must contain only lowercase alphanumeric characters and hyphens"),
validation.StringMatch(regexp.MustCompile(`^[a-z]`), "must begin with a lowercase letter"),
validateStringNotMatch(regexp.MustCompile(`--`), "cannot contain two consecutive hyphens"),
validateStringNotMatch(regexp.MustCompile(`-$`), "cannot end with a hyphen"),
),
},
"iam_role_arn": {
Type: schema.TypeString,
Expand Down
9 changes: 8 additions & 1 deletion aws/resource_aws_elasticache_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"log"
"regexp"
"sort"
"strings"
"time"
Expand Down Expand Up @@ -95,7 +96,13 @@ func resourceAwsElasticacheCluster() *schema.Resource {
// with non-converging diffs.
return strings.ToLower(val.(string))
},
ValidateFunc: validateElastiCacheClusterId,
ValidateFunc: validation.All(
validation.StringLenBetween(1, 50),
validation.StringMatch(regexp.MustCompile(`^[0-9a-z-]+$`), "must contain only lowercase alphanumeric characters and hyphens"),
validation.StringMatch(regexp.MustCompile(`^[a-z]`), "must begin with a lowercase letter"),
validateStringNotMatch(regexp.MustCompile(`--`), "cannot contain two consecutive hyphens"),
validateStringNotMatch(regexp.MustCompile(`-$`), "cannot end with a hyphen"),
),
},
"configuration_endpoint": {
Type: schema.TypeString,
Expand Down
62 changes: 36 additions & 26 deletions aws/resource_aws_elasticache_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func TestAccAWSElasticacheCluster_Engine_Memcached_Ec2Classic(t *testing.T) {
defer os.Setenv("AWS_DEFAULT_REGION", oldvar)

var ec elasticache.CacheCluster
rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(8))
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_elasticache_cluster.bar"

resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -110,7 +110,7 @@ func TestAccAWSElasticacheCluster_Engine_Redis_Ec2Classic(t *testing.T) {
defer os.Setenv("AWS_DEFAULT_REGION", oldvar)

var ec elasticache.CacheCluster
rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(8))
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_elasticache_cluster.bar"

resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -141,7 +141,7 @@ func TestAccAWSElasticacheCluster_Engine_Redis_Ec2Classic(t *testing.T) {

func TestAccAWSElasticacheCluster_ParameterGroupName_Default(t *testing.T) {
var ec elasticache.CacheCluster
rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(8))
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_elasticache_cluster.test"

resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -177,7 +177,7 @@ func TestAccAWSElasticacheCluster_Port_Ec2Classic(t *testing.T) {

var ec elasticache.CacheCluster
port := 11212
rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(8))
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_elasticache_cluster.bar"

resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -271,7 +271,7 @@ func TestAccAWSElasticacheCluster_snapshotsWithUpdates(t *testing.T) {

func TestAccAWSElasticacheCluster_NumCacheNodes_Decrease(t *testing.T) {
var ec elasticache.CacheCluster
rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(8))
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_elasticache_cluster.bar"

resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -299,7 +299,7 @@ func TestAccAWSElasticacheCluster_NumCacheNodes_Decrease(t *testing.T) {

func TestAccAWSElasticacheCluster_NumCacheNodes_Increase(t *testing.T) {
var ec elasticache.CacheCluster
rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(8))
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_elasticache_cluster.bar"

resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -327,7 +327,7 @@ func TestAccAWSElasticacheCluster_NumCacheNodes_Increase(t *testing.T) {

func TestAccAWSElasticacheCluster_NumCacheNodes_IncreaseWithPreferredAvailabilityZones(t *testing.T) {
var ec elasticache.CacheCluster
rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(8))
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_elasticache_cluster.bar"

resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -369,8 +369,6 @@ func TestAccAWSElasticacheCluster_vpc(t *testing.T) {
testAccCheckAWSElasticacheSubnetGroupExists("aws_elasticache_subnet_group.bar", &csg),
testAccCheckAWSElasticacheClusterExists("aws_elasticache_cluster.bar", &ec),
testAccCheckAWSElasticacheClusterAttributes(&ec),
resource.TestCheckResourceAttr(
"aws_elasticache_cluster.bar", "availability_zone", "us-west-2a"),
),
},
},
Expand Down Expand Up @@ -404,7 +402,7 @@ func TestAccAWSElasticacheCluster_AZMode_Memcached_Ec2Classic(t *testing.T) {
defer os.Setenv("AWS_DEFAULT_REGION", oldvar)

var cluster elasticache.CacheCluster
rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(8))
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_elasticache_cluster.bar"

resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -441,7 +439,7 @@ func TestAccAWSElasticacheCluster_AZMode_Redis_Ec2Classic(t *testing.T) {
defer os.Setenv("AWS_DEFAULT_REGION", oldvar)

var cluster elasticache.CacheCluster
rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(8))
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_elasticache_cluster.bar"

resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -474,7 +472,7 @@ func TestAccAWSElasticacheCluster_EngineVersion_Memcached_Ec2Classic(t *testing.
defer os.Setenv("AWS_DEFAULT_REGION", oldvar)

var pre, mid, post elasticache.CacheCluster
rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(8))
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_elasticache_cluster.bar"

resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -515,7 +513,7 @@ func TestAccAWSElasticacheCluster_EngineVersion_Redis_Ec2Classic(t *testing.T) {
defer os.Setenv("AWS_DEFAULT_REGION", oldvar)

var pre, mid, post elasticache.CacheCluster
rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(8))
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_elasticache_cluster.bar"

resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -556,7 +554,7 @@ func TestAccAWSElasticacheCluster_NodeTypeResize_Memcached_Ec2Classic(t *testing
defer os.Setenv("AWS_DEFAULT_REGION", oldvar)

var pre, post elasticache.CacheCluster
rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(8))
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_elasticache_cluster.bar"

resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -589,7 +587,7 @@ func TestAccAWSElasticacheCluster_NodeTypeResize_Redis_Ec2Classic(t *testing.T)
defer os.Setenv("AWS_DEFAULT_REGION", oldvar)

var pre, post elasticache.CacheCluster
rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(8))
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_elasticache_cluster.bar"

resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -621,7 +619,7 @@ func TestAccAWSElasticacheCluster_NumCacheNodes_Redis_Ec2Classic(t *testing.T) {
os.Setenv("AWS_DEFAULT_REGION", "us-east-1")
defer os.Setenv("AWS_DEFAULT_REGION", oldvar)

rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(8))
rName := acctest.RandomWithPrefix("tf-acc-test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccEC2ClassicPreCheck(t) },
Expand All @@ -641,7 +639,7 @@ func TestAccAWSElasticacheCluster_ReplicationGroupID_InvalidAttributes(t *testin
os.Setenv("AWS_DEFAULT_REGION", "us-east-1")
defer os.Setenv("AWS_DEFAULT_REGION", oldvar)

rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(8))
rName := acctest.RandomWithPrefix("tf-acc-test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccEC2ClassicPreCheck(t) },
Expand Down Expand Up @@ -723,7 +721,7 @@ func TestAccAWSElasticacheCluster_ReplicationGroupID_AvailabilityZone_Ec2Classic

var cluster elasticache.CacheCluster
var replicationGroup elasticache.ReplicationGroup
rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(7))
rName := acctest.RandomWithPrefix("tf-acc-test")
clusterResourceName := "aws_elasticache_cluster.replica"
replicationGroupResourceName := "aws_elasticache_replication_group.test"

Expand Down Expand Up @@ -751,7 +749,7 @@ func TestAccAWSElasticacheCluster_ReplicationGroupID_SingleReplica_Ec2Classic(t

var cluster elasticache.CacheCluster
var replicationGroup elasticache.ReplicationGroup
rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(7))
rName := acctest.RandomWithPrefix("tf-acc-test")
clusterResourceName := "aws_elasticache_cluster.replica"
replicationGroupResourceName := "aws_elasticache_replication_group.test"

Expand Down Expand Up @@ -782,7 +780,7 @@ func TestAccAWSElasticacheCluster_ReplicationGroupID_MultipleReplica_Ec2Classic(

var cluster1, cluster2 elasticache.CacheCluster
var replicationGroup elasticache.ReplicationGroup
rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(7))
rName := acctest.RandomWithPrefix("tf-acc-test")
clusterResourceName1 := "aws_elasticache_cluster.replica.0"
clusterResourceName2 := "aws_elasticache_cluster.replica.1"
replicationGroupResourceName := "aws_elasticache_replication_group.test"
Expand Down Expand Up @@ -1095,6 +1093,12 @@ resource "aws_elasticache_cluster" "bar" {
}

var testAccAWSElasticacheClusterInVPCConfig = fmt.Sprintf(`
data "aws_availability_zones" "available" {
# InsufficientCacheClusterCapacity: cache.m1.small (VPC) is not currently supported in the availability zone us-east-1b
blacklisted_zone_ids = ["use1-az1"]
state = "available"
}

resource "aws_vpc" "foo" {
cidr_block = "192.168.0.0/16"
tags = {
Expand All @@ -1105,7 +1109,7 @@ resource "aws_vpc" "foo" {
resource "aws_subnet" "foo" {
vpc_id = "${aws_vpc.foo.id}"
cidr_block = "192.168.0.0/20"
availability_zone = "us-west-2a"
availability_zone = "${data.aws_availability_zones.available.names[0]}"
tags = {
Name = "tf-acc-elasticache-cluster-in-vpc"
}
Expand Down Expand Up @@ -1143,7 +1147,7 @@ resource "aws_elasticache_cluster" "bar" {
security_group_ids = ["${aws_security_group.bar.id}"]
parameter_group_name = "default.redis2.8"
notification_topic_arn = "${aws_sns_topic.topic_example.arn}"
availability_zone = "us-west-2a"
availability_zone = "${data.aws_availability_zones.available.names[0]}"
}

resource "aws_sns_topic" "topic_example" {
Expand All @@ -1152,6 +1156,12 @@ resource "aws_sns_topic" "topic_example" {
`, acctest.RandInt(), acctest.RandInt(), acctest.RandString(10))

var testAccAWSElasticacheClusterMultiAZInVPCConfig = fmt.Sprintf(`
data "aws_availability_zones" "available" {
# InsufficientCacheClusterCapacity: cache.m1.small (VPC) is not currently supported in the availability zone us-east-1b
blacklisted_zone_ids = ["use1-az1"]
state = "available"
}

resource "aws_vpc" "foo" {
cidr_block = "192.168.0.0/16"
tags = {
Expand All @@ -1162,7 +1172,7 @@ resource "aws_vpc" "foo" {
resource "aws_subnet" "foo" {
vpc_id = "${aws_vpc.foo.id}"
cidr_block = "192.168.0.0/20"
availability_zone = "us-west-2a"
availability_zone = "${data.aws_availability_zones.available.names[0]}"
tags = {
Name = "tf-acc-elasticache-cluster-multi-az-in-vpc-foo"
}
Expand All @@ -1171,7 +1181,7 @@ resource "aws_subnet" "foo" {
resource "aws_subnet" "bar" {
vpc_id = "${aws_vpc.foo.id}"
cidr_block = "192.168.16.0/20"
availability_zone = "us-east-1c"
availability_zone = "${data.aws_availability_zones.available.names[1]}"
tags = {
Name = "tf-acc-elasticache-cluster-multi-az-in-vpc-bar"
}
Expand Down Expand Up @@ -1208,8 +1218,8 @@ resource "aws_elasticache_cluster" "bar" {
security_group_ids = ["${aws_security_group.bar.id}"]
az_mode = "cross-az"
preferred_availability_zones = [
"us-west-2a",
"us-west-2b"
"${data.aws_availability_zones.available.names[0]}",
"${data.aws_availability_zones.available.names[1]}"
]
}
`, acctest.RandInt(), acctest.RandInt(), acctest.RandString(10))
Expand Down
39 changes: 10 additions & 29 deletions aws/resource_aws_elasticache_replication_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,16 @@ func resourceAwsElasticacheReplicationGroup() *schema.Resource {
Required: true,
},
"replication_group_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateAwsElastiCacheReplicationGroupId,
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.All(
validation.StringLenBetween(1, 40),
validation.StringMatch(regexp.MustCompile(`^[0-9a-zA-Z-]+$`), "must contain only alphanumeric characters and hyphens"),
validation.StringMatch(regexp.MustCompile(`^[a-zA-Z]`), "must begin with a letter"),
validateStringNotMatch(regexp.MustCompile(`--`), "cannot contain two consecutive hyphens"),
validateStringNotMatch(regexp.MustCompile(`-$`), "cannot end with a hyphen"),
),
StateFunc: func(val interface{}) string {
return strings.ToLower(val.(string))
},
Expand Down Expand Up @@ -919,28 +925,3 @@ func validateAwsElastiCacheReplicationGroupEngine(v interface{}, k string) (ws [
}
return
}

func validateAwsElastiCacheReplicationGroupId(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
if (len(value) < 1) || (len(value) > 20) {
errors = append(errors, fmt.Errorf(
"%q must contain from 1 to 20 alphanumeric characters or hyphens", k))
}
if !regexp.MustCompile(`^[0-9a-zA-Z-]+$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"only alphanumeric characters and hyphens allowed in %q", k))
}
if !regexp.MustCompile(`^[a-zA-Z]`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"first character of %q must be a letter", k))
}
if regexp.MustCompile(`--`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q cannot contain two consecutive hyphens", k))
}
if regexp.MustCompile(`-$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q cannot end with a hyphen", k))
}
return
}
Loading