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