From bfcff6b068a6ae4532abcdbc772cd714fc4a4ae6 Mon Sep 17 00:00:00 2001 From: wata_mac Date: Mon, 11 Jan 2016 23:45:07 +0900 Subject: [PATCH] Add az_mode and availability_zones parameters Signed-off-by: wata727 --- .../aws/resource_aws_elasticache_cluster.go | 30 +++++++ .../resource_aws_elasticache_cluster_test.go | 85 +++++++++++++++++++ .../aws/r/elasticache_cluster.html.markdown | 6 +- 3 files changed, 120 insertions(+), 1 deletion(-) diff --git a/builtin/providers/aws/resource_aws_elasticache_cluster.go b/builtin/providers/aws/resource_aws_elasticache_cluster.go index 7a1448c26..d2c6e4507 100644 --- a/builtin/providers/aws/resource_aws_elasticache_cluster.go +++ b/builtin/providers/aws/resource_aws_elasticache_cluster.go @@ -166,6 +166,13 @@ func resourceAwsElasticacheCluster() *schema.Resource { }, }, + "az_mode": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + "availability_zone": &schema.Schema{ Type: schema.TypeString, Optional: true, @@ -173,6 +180,16 @@ func resourceAwsElasticacheCluster() *schema.Resource { ForceNew: true, }, + "availability_zones": &schema.Schema{ + Type: schema.TypeSet, + Optional: true, + ForceNew: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: func(v interface{}) int { + return hashcode.String(v.(string)) + }, + }, + "tags": tagsSchema(), // apply_immediately is used to determine when the update modifications @@ -245,10 +262,20 @@ func resourceAwsElasticacheClusterCreate(d *schema.ResourceData, meta interface{ log.Printf("[DEBUG] Restoring Redis cluster from S3 snapshot: %#v", s) } + if v, ok := d.GetOk("az_mode"); ok { + req.AZMode = aws.String(v.(string)) + } + if v, ok := d.GetOk("availability_zone"); ok { req.PreferredAvailabilityZone = aws.String(v.(string)) } + preferred_azs := d.Get("availability_zones").(*schema.Set).List() + if len(preferred_azs) > 0 { + azs := expandStringList(preferred_azs) + req.PreferredAvailabilityZones = azs + } + resp, err := conn.CreateCacheCluster(req) if err != nil { return fmt.Errorf("Error creating Elasticache: %s", err) @@ -414,6 +441,9 @@ func resourceAwsElasticacheClusterUpdate(d *schema.ResourceData, meta interface{ oraw, nraw := d.GetChange("num_cache_nodes") o := oraw.(int) n := nraw.(int) + if v, ok := d.GetOk("az_mode"); ok && v.(string) == "cross-az" && n == 1 { + return fmt.Errorf("[WARN] Error updateing Elasticache cluster (%s), error: Cross-AZ mode is not supported in a single cache node.", d.Id()) + } if n < o { log.Printf("[INFO] Cluster %s is marked for Decreasing cache nodes from %d to %d", d.Id(), o, n) nodesToRemove := getCacheNodesToRemove(d, o, o-n) diff --git a/builtin/providers/aws/resource_aws_elasticache_cluster_test.go b/builtin/providers/aws/resource_aws_elasticache_cluster_test.go index 24442dbf5..3cbc4790a 100644 --- a/builtin/providers/aws/resource_aws_elasticache_cluster_test.go +++ b/builtin/providers/aws/resource_aws_elasticache_cluster_test.go @@ -130,6 +130,27 @@ func TestAccAWSElasticacheCluster_vpc(t *testing.T) { }) } +func TestAccAWSElasticacheCluster_multiAZInVpc(t *testing.T) { + var csg elasticache.CacheSubnetGroup + var ec elasticache.CacheCluster + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSElasticacheClusterDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAWSElasticacheClusterMultiAZInVPCConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSElasticacheSubnetGroupExists("aws_elasticache_subnet_group.bar", &csg), + testAccCheckAWSElasticacheClusterExists("aws_elasticache_cluster.bar", &ec), + resource.TestCheckResourceAttr( + "aws_elasticache_cluster.bar", "availability_zone", "Multiple"), + ), + }, + }, + }) +} + func testAccCheckAWSElasticacheClusterAttributes(v *elasticache.CacheCluster) resource.TestCheckFunc { return func(s *terraform.State) error { if v.NotificationConfiguration == nil { @@ -423,3 +444,67 @@ resource "aws_sns_topic" "topic_example" { name = "tf-ecache-cluster-test" } `, genRandInt(), genRandInt(), genRandInt()) + +var testAccAWSElasticacheClusterMultiAZInVPCConfig = fmt.Sprintf(` +resource "aws_vpc" "foo" { + cidr_block = "192.168.0.0/16" + tags { + Name = "tf-test" + } +} + +resource "aws_subnet" "foo" { + vpc_id = "${aws_vpc.foo.id}" + cidr_block = "192.168.0.0/20" + availability_zone = "us-west-2a" + tags { + Name = "tf-test-%03d" + } +} + +resource "aws_subnet" "bar" { + vpc_id = "${aws_vpc.foo.id}" + cidr_block = "192.168.16.0/20" + availability_zone = "us-west-2b" + tags { + Name = "tf-test-%03d" + } +} + +resource "aws_elasticache_subnet_group" "bar" { + name = "tf-test-cache-subnet-%03d" + description = "tf-test-cache-subnet-group-descr" + subnet_ids = [ + "${aws_subnet.foo.id}", + "${aws_subnet.bar.id}" + ] +} + +resource "aws_security_group" "bar" { + name = "tf-test-security-group-%03d" + description = "tf-test-security-group-descr" + vpc_id = "${aws_vpc.foo.id}" + ingress { + from_port = -1 + to_port = -1 + protocol = "icmp" + cidr_blocks = ["0.0.0.0/0"] + } +} + +resource "aws_elasticache_cluster" "bar" { + cluster_id = "tf-test-%03d" + engine = "memcached" + node_type = "cache.m1.small" + num_cache_nodes = 2 + port = 11211 + subnet_group_name = "${aws_elasticache_subnet_group.bar.name}" + security_group_ids = ["${aws_security_group.bar.id}"] + parameter_group_name = "default.memcached1.4" + az_mode = "cross-az" + availability_zones = [ + "us-west-2a", + "us-west-2b" + ] +} +`, genRandInt(), genRandInt(), genRandInt(), genRandInt(), genRandInt()) diff --git a/website/source/docs/providers/aws/r/elasticache_cluster.html.markdown b/website/source/docs/providers/aws/r/elasticache_cluster.html.markdown index e32a70cf1..9726ec61f 100644 --- a/website/source/docs/providers/aws/r/elasticache_cluster.html.markdown +++ b/website/source/docs/providers/aws/r/elasticache_cluster.html.markdown @@ -98,7 +98,11 @@ Can only be used for the Redis engine. SNS topic to send ElastiCache notifications to. Example: `arn:aws:sns:us-east-1:012345678999:my_sns_topic` -* `availability_zone` - (Optional) The AZ for the cache cluster. +* `az_mode` - (Optional, Memcached only) Specifies whether the nodes in this Memcached node group are created in a single Availability Zone or created across multiple Availability Zones in the cluster's region. Valid values for this parameter are `single-az` or `cross-az`, default is `single-az`. If you want to choose `cross-az`, `num_cache_nodes` must be greater than `1`. + +* `availability_zone` - (Optional) The AZ for the cache cluster. If you want to create cache nodes in multi-az, use `availability_zones`. + +* `availability_zones` - (Optional, Memcached only) List of AZ in which the cache nodes will be created. If you want to create cache nodes in single-az, use `availability_zone`. * `tags` - (Optional) A mapping of tags to assign to the resource.