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 }