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