github.com/andresvia/terraform@v0.6.15-0.20160412045437-d51c75946785/builtin/providers/aws/resource_aws_elasticache_subnet_group.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 "strings" 7 "time" 8 9 "github.com/aws/aws-sdk-go/aws" 10 "github.com/aws/aws-sdk-go/aws/awserr" 11 "github.com/aws/aws-sdk-go/service/elasticache" 12 "github.com/hashicorp/terraform/helper/resource" 13 "github.com/hashicorp/terraform/helper/schema" 14 ) 15 16 func resourceAwsElasticacheSubnetGroup() *schema.Resource { 17 return &schema.Resource{ 18 Create: resourceAwsElasticacheSubnetGroupCreate, 19 Read: resourceAwsElasticacheSubnetGroupRead, 20 Update: resourceAwsElasticacheSubnetGroupUpdate, 21 Delete: resourceAwsElasticacheSubnetGroupDelete, 22 23 Schema: map[string]*schema.Schema{ 24 "description": &schema.Schema{ 25 Type: schema.TypeString, 26 Required: true, 27 }, 28 "name": &schema.Schema{ 29 Type: schema.TypeString, 30 Required: true, 31 ForceNew: true, 32 StateFunc: func(val interface{}) string { 33 // Elasticache normalizes subnet names to lowercase, 34 // so we have to do this too or else we can end up 35 // with non-converging diffs. 36 return strings.ToLower(val.(string)) 37 }, 38 }, 39 "subnet_ids": &schema.Schema{ 40 Type: schema.TypeSet, 41 Required: true, 42 Elem: &schema.Schema{Type: schema.TypeString}, 43 Set: schema.HashString, 44 }, 45 }, 46 } 47 } 48 49 func resourceAwsElasticacheSubnetGroupCreate(d *schema.ResourceData, meta interface{}) error { 50 conn := meta.(*AWSClient).elasticacheconn 51 52 // Get the group properties 53 name := d.Get("name").(string) 54 desc := d.Get("description").(string) 55 subnetIdsSet := d.Get("subnet_ids").(*schema.Set) 56 57 log.Printf("[DEBUG] Cache subnet group create: name: %s, description: %s", name, desc) 58 59 subnetIds := expandStringList(subnetIdsSet.List()) 60 61 req := &elasticache.CreateCacheSubnetGroupInput{ 62 CacheSubnetGroupDescription: aws.String(desc), 63 CacheSubnetGroupName: aws.String(name), 64 SubnetIds: subnetIds, 65 } 66 67 _, err := conn.CreateCacheSubnetGroup(req) 68 if err != nil { 69 return fmt.Errorf("Error creating CacheSubnetGroup: %s", err) 70 } 71 72 // Assign the group name as the resource ID 73 // Elasticache always retains the name in lower case, so we have to 74 // mimic that or else we won't be able to refresh a resource whose 75 // name contained uppercase characters. 76 d.SetId(strings.ToLower(name)) 77 78 return nil 79 } 80 81 func resourceAwsElasticacheSubnetGroupRead(d *schema.ResourceData, meta interface{}) error { 82 conn := meta.(*AWSClient).elasticacheconn 83 req := &elasticache.DescribeCacheSubnetGroupsInput{ 84 CacheSubnetGroupName: aws.String(d.Get("name").(string)), 85 } 86 87 res, err := conn.DescribeCacheSubnetGroups(req) 88 if err != nil { 89 return err 90 } 91 if len(res.CacheSubnetGroups) == 0 { 92 return fmt.Errorf("Error missing %v", d.Get("name")) 93 } 94 95 var group *elasticache.CacheSubnetGroup 96 for _, g := range res.CacheSubnetGroups { 97 log.Printf("[DEBUG] %v %v", g.CacheSubnetGroupName, d.Id()) 98 if *g.CacheSubnetGroupName == d.Id() { 99 group = g 100 } 101 } 102 if group == nil { 103 return fmt.Errorf("Error retrieving cache subnet group: %v", res) 104 } 105 106 ids := make([]string, len(group.Subnets)) 107 for i, s := range group.Subnets { 108 ids[i] = *s.SubnetIdentifier 109 } 110 111 d.Set("name", group.CacheSubnetGroupName) 112 d.Set("description", group.CacheSubnetGroupDescription) 113 d.Set("subnet_ids", ids) 114 115 return nil 116 } 117 118 func resourceAwsElasticacheSubnetGroupUpdate(d *schema.ResourceData, meta interface{}) error { 119 conn := meta.(*AWSClient).elasticacheconn 120 if d.HasChange("subnet_ids") || d.HasChange("description") { 121 var subnets []*string 122 if v := d.Get("subnet_ids"); v != nil { 123 for _, v := range v.(*schema.Set).List() { 124 subnets = append(subnets, aws.String(v.(string))) 125 } 126 } 127 log.Printf("[DEBUG] Updating ElastiCache Subnet Group") 128 129 _, err := conn.ModifyCacheSubnetGroup(&elasticache.ModifyCacheSubnetGroupInput{ 130 CacheSubnetGroupName: aws.String(d.Get("name").(string)), 131 CacheSubnetGroupDescription: aws.String(d.Get("description").(string)), 132 SubnetIds: subnets, 133 }) 134 if err != nil { 135 return err 136 } 137 } 138 139 return resourceAwsElasticacheSubnetGroupRead(d, meta) 140 } 141 func resourceAwsElasticacheSubnetGroupDelete(d *schema.ResourceData, meta interface{}) error { 142 conn := meta.(*AWSClient).elasticacheconn 143 144 log.Printf("[DEBUG] Cache subnet group delete: %s", d.Id()) 145 146 return resource.Retry(5*time.Minute, func() *resource.RetryError { 147 _, err := conn.DeleteCacheSubnetGroup(&elasticache.DeleteCacheSubnetGroupInput{ 148 CacheSubnetGroupName: aws.String(d.Id()), 149 }) 150 if err != nil { 151 apierr, ok := err.(awserr.Error) 152 if !ok { 153 return resource.RetryableError(err) 154 } 155 log.Printf("[DEBUG] APIError.Code: %v", apierr.Code()) 156 switch apierr.Code() { 157 case "DependencyViolation": 158 // If it is a dependency violation, we want to retry 159 return resource.RetryableError(err) 160 default: 161 return resource.NonRetryableError(err) 162 } 163 } 164 return nil 165 }) 166 }