github.com/rmenn/terraform@v0.3.8-0.20150225065417-fc84b3a78802/builtin/providers/aws/resource_aws_db_parameter_group.go (about)

     1  package aws
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"log"
     7  	"time"
     8  
     9  	"github.com/hashicorp/terraform/helper/hashcode"
    10  	"github.com/hashicorp/terraform/helper/resource"
    11  	"github.com/hashicorp/terraform/helper/schema"
    12  	"github.com/mitchellh/goamz/rds"
    13  )
    14  
    15  func resourceAwsDbParameterGroup() *schema.Resource {
    16  	return &schema.Resource{
    17  		Create: resourceAwsDbParameterGroupCreate,
    18  		Read:   resourceAwsDbParameterGroupRead,
    19  		Update: resourceAwsDbParameterGroupUpdate,
    20  		Delete: resourceAwsDbParameterGroupDelete,
    21  		Schema: map[string]*schema.Schema{
    22  			"name": &schema.Schema{
    23  				Type:     schema.TypeString,
    24  				ForceNew: true,
    25  				Required: true,
    26  			},
    27  			"family": &schema.Schema{
    28  				Type:     schema.TypeString,
    29  				Required: true,
    30  				ForceNew: true,
    31  			},
    32  			"description": &schema.Schema{
    33  				Type:     schema.TypeString,
    34  				Required: true,
    35  				ForceNew: true,
    36  			},
    37  			"parameter": &schema.Schema{
    38  				Type:     schema.TypeSet,
    39  				Optional: true,
    40  				ForceNew: false,
    41  				Elem: &schema.Resource{
    42  					Schema: map[string]*schema.Schema{
    43  						"name": &schema.Schema{
    44  							Type:     schema.TypeString,
    45  							Required: true,
    46  						},
    47  						"value": &schema.Schema{
    48  							Type:     schema.TypeString,
    49  							Required: true,
    50  						},
    51  						"apply_method": &schema.Schema{
    52  							Type:     schema.TypeString,
    53  							Optional: true,
    54  							Default:  "immediate",
    55  							// this parameter is not actually state, but a
    56  							// meta-parameter describing how the RDS API call
    57  							// to modify the parameter group should be made.
    58  							// Future reads of the resource from AWS don't tell
    59  							// us what we used for apply_method previously, so
    60  							// by squashing state to an empty string we avoid
    61  							// needing to do an update for every future run.
    62  							StateFunc: func(interface{}) string { return "" },
    63  						},
    64  					},
    65  				},
    66  				Set: resourceAwsDbParameterHash,
    67  			},
    68  		},
    69  	}
    70  }
    71  
    72  func resourceAwsDbParameterGroupCreate(d *schema.ResourceData, meta interface{}) error {
    73  	rdsconn := meta.(*AWSClient).rdsconn
    74  
    75  	createOpts := rds.CreateDBParameterGroup{
    76  		DBParameterGroupName:   d.Get("name").(string),
    77  		DBParameterGroupFamily: d.Get("family").(string),
    78  		Description:            d.Get("description").(string),
    79  	}
    80  
    81  	log.Printf("[DEBUG] Create DB Parameter Group: %#v", createOpts)
    82  	_, err := rdsconn.CreateDBParameterGroup(&createOpts)
    83  	if err != nil {
    84  		return fmt.Errorf("Error creating DB Parameter Group: %s", err)
    85  	}
    86  
    87  	d.Partial(true)
    88  	d.SetPartial("name")
    89  	d.SetPartial("family")
    90  	d.SetPartial("description")
    91  	d.Partial(false)
    92  
    93  	d.SetId(createOpts.DBParameterGroupName)
    94  	log.Printf("[INFO] DB Parameter Group ID: %s", d.Id())
    95  
    96  	return resourceAwsDbParameterGroupUpdate(d, meta)
    97  }
    98  
    99  func resourceAwsDbParameterGroupRead(d *schema.ResourceData, meta interface{}) error {
   100  	rdsconn := meta.(*AWSClient).rdsconn
   101  
   102  	describeOpts := rds.DescribeDBParameterGroups{
   103  		DBParameterGroupName: d.Id(),
   104  	}
   105  
   106  	describeResp, err := rdsconn.DescribeDBParameterGroups(&describeOpts)
   107  	if err != nil {
   108  		return err
   109  	}
   110  
   111  	if len(describeResp.DBParameterGroups) != 1 ||
   112  		describeResp.DBParameterGroups[0].DBParameterGroupName != d.Id() {
   113  		return fmt.Errorf("Unable to find Parameter Group: %#v", describeResp.DBParameterGroups)
   114  	}
   115  
   116  	d.Set("name", describeResp.DBParameterGroups[0].DBParameterGroupName)
   117  	d.Set("family", describeResp.DBParameterGroups[0].DBParameterGroupFamily)
   118  	d.Set("description", describeResp.DBParameterGroups[0].Description)
   119  
   120  	// Only include user customized parameters as there's hundreds of system/default ones
   121  	describeParametersOpts := rds.DescribeDBParameters{
   122  		DBParameterGroupName: d.Id(),
   123  		Source:               "user",
   124  	}
   125  
   126  	describeParametersResp, err := rdsconn.DescribeDBParameters(&describeParametersOpts)
   127  	if err != nil {
   128  		return err
   129  	}
   130  
   131  	d.Set("parameter", flattenParameters(describeParametersResp.Parameters))
   132  
   133  	return nil
   134  }
   135  
   136  func resourceAwsDbParameterGroupUpdate(d *schema.ResourceData, meta interface{}) error {
   137  	rdsconn := meta.(*AWSClient).rdsconn
   138  
   139  	d.Partial(true)
   140  
   141  	if d.HasChange("parameter") {
   142  		o, n := d.GetChange("parameter")
   143  		if o == nil {
   144  			o = new(schema.Set)
   145  		}
   146  		if n == nil {
   147  			n = new(schema.Set)
   148  		}
   149  
   150  		os := o.(*schema.Set)
   151  		ns := n.(*schema.Set)
   152  
   153  		// Expand the "parameter" set to goamz compat []rds.Parameter
   154  		parameters, err := expandParameters(ns.Difference(os).List())
   155  		if err != nil {
   156  			return err
   157  		}
   158  
   159  		if len(parameters) > 0 {
   160  			modifyOpts := rds.ModifyDBParameterGroup{
   161  				DBParameterGroupName: d.Get("name").(string),
   162  				Parameters:           parameters,
   163  			}
   164  
   165  			log.Printf("[DEBUG] Modify DB Parameter Group: %#v", modifyOpts)
   166  			_, err = rdsconn.ModifyDBParameterGroup(&modifyOpts)
   167  			if err != nil {
   168  				return fmt.Errorf("Error modifying DB Parameter Group: %s", err)
   169  			}
   170  		}
   171  		d.SetPartial("parameter")
   172  	}
   173  
   174  	d.Partial(false)
   175  
   176  	return resourceAwsDbParameterGroupRead(d, meta)
   177  }
   178  
   179  func resourceAwsDbParameterGroupDelete(d *schema.ResourceData, meta interface{}) error {
   180  	stateConf := &resource.StateChangeConf{
   181  		Pending:    []string{"pending"},
   182  		Target:     "destroyed",
   183  		Refresh:    resourceAwsDbParameterGroupDeleteRefreshFunc(d, meta),
   184  		Timeout:    3 * time.Minute,
   185  		MinTimeout: 1 * time.Second,
   186  	}
   187  	_, err := stateConf.WaitForState()
   188  	return err
   189  }
   190  
   191  func resourceAwsDbParameterGroupDeleteRefreshFunc(
   192  	d *schema.ResourceData,
   193  	meta interface{}) resource.StateRefreshFunc {
   194  	rdsconn := meta.(*AWSClient).rdsconn
   195  
   196  	return func() (interface{}, string, error) {
   197  
   198  		deleteOpts := rds.DeleteDBParameterGroup{
   199  			DBParameterGroupName: d.Id(),
   200  		}
   201  
   202  		if _, err := rdsconn.DeleteDBParameterGroup(&deleteOpts); err != nil {
   203  			rdserr, ok := err.(*rds.Error)
   204  			if !ok {
   205  				return d, "error", err
   206  			}
   207  
   208  			if rdserr.Code != "DBParameterGroupNotFoundFault" {
   209  				return d, "error", err
   210  			}
   211  		}
   212  
   213  		return d, "destroyed", nil
   214  	}
   215  }
   216  
   217  func resourceAwsDbParameterHash(v interface{}) int {
   218  	var buf bytes.Buffer
   219  	m := v.(map[string]interface{})
   220  	buf.WriteString(fmt.Sprintf("%s-", m["name"].(string)))
   221  	buf.WriteString(fmt.Sprintf("%s-", m["value"].(string)))
   222  
   223  	return hashcode.String(buf.String())
   224  }