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