github.com/andresvia/terraform@v0.6.15-0.20160412045437-d51c75946785/builtin/providers/aws/resource_aws_rds_cluster_instance.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 "time" 7 8 "github.com/aws/aws-sdk-go/aws" 9 "github.com/aws/aws-sdk-go/service/rds" 10 "github.com/hashicorp/terraform/helper/resource" 11 "github.com/hashicorp/terraform/helper/schema" 12 ) 13 14 func resourceAwsRDSClusterInstance() *schema.Resource { 15 return &schema.Resource{ 16 Create: resourceAwsRDSClusterInstanceCreate, 17 Read: resourceAwsRDSClusterInstanceRead, 18 Update: resourceAwsRDSClusterInstanceUpdate, 19 Delete: resourceAwsRDSClusterInstanceDelete, 20 21 Schema: map[string]*schema.Schema{ 22 "identifier": &schema.Schema{ 23 Type: schema.TypeString, 24 Optional: true, 25 ForceNew: true, 26 ValidateFunc: validateRdsId, 27 }, 28 29 "db_subnet_group_name": &schema.Schema{ 30 Type: schema.TypeString, 31 Optional: true, 32 ForceNew: true, 33 Computed: true, 34 }, 35 36 "writer": &schema.Schema{ 37 Type: schema.TypeBool, 38 Computed: true, 39 }, 40 41 "cluster_identifier": &schema.Schema{ 42 Type: schema.TypeString, 43 Required: true, 44 ForceNew: true, 45 }, 46 47 "endpoint": &schema.Schema{ 48 Type: schema.TypeString, 49 Computed: true, 50 }, 51 52 "port": &schema.Schema{ 53 Type: schema.TypeInt, 54 Computed: true, 55 }, 56 57 "publicly_accessible": &schema.Schema{ 58 Type: schema.TypeBool, 59 Optional: true, 60 Default: false, 61 ForceNew: true, 62 }, 63 64 "instance_class": &schema.Schema{ 65 Type: schema.TypeString, 66 Required: true, 67 ForceNew: true, 68 }, 69 70 "tags": tagsSchema(), 71 }, 72 } 73 } 74 75 func resourceAwsRDSClusterInstanceCreate(d *schema.ResourceData, meta interface{}) error { 76 conn := meta.(*AWSClient).rdsconn 77 tags := tagsFromMapRDS(d.Get("tags").(map[string]interface{})) 78 79 createOpts := &rds.CreateDBInstanceInput{ 80 DBInstanceClass: aws.String(d.Get("instance_class").(string)), 81 DBClusterIdentifier: aws.String(d.Get("cluster_identifier").(string)), 82 Engine: aws.String("aurora"), 83 PubliclyAccessible: aws.Bool(d.Get("publicly_accessible").(bool)), 84 Tags: tags, 85 } 86 87 if v := d.Get("identifier").(string); v != "" { 88 createOpts.DBInstanceIdentifier = aws.String(v) 89 } else { 90 createOpts.DBInstanceIdentifier = aws.String(resource.UniqueId()) 91 } 92 93 if attr, ok := d.GetOk("db_subnet_group_name"); ok { 94 createOpts.DBSubnetGroupName = aws.String(attr.(string)) 95 } 96 97 log.Printf("[DEBUG] Creating RDS DB Instance opts: %s", createOpts) 98 resp, err := conn.CreateDBInstance(createOpts) 99 if err != nil { 100 return err 101 } 102 103 d.SetId(*resp.DBInstance.DBInstanceIdentifier) 104 105 // reuse db_instance refresh func 106 stateConf := &resource.StateChangeConf{ 107 Pending: []string{"creating", "backing-up", "modifying"}, 108 Target: []string{"available"}, 109 Refresh: resourceAwsDbInstanceStateRefreshFunc(d, meta), 110 Timeout: 40 * time.Minute, 111 MinTimeout: 10 * time.Second, 112 Delay: 10 * time.Second, 113 } 114 115 // Wait, catching any errors 116 _, err = stateConf.WaitForState() 117 if err != nil { 118 return err 119 } 120 121 return resourceAwsRDSClusterInstanceRead(d, meta) 122 } 123 124 func resourceAwsRDSClusterInstanceRead(d *schema.ResourceData, meta interface{}) error { 125 db, err := resourceAwsDbInstanceRetrieve(d, meta) 126 // Errors from this helper are always reportable 127 if err != nil { 128 return fmt.Errorf("[WARN] Error on retrieving RDS Cluster Instance (%s): %s", d.Id(), err) 129 } 130 // A nil response means "not found" 131 if db == nil { 132 log.Printf("[WARN] RDS Cluster Instance (%s): not found, removing from state.", d.Id()) 133 d.SetId("") 134 return nil 135 } 136 137 // Retreive DB Cluster information, to determine if this Instance is a writer 138 conn := meta.(*AWSClient).rdsconn 139 resp, err := conn.DescribeDBClusters(&rds.DescribeDBClustersInput{ 140 DBClusterIdentifier: db.DBClusterIdentifier, 141 }) 142 143 var dbc *rds.DBCluster 144 for _, c := range resp.DBClusters { 145 if *c.DBClusterIdentifier == *db.DBClusterIdentifier { 146 dbc = c 147 } 148 } 149 150 if dbc == nil { 151 return fmt.Errorf("[WARN] Error finding RDS Cluster (%s) for Cluster Instance (%s): %s", 152 *db.DBClusterIdentifier, *db.DBInstanceIdentifier, err) 153 } 154 155 for _, m := range dbc.DBClusterMembers { 156 if *db.DBInstanceIdentifier == *m.DBInstanceIdentifier { 157 if *m.IsClusterWriter == true { 158 d.Set("writer", true) 159 } else { 160 d.Set("writer", false) 161 } 162 } 163 } 164 165 if db.Endpoint != nil { 166 d.Set("endpoint", db.Endpoint.Address) 167 d.Set("port", db.Endpoint.Port) 168 } 169 170 d.Set("publicly_accessible", db.PubliclyAccessible) 171 172 // Fetch and save tags 173 arn, err := buildRDSARN(d.Id(), meta) 174 if err != nil { 175 log.Printf("[DEBUG] Error building ARN for RDS Cluster Instance (%s), not setting Tags", *db.DBInstanceIdentifier) 176 } else { 177 if err := saveTagsRDS(conn, d, arn); err != nil { 178 log.Printf("[WARN] Failed to save tags for RDS Cluster Instance (%s): %s", *db.DBClusterIdentifier, err) 179 } 180 } 181 182 return nil 183 } 184 185 func resourceAwsRDSClusterInstanceUpdate(d *schema.ResourceData, meta interface{}) error { 186 conn := meta.(*AWSClient).rdsconn 187 188 if arn, err := buildRDSARN(d.Id(), meta); err == nil { 189 if err := setTagsRDS(conn, d, arn); err != nil { 190 return err 191 } 192 } 193 194 return resourceAwsRDSClusterInstanceRead(d, meta) 195 } 196 197 func resourceAwsRDSClusterInstanceDelete(d *schema.ResourceData, meta interface{}) error { 198 conn := meta.(*AWSClient).rdsconn 199 200 log.Printf("[DEBUG] RDS Cluster Instance destroy: %v", d.Id()) 201 202 opts := rds.DeleteDBInstanceInput{DBInstanceIdentifier: aws.String(d.Id())} 203 204 log.Printf("[DEBUG] RDS Cluster Instance destroy configuration: %s", opts) 205 if _, err := conn.DeleteDBInstance(&opts); err != nil { 206 return err 207 } 208 209 // re-uses db_instance refresh func 210 log.Println("[INFO] Waiting for RDS Cluster Instance to be destroyed") 211 stateConf := &resource.StateChangeConf{ 212 Pending: []string{"modifying", "deleting"}, 213 Target: []string{}, 214 Refresh: resourceAwsDbInstanceStateRefreshFunc(d, meta), 215 Timeout: 40 * time.Minute, 216 MinTimeout: 10 * time.Second, 217 } 218 219 if _, err := stateConf.WaitForState(); err != nil { 220 return err 221 } 222 223 return nil 224 225 }