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