github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/builtin/providers/aws/resource_aws_iam_policy_attachment.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 7 "github.com/aws/aws-sdk-go/aws" 8 "github.com/aws/aws-sdk-go/aws/awserr" 9 "github.com/aws/aws-sdk-go/service/iam" 10 "github.com/hashicorp/terraform/helper/schema" 11 ) 12 13 func resourceAwsIamPolicyAttachment() *schema.Resource { 14 return &schema.Resource{ 15 Create: resourceAwsIamPolicyAttachmentCreate, 16 Read: resourceAwsIamPolicyAttachmentRead, 17 Update: resourceAwsIamPolicyAttachmentUpdate, 18 Delete: resourceAwsIamPolicyAttachmentDelete, 19 20 Schema: map[string]*schema.Schema{ 21 "name": &schema.Schema{ 22 Type: schema.TypeString, 23 Required: true, 24 ForceNew: true, 25 }, 26 "users": &schema.Schema{ 27 Type: schema.TypeSet, 28 Optional: true, 29 Elem: &schema.Schema{Type: schema.TypeString}, 30 Set: schema.HashString, 31 }, 32 "roles": &schema.Schema{ 33 Type: schema.TypeSet, 34 Optional: true, 35 Elem: &schema.Schema{Type: schema.TypeString}, 36 Set: schema.HashString, 37 }, 38 "groups": &schema.Schema{ 39 Type: schema.TypeSet, 40 Optional: true, 41 Elem: &schema.Schema{Type: schema.TypeString}, 42 Set: schema.HashString, 43 }, 44 "policy_arn": &schema.Schema{ 45 Type: schema.TypeString, 46 Required: true, 47 ForceNew: true, 48 }, 49 }, 50 } 51 } 52 53 func resourceAwsIamPolicyAttachmentCreate(d *schema.ResourceData, meta interface{}) error { 54 conn := meta.(*AWSClient).iamconn 55 56 name := d.Get("name").(string) 57 arn := d.Get("policy_arn").(string) 58 users := expandStringList(d.Get("users").(*schema.Set).List()) 59 roles := expandStringList(d.Get("roles").(*schema.Set).List()) 60 groups := expandStringList(d.Get("groups").(*schema.Set).List()) 61 62 if len(users) == 0 && len(roles) == 0 && len(groups) == 0 { 63 return fmt.Errorf("[WARN] No Users, Roles, or Groups specified for IAM Policy Attachment %s", name) 64 } else { 65 var userErr, roleErr, groupErr error 66 if users != nil { 67 userErr = attachPolicyToUsers(conn, users, arn) 68 } 69 if roles != nil { 70 roleErr = attachPolicyToRoles(conn, roles, arn) 71 } 72 if groups != nil { 73 groupErr = attachPolicyToGroups(conn, groups, arn) 74 } 75 if userErr != nil || roleErr != nil || groupErr != nil { 76 return composeErrors(fmt.Sprint("[WARN] Error attaching policy with IAM Policy Attachment ", name, ":"), userErr, roleErr, groupErr) 77 } 78 } 79 d.SetId(d.Get("name").(string)) 80 return resourceAwsIamPolicyAttachmentRead(d, meta) 81 } 82 83 func resourceAwsIamPolicyAttachmentRead(d *schema.ResourceData, meta interface{}) error { 84 conn := meta.(*AWSClient).iamconn 85 arn := d.Get("policy_arn").(string) 86 name := d.Get("name").(string) 87 88 _, err := conn.GetPolicy(&iam.GetPolicyInput{ 89 PolicyArn: aws.String(arn), 90 }) 91 92 if err != nil { 93 if awsErr, ok := err.(awserr.Error); ok { 94 if awsErr.Code() == "NoSuchEntity" { 95 log.Printf("[WARN] No such entity found for Policy Attachment (%s)", d.Id()) 96 d.SetId("") 97 return nil 98 } 99 } 100 return err 101 } 102 103 policyEntities, err := conn.ListEntitiesForPolicy(&iam.ListEntitiesForPolicyInput{ 104 PolicyArn: aws.String(arn), 105 }) 106 107 if err != nil { 108 return err 109 } 110 111 ul := make([]string, 0, len(policyEntities.PolicyUsers)) 112 rl := make([]string, 0, len(policyEntities.PolicyRoles)) 113 gl := make([]string, 0, len(policyEntities.PolicyGroups)) 114 115 for _, u := range policyEntities.PolicyUsers { 116 ul = append(ul, *u.UserName) 117 } 118 119 for _, r := range policyEntities.PolicyRoles { 120 rl = append(rl, *r.RoleName) 121 } 122 123 for _, g := range policyEntities.PolicyGroups { 124 gl = append(gl, *g.GroupName) 125 } 126 127 userErr := d.Set("users", ul) 128 roleErr := d.Set("roles", rl) 129 groupErr := d.Set("groups", gl) 130 131 if userErr != nil || roleErr != nil || groupErr != nil { 132 return composeErrors(fmt.Sprint("[WARN} Error setting user, role, or group list from IAM Policy Attachment ", name, ":"), userErr, roleErr, groupErr) 133 } 134 135 return nil 136 } 137 func resourceAwsIamPolicyAttachmentUpdate(d *schema.ResourceData, meta interface{}) error { 138 conn := meta.(*AWSClient).iamconn 139 name := d.Get("name").(string) 140 var userErr, roleErr, groupErr error 141 142 if d.HasChange("users") { 143 userErr = updateUsers(conn, d, meta) 144 } 145 if d.HasChange("roles") { 146 roleErr = updateRoles(conn, d, meta) 147 } 148 if d.HasChange("groups") { 149 groupErr = updateGroups(conn, d, meta) 150 } 151 if userErr != nil || roleErr != nil || groupErr != nil { 152 return composeErrors(fmt.Sprint("[WARN] Error updating user, role, or group list from IAM Policy Attachment ", name, ":"), userErr, roleErr, groupErr) 153 } 154 return resourceAwsIamPolicyAttachmentRead(d, meta) 155 } 156 157 func resourceAwsIamPolicyAttachmentDelete(d *schema.ResourceData, meta interface{}) error { 158 conn := meta.(*AWSClient).iamconn 159 name := d.Get("name").(string) 160 arn := d.Get("policy_arn").(string) 161 users := expandStringList(d.Get("users").(*schema.Set).List()) 162 roles := expandStringList(d.Get("roles").(*schema.Set).List()) 163 groups := expandStringList(d.Get("groups").(*schema.Set).List()) 164 165 var userErr, roleErr, groupErr error 166 if len(users) != 0 { 167 userErr = detachPolicyFromUsers(conn, users, arn) 168 } 169 if len(roles) != 0 { 170 roleErr = detachPolicyFromRoles(conn, roles, arn) 171 } 172 if len(groups) != 0 { 173 groupErr = detachPolicyFromGroups(conn, groups, arn) 174 } 175 if userErr != nil || roleErr != nil || groupErr != nil { 176 return composeErrors(fmt.Sprint("[WARN] Error removing user, role, or group list from IAM Policy Detach ", name, ":"), userErr, roleErr, groupErr) 177 } 178 return nil 179 } 180 181 func composeErrors(desc string, uErr error, rErr error, gErr error) error { 182 errMsg := fmt.Sprintf(desc) 183 errs := []error{uErr, rErr, gErr} 184 for _, e := range errs { 185 if e != nil { 186 errMsg = errMsg + "\n– " + e.Error() 187 } 188 } 189 return fmt.Errorf(errMsg) 190 } 191 192 func attachPolicyToUsers(conn *iam.IAM, users []*string, arn string) error { 193 for _, u := range users { 194 _, err := conn.AttachUserPolicy(&iam.AttachUserPolicyInput{ 195 UserName: u, 196 PolicyArn: aws.String(arn), 197 }) 198 if err != nil { 199 return err 200 } 201 } 202 return nil 203 } 204 func attachPolicyToRoles(conn *iam.IAM, roles []*string, arn string) error { 205 for _, r := range roles { 206 _, err := conn.AttachRolePolicy(&iam.AttachRolePolicyInput{ 207 RoleName: r, 208 PolicyArn: aws.String(arn), 209 }) 210 if err != nil { 211 return err 212 } 213 } 214 return nil 215 } 216 func attachPolicyToGroups(conn *iam.IAM, groups []*string, arn string) error { 217 for _, g := range groups { 218 _, err := conn.AttachGroupPolicy(&iam.AttachGroupPolicyInput{ 219 GroupName: g, 220 PolicyArn: aws.String(arn), 221 }) 222 if err != nil { 223 return err 224 } 225 } 226 return nil 227 } 228 func updateUsers(conn *iam.IAM, d *schema.ResourceData, meta interface{}) error { 229 arn := d.Get("policy_arn").(string) 230 o, n := d.GetChange("users") 231 if o == nil { 232 o = new(schema.Set) 233 } 234 if n == nil { 235 n = new(schema.Set) 236 } 237 os := o.(*schema.Set) 238 ns := n.(*schema.Set) 239 remove := expandStringList(os.Difference(ns).List()) 240 add := expandStringList(ns.Difference(os).List()) 241 242 if rErr := detachPolicyFromUsers(conn, remove, arn); rErr != nil { 243 return rErr 244 } 245 if aErr := attachPolicyToUsers(conn, add, arn); aErr != nil { 246 return aErr 247 } 248 return nil 249 } 250 func updateRoles(conn *iam.IAM, d *schema.ResourceData, meta interface{}) error { 251 arn := d.Get("policy_arn").(string) 252 o, n := d.GetChange("roles") 253 if o == nil { 254 o = new(schema.Set) 255 } 256 if n == nil { 257 n = new(schema.Set) 258 } 259 os := o.(*schema.Set) 260 ns := n.(*schema.Set) 261 remove := expandStringList(os.Difference(ns).List()) 262 add := expandStringList(ns.Difference(os).List()) 263 264 if rErr := detachPolicyFromRoles(conn, remove, arn); rErr != nil { 265 return rErr 266 } 267 if aErr := attachPolicyToRoles(conn, add, arn); aErr != nil { 268 return aErr 269 } 270 return nil 271 } 272 func updateGroups(conn *iam.IAM, d *schema.ResourceData, meta interface{}) error { 273 arn := d.Get("policy_arn").(string) 274 o, n := d.GetChange("groups") 275 if o == nil { 276 o = new(schema.Set) 277 } 278 if n == nil { 279 n = new(schema.Set) 280 } 281 os := o.(*schema.Set) 282 ns := n.(*schema.Set) 283 remove := expandStringList(os.Difference(ns).List()) 284 add := expandStringList(ns.Difference(os).List()) 285 286 if rErr := detachPolicyFromGroups(conn, remove, arn); rErr != nil { 287 return rErr 288 } 289 if aErr := attachPolicyToGroups(conn, add, arn); aErr != nil { 290 return aErr 291 } 292 return nil 293 294 } 295 func detachPolicyFromUsers(conn *iam.IAM, users []*string, arn string) error { 296 for _, u := range users { 297 _, err := conn.DetachUserPolicy(&iam.DetachUserPolicyInput{ 298 UserName: u, 299 PolicyArn: aws.String(arn), 300 }) 301 if err != nil { 302 return err 303 } 304 } 305 return nil 306 } 307 func detachPolicyFromRoles(conn *iam.IAM, roles []*string, arn string) error { 308 for _, r := range roles { 309 _, err := conn.DetachRolePolicy(&iam.DetachRolePolicyInput{ 310 RoleName: r, 311 PolicyArn: aws.String(arn), 312 }) 313 if err != nil { 314 return err 315 } 316 } 317 return nil 318 } 319 func detachPolicyFromGroups(conn *iam.IAM, groups []*string, arn string) error { 320 for _, g := range groups { 321 _, err := conn.DetachGroupPolicy(&iam.DetachGroupPolicyInput{ 322 GroupName: g, 323 PolicyArn: aws.String(arn), 324 }) 325 if err != nil { 326 return err 327 } 328 } 329 return nil 330 }