github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/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:     "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  	if err != nil {
   127  		log.Printf("[WARN] Error on retrieving RDS Cluster Instance (%s): %s", d.Id(), err)
   128  		d.SetId("")
   129  		return nil
   130  	}
   131  
   132  	// Retreive DB Cluster information, to determine if this Instance is a writer
   133  	conn := meta.(*AWSClient).rdsconn
   134  	resp, err := conn.DescribeDBClusters(&rds.DescribeDBClustersInput{
   135  		DBClusterIdentifier: db.DBClusterIdentifier,
   136  	})
   137  
   138  	var dbc *rds.DBCluster
   139  	for _, c := range resp.DBClusters {
   140  		if *c.DBClusterIdentifier == *db.DBClusterIdentifier {
   141  			dbc = c
   142  		}
   143  	}
   144  
   145  	if dbc == nil {
   146  		return fmt.Errorf("[WARN] Error finding RDS Cluster (%s) for Cluster Instance (%s): %s",
   147  			*db.DBClusterIdentifier, *db.DBInstanceIdentifier, err)
   148  	}
   149  
   150  	for _, m := range dbc.DBClusterMembers {
   151  		if *db.DBInstanceIdentifier == *m.DBInstanceIdentifier {
   152  			if *m.IsClusterWriter == true {
   153  				d.Set("writer", true)
   154  			} else {
   155  				d.Set("writer", false)
   156  			}
   157  		}
   158  	}
   159  
   160  	if db.Endpoint != nil {
   161  		d.Set("endpoint", db.Endpoint.Address)
   162  		d.Set("port", db.Endpoint.Port)
   163  	}
   164  
   165  	d.Set("publicly_accessible", db.PubliclyAccessible)
   166  
   167  	// Fetch and save tags
   168  	arn, err := buildRDSARN(d, meta)
   169  	if err != nil {
   170  		log.Printf("[DEBUG] Error building ARN for RDS Cluster Instance (%s), not setting Tags", *db.DBInstanceIdentifier)
   171  	} else {
   172  		if err := saveTagsRDS(conn, d, arn); err != nil {
   173  			log.Printf("[WARN] Failed to save tags for RDS Cluster Instance (%s): %s", *db.DBClusterIdentifier, err)
   174  		}
   175  	}
   176  
   177  	return nil
   178  }
   179  
   180  func resourceAwsRDSClusterInstanceUpdate(d *schema.ResourceData, meta interface{}) error {
   181  	conn := meta.(*AWSClient).rdsconn
   182  
   183  	if arn, err := buildRDSARN(d, meta); err == nil {
   184  		if err := setTagsRDS(conn, d, arn); err != nil {
   185  			return err
   186  		}
   187  	}
   188  
   189  	return resourceAwsRDSClusterInstanceRead(d, meta)
   190  }
   191  
   192  func resourceAwsRDSClusterInstanceDelete(d *schema.ResourceData, meta interface{}) error {
   193  	conn := meta.(*AWSClient).rdsconn
   194  
   195  	log.Printf("[DEBUG] RDS Cluster Instance destroy: %v", d.Id())
   196  
   197  	opts := rds.DeleteDBInstanceInput{DBInstanceIdentifier: aws.String(d.Id())}
   198  
   199  	log.Printf("[DEBUG] RDS Cluster Instance destroy configuration: %s", opts)
   200  	if _, err := conn.DeleteDBInstance(&opts); err != nil {
   201  		return err
   202  	}
   203  
   204  	// re-uses db_instance refresh func
   205  	log.Println("[INFO] Waiting for RDS Cluster Instance to be destroyed")
   206  	stateConf := &resource.StateChangeConf{
   207  		Pending:    []string{"modifying", "deleting"},
   208  		Target:     "",
   209  		Refresh:    resourceAwsDbInstanceStateRefreshFunc(d, meta),
   210  		Timeout:    40 * time.Minute,
   211  		MinTimeout: 10 * time.Second,
   212  	}
   213  
   214  	if _, err := stateConf.WaitForState(); err != nil {
   215  		return err
   216  	}
   217  
   218  	return nil
   219  
   220  }