github.com/leeprovoost/terraform@v0.6.10-0.20160119085442-96f3f76118e7/builtin/providers/aws/resource_aws_redshift_subnet_group.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 "regexp" 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/redshift" 12 "github.com/hashicorp/terraform/helper/resource" 13 "github.com/hashicorp/terraform/helper/schema" 14 ) 15 16 func resourceAwsRedshiftSubnetGroup() *schema.Resource { 17 return &schema.Resource{ 18 Create: resourceAwsRedshiftSubnetGroupCreate, 19 Read: resourceAwsRedshiftSubnetGroupRead, 20 Update: resourceAwsRedshiftSubnetGroupUpdate, 21 Delete: resourceAwsRedshiftSubnetGroupDelete, 22 23 Schema: map[string]*schema.Schema{ 24 "name": &schema.Schema{ 25 Type: schema.TypeString, 26 ForceNew: true, 27 Required: true, 28 ValidateFunc: validateRedshiftSubnetGroupName, 29 }, 30 31 "description": &schema.Schema{ 32 Type: schema.TypeString, 33 Required: true, 34 }, 35 36 "subnet_ids": &schema.Schema{ 37 Type: schema.TypeSet, 38 Required: true, 39 Elem: &schema.Schema{Type: schema.TypeString}, 40 Set: schema.HashString, 41 }, 42 }, 43 } 44 } 45 46 func resourceAwsRedshiftSubnetGroupCreate(d *schema.ResourceData, meta interface{}) error { 47 conn := meta.(*AWSClient).redshiftconn 48 49 subnetIdsSet := d.Get("subnet_ids").(*schema.Set) 50 subnetIds := make([]*string, subnetIdsSet.Len()) 51 for i, subnetId := range subnetIdsSet.List() { 52 subnetIds[i] = aws.String(subnetId.(string)) 53 } 54 55 createOpts := redshift.CreateClusterSubnetGroupInput{ 56 ClusterSubnetGroupName: aws.String(d.Get("name").(string)), 57 Description: aws.String(d.Get("description").(string)), 58 SubnetIds: subnetIds, 59 } 60 61 log.Printf("[DEBUG] Create Redshift Subnet Group: %#v", createOpts) 62 _, err := conn.CreateClusterSubnetGroup(&createOpts) 63 if err != nil { 64 return fmt.Errorf("Error creating Redshift Subnet Group: %s", err) 65 } 66 67 d.SetId(*createOpts.ClusterSubnetGroupName) 68 log.Printf("[INFO] Redshift Subnet Group ID: %s", d.Id()) 69 return resourceAwsRedshiftSubnetGroupRead(d, meta) 70 } 71 72 func resourceAwsRedshiftSubnetGroupRead(d *schema.ResourceData, meta interface{}) error { 73 conn := meta.(*AWSClient).redshiftconn 74 75 describeOpts := redshift.DescribeClusterSubnetGroupsInput{ 76 ClusterSubnetGroupName: aws.String(d.Id()), 77 } 78 79 describeResp, err := conn.DescribeClusterSubnetGroups(&describeOpts) 80 if err != nil { 81 if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "ClusterSubnetGroupNotFoundFault" { 82 log.Printf("[INFO] Redshift Subnet Group: %s was not found", d.Id()) 83 d.SetId("") 84 return nil 85 } 86 return err 87 } 88 89 if len(describeResp.ClusterSubnetGroups) == 0 { 90 return fmt.Errorf("Unable to find Redshift Subnet Group: %#v", describeResp.ClusterSubnetGroups) 91 } 92 93 d.Set("name", d.Id()) 94 d.Set("description", describeResp.ClusterSubnetGroups[0].Description) 95 d.Set("subnet_ids", subnetIdsToSlice(describeResp.ClusterSubnetGroups[0].Subnets)) 96 97 return nil 98 } 99 100 func resourceAwsRedshiftSubnetGroupUpdate(d *schema.ResourceData, meta interface{}) error { 101 conn := meta.(*AWSClient).redshiftconn 102 if d.HasChange("subnet_ids") { 103 _, n := d.GetChange("subnet_ids") 104 if n == nil { 105 n = new(schema.Set) 106 } 107 ns := n.(*schema.Set) 108 109 var sIds []*string 110 for _, s := range ns.List() { 111 sIds = append(sIds, aws.String(s.(string))) 112 } 113 114 _, err := conn.ModifyClusterSubnetGroup(&redshift.ModifyClusterSubnetGroupInput{ 115 ClusterSubnetGroupName: aws.String(d.Id()), 116 SubnetIds: sIds, 117 }) 118 119 if err != nil { 120 return err 121 } 122 } 123 124 return nil 125 } 126 127 func resourceAwsRedshiftSubnetGroupDelete(d *schema.ResourceData, meta interface{}) error { 128 stateConf := &resource.StateChangeConf{ 129 Pending: []string{"pending"}, 130 Target: "destroyed", 131 Refresh: resourceAwsRedshiftSubnetGroupDeleteRefreshFunc(d, meta), 132 Timeout: 3 * time.Minute, 133 MinTimeout: 1 * time.Second, 134 } 135 _, err := stateConf.WaitForState() 136 return err 137 } 138 139 func resourceAwsRedshiftSubnetGroupDeleteRefreshFunc(d *schema.ResourceData, meta interface{}) resource.StateRefreshFunc { 140 conn := meta.(*AWSClient).redshiftconn 141 142 return func() (interface{}, string, error) { 143 144 deleteOpts := redshift.DeleteClusterSubnetGroupInput{ 145 ClusterSubnetGroupName: aws.String(d.Id()), 146 } 147 148 if _, err := conn.DeleteClusterSubnetGroup(&deleteOpts); err != nil { 149 redshiftErr, ok := err.(awserr.Error) 150 if !ok { 151 return d, "error", err 152 } 153 154 if redshiftErr.Code() != "ClusterSubnetGroupNotFoundFault" { 155 return d, "error", err 156 } 157 } 158 159 return d, "destroyed", nil 160 } 161 } 162 163 func subnetIdsToSlice(subnetIds []*redshift.Subnet) []string { 164 subnetsSlice := make([]string, 0, len(subnetIds)) 165 for _, s := range subnetIds { 166 subnetsSlice = append(subnetsSlice, *s.SubnetIdentifier) 167 } 168 return subnetsSlice 169 } 170 171 func validateRedshiftSubnetGroupName(v interface{}, k string) (ws []string, errors []error) { 172 value := v.(string) 173 if !regexp.MustCompile(`^[0-9a-z-_]+$`).MatchString(value) { 174 errors = append(errors, fmt.Errorf( 175 "only lowercase alphanumeric characters, hyphens, underscores, and periods allowed in %q", k)) 176 } 177 if len(value) > 255 { 178 errors = append(errors, fmt.Errorf( 179 "%q cannot be longer than 255 characters", k)) 180 } 181 if regexp.MustCompile(`(?i)^default$`).MatchString(value) { 182 errors = append(errors, fmt.Errorf( 183 "%q is not allowed as %q", "Default", k)) 184 } 185 return 186 }