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