github.com/ottenhoff/terraform@v0.7.0-rc1.0.20160607213102-ac2d195cc560/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 Optional: true, 27 Default: "Managed by Terraform", 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: schema.HashString, 45 }, 46 }, 47 } 48 } 49 50 func resourceAwsElasticacheSubnetGroupCreate(d *schema.ResourceData, meta interface{}) error { 51 conn := meta.(*AWSClient).elasticacheconn 52 53 // Get the group properties 54 name := d.Get("name").(string) 55 desc := d.Get("description").(string) 56 subnetIdsSet := d.Get("subnet_ids").(*schema.Set) 57 58 log.Printf("[DEBUG] Cache subnet group create: name: %s, description: %s", name, desc) 59 60 subnetIds := expandStringList(subnetIdsSet.List()) 61 62 req := &elasticache.CreateCacheSubnetGroupInput{ 63 CacheSubnetGroupDescription: aws.String(desc), 64 CacheSubnetGroupName: aws.String(name), 65 SubnetIds: subnetIds, 66 } 67 68 _, err := conn.CreateCacheSubnetGroup(req) 69 if err != nil { 70 return fmt.Errorf("Error creating CacheSubnetGroup: %s", err) 71 } 72 73 // Assign the group name as the resource ID 74 // Elasticache always retains the name in lower case, so we have to 75 // mimic that or else we won't be able to refresh a resource whose 76 // name contained uppercase characters. 77 d.SetId(strings.ToLower(name)) 78 79 return nil 80 } 81 82 func resourceAwsElasticacheSubnetGroupRead(d *schema.ResourceData, meta interface{}) error { 83 conn := meta.(*AWSClient).elasticacheconn 84 req := &elasticache.DescribeCacheSubnetGroupsInput{ 85 CacheSubnetGroupName: aws.String(d.Get("name").(string)), 86 } 87 88 res, err := conn.DescribeCacheSubnetGroups(req) 89 if err != nil { 90 return err 91 } 92 if len(res.CacheSubnetGroups) == 0 { 93 return fmt.Errorf("Error missing %v", d.Get("name")) 94 } 95 96 var group *elasticache.CacheSubnetGroup 97 for _, g := range res.CacheSubnetGroups { 98 log.Printf("[DEBUG] %v %v", g.CacheSubnetGroupName, d.Id()) 99 if *g.CacheSubnetGroupName == d.Id() { 100 group = g 101 } 102 } 103 if group == nil { 104 return fmt.Errorf("Error retrieving cache subnet group: %v", res) 105 } 106 107 ids := make([]string, len(group.Subnets)) 108 for i, s := range group.Subnets { 109 ids[i] = *s.SubnetIdentifier 110 } 111 112 d.Set("name", group.CacheSubnetGroupName) 113 d.Set("description", group.CacheSubnetGroupDescription) 114 d.Set("subnet_ids", ids) 115 116 return nil 117 } 118 119 func resourceAwsElasticacheSubnetGroupUpdate(d *schema.ResourceData, meta interface{}) error { 120 conn := meta.(*AWSClient).elasticacheconn 121 if d.HasChange("subnet_ids") || d.HasChange("description") { 122 var subnets []*string 123 if v := d.Get("subnet_ids"); v != nil { 124 for _, v := range v.(*schema.Set).List() { 125 subnets = append(subnets, aws.String(v.(string))) 126 } 127 } 128 log.Printf("[DEBUG] Updating ElastiCache Subnet Group") 129 130 _, err := conn.ModifyCacheSubnetGroup(&elasticache.ModifyCacheSubnetGroupInput{ 131 CacheSubnetGroupName: aws.String(d.Get("name").(string)), 132 CacheSubnetGroupDescription: aws.String(d.Get("description").(string)), 133 SubnetIds: subnets, 134 }) 135 if err != nil { 136 return err 137 } 138 } 139 140 return resourceAwsElasticacheSubnetGroupRead(d, meta) 141 } 142 func resourceAwsElasticacheSubnetGroupDelete(d *schema.ResourceData, meta interface{}) error { 143 conn := meta.(*AWSClient).elasticacheconn 144 145 log.Printf("[DEBUG] Cache subnet group delete: %s", d.Id()) 146 147 return resource.Retry(5*time.Minute, func() *resource.RetryError { 148 _, err := conn.DeleteCacheSubnetGroup(&elasticache.DeleteCacheSubnetGroupInput{ 149 CacheSubnetGroupName: aws.String(d.Id()), 150 }) 151 if err != nil { 152 apierr, ok := err.(awserr.Error) 153 if !ok { 154 return resource.RetryableError(err) 155 } 156 log.Printf("[DEBUG] APIError.Code: %v", apierr.Code()) 157 switch apierr.Code() { 158 case "DependencyViolation": 159 // If it is a dependency violation, we want to retry 160 return resource.RetryableError(err) 161 default: 162 return resource.NonRetryableError(err) 163 } 164 } 165 return nil 166 }) 167 }