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  }