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 }