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