github.com/pmcatominey/terraform@v0.7.0-rc2.0.20160708105029-1401a52a5cc5/builtin/providers/aws/resource_aws_iam_user.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 11 "github.com/hashicorp/terraform/helper/schema" 12 ) 13 14 func resourceAwsIamUser() *schema.Resource { 15 return &schema.Resource{ 16 Create: resourceAwsIamUserCreate, 17 Read: resourceAwsIamUserRead, 18 Update: resourceAwsIamUserUpdate, 19 Delete: resourceAwsIamUserDelete, 20 Importer: &schema.ResourceImporter{ 21 State: schema.ImportStatePassthrough, 22 }, 23 24 Schema: map[string]*schema.Schema{ 25 "arn": &schema.Schema{ 26 Type: schema.TypeString, 27 Computed: true, 28 }, 29 /* 30 The UniqueID could be used as the Id(), but none of the API 31 calls allow specifying a user by the UniqueID: they require the 32 name. The only way to locate a user by UniqueID is to list them 33 all and that would make this provider unnecessarilly complex 34 and inefficient. Still, there are other reasons one might want 35 the UniqueID, so we can make it available. 36 */ 37 "unique_id": &schema.Schema{ 38 Type: schema.TypeString, 39 Computed: true, 40 }, 41 "name": &schema.Schema{ 42 Type: schema.TypeString, 43 Required: true, 44 }, 45 "path": &schema.Schema{ 46 Type: schema.TypeString, 47 Optional: true, 48 Default: "/", 49 ForceNew: true, 50 }, 51 }, 52 } 53 } 54 55 func resourceAwsIamUserCreate(d *schema.ResourceData, meta interface{}) error { 56 iamconn := meta.(*AWSClient).iamconn 57 name := d.Get("name").(string) 58 path := d.Get("path").(string) 59 60 request := &iam.CreateUserInput{ 61 Path: aws.String(path), 62 UserName: aws.String(name), 63 } 64 65 log.Println("[DEBUG] Create IAM User request:", request) 66 createResp, err := iamconn.CreateUser(request) 67 if err != nil { 68 return fmt.Errorf("Error creating IAM User %s: %s", name, err) 69 } 70 d.SetId(*createResp.User.UserName) 71 return resourceAwsIamUserReadResult(d, createResp.User) 72 } 73 74 func resourceAwsIamUserRead(d *schema.ResourceData, meta interface{}) error { 75 iamconn := meta.(*AWSClient).iamconn 76 77 request := &iam.GetUserInput{ 78 UserName: aws.String(d.Id()), 79 } 80 81 getResp, err := iamconn.GetUser(request) 82 if err != nil { 83 if iamerr, ok := err.(awserr.Error); ok && iamerr.Code() == "NoSuchEntity" { // XXX test me 84 log.Printf("[WARN] No IAM user by name (%s) found", d.Id()) 85 d.SetId("") 86 return nil 87 } 88 return fmt.Errorf("Error reading IAM User %s: %s", d.Id(), err) 89 } 90 return resourceAwsIamUserReadResult(d, getResp.User) 91 } 92 93 func resourceAwsIamUserReadResult(d *schema.ResourceData, user *iam.User) error { 94 if err := d.Set("name", user.UserName); err != nil { 95 return err 96 } 97 if err := d.Set("arn", user.Arn); err != nil { 98 return err 99 } 100 if err := d.Set("path", user.Path); err != nil { 101 return err 102 } 103 if err := d.Set("unique_id", user.UserId); err != nil { 104 return err 105 } 106 return nil 107 } 108 109 func resourceAwsIamUserUpdate(d *schema.ResourceData, meta interface{}) error { 110 if d.HasChange("name") || d.HasChange("path") { 111 iamconn := meta.(*AWSClient).iamconn 112 on, nn := d.GetChange("name") 113 _, np := d.GetChange("path") 114 115 request := &iam.UpdateUserInput{ 116 UserName: aws.String(on.(string)), 117 NewUserName: aws.String(nn.(string)), 118 NewPath: aws.String(np.(string)), 119 } 120 121 log.Println("[DEBUG] Update IAM User request:", request) 122 _, err := iamconn.UpdateUser(request) 123 if err != nil { 124 if iamerr, ok := err.(awserr.Error); ok && iamerr.Code() == "NoSuchEntity" { 125 log.Printf("[WARN] No IAM user by name (%s) found", d.Id()) 126 d.SetId("") 127 return nil 128 } 129 return fmt.Errorf("Error updating IAM User %s: %s", d.Id(), err) 130 } 131 return resourceAwsIamUserRead(d, meta) 132 } 133 return nil 134 } 135 func resourceAwsIamUserDelete(d *schema.ResourceData, meta interface{}) error { 136 iamconn := meta.(*AWSClient).iamconn 137 138 // IAM Users must be removed from all groups before they can be deleted 139 var groups []string 140 var marker *string 141 truncated := aws.Bool(true) 142 143 for *truncated == true { 144 listOpts := iam.ListGroupsForUserInput{ 145 UserName: aws.String(d.Id()), 146 } 147 148 if marker != nil { 149 listOpts.Marker = marker 150 } 151 152 r, err := iamconn.ListGroupsForUser(&listOpts) 153 if err != nil { 154 return err 155 } 156 157 for _, g := range r.Groups { 158 groups = append(groups, *g.GroupName) 159 } 160 161 // if there's a marker present, we need to save it for pagination 162 if r.Marker != nil { 163 *marker = *r.Marker 164 } 165 *truncated = *r.IsTruncated 166 } 167 168 for _, g := range groups { 169 // use iam group membership func to remove user from all groups 170 log.Printf("[DEBUG] Removing IAM User %s from IAM Group %s", d.Id(), g) 171 if err := removeUsersFromGroup(iamconn, []*string{aws.String(d.Id())}, g); err != nil { 172 return err 173 } 174 } 175 176 request := &iam.DeleteUserInput{ 177 UserName: aws.String(d.Id()), 178 } 179 180 log.Println("[DEBUG] Delete IAM User request:", request) 181 if _, err := iamconn.DeleteUser(request); err != nil { 182 return fmt.Errorf("Error deleting IAM User %s: %s", d.Id(), err) 183 } 184 return nil 185 }