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