github.com/hobbeswalsh/terraform@v0.3.7-0.20150619183303-ad17cf55a0fa/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: %#v", 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 }