github.com/ndarilek/terraform@v0.3.8-0.20150320140257-d3135c1b2bac/builtin/providers/aws/resource_aws_db_parameter_group.go (about)

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