diff --git a/builtin/providers/aws/resource_aws_iam_group_membership.go b/builtin/providers/aws/resource_aws_iam_group_membership.go index c90511cd6..14bdd3713 100644 --- a/builtin/providers/aws/resource_aws_iam_group_membership.go +++ b/builtin/providers/aws/resource_aws_iam_group_membership.go @@ -135,6 +135,9 @@ func removeUsersFromGroup(conn *iam.IAM, users []*string, group string) error { }) if err != nil { + if iamerr, ok := err.(awserr.Error); ok && iamerr.Code() == "NoSuchEntity" { + return nil + } return err } } diff --git a/builtin/providers/aws/resource_aws_iam_user.go b/builtin/providers/aws/resource_aws_iam_user.go index e3811652f..daff0d97c 100644 --- a/builtin/providers/aws/resource_aws_iam_user.go +++ b/builtin/providers/aws/resource_aws_iam_user.go @@ -14,9 +14,7 @@ func resourceAwsIamUser() *schema.Resource { return &schema.Resource{ Create: resourceAwsIamUserCreate, Read: resourceAwsIamUserRead, - // There is an UpdateUser API call, but goamz doesn't support it yet. - // XXX but we aren't using goamz anymore. - //Update: resourceAwsIamUserUpdate, + Update: resourceAwsIamUserUpdate, Delete: resourceAwsIamUserDelete, Schema: map[string]*schema.Schema{ @@ -39,7 +37,6 @@ func resourceAwsIamUser() *schema.Resource { "name": &schema.Schema{ Type: schema.TypeString, Required: true, - ForceNew: true, }, "path": &schema.Schema{ Type: schema.TypeString, @@ -54,9 +51,10 @@ func resourceAwsIamUser() *schema.Resource { func resourceAwsIamUserCreate(d *schema.ResourceData, meta interface{}) error { iamconn := meta.(*AWSClient).iamconn name := d.Get("name").(string) + path := d.Get("path").(string) request := &iam.CreateUserInput{ - Path: aws.String(d.Get("path").(string)), + Path: aws.String(path), UserName: aws.String(name), } @@ -69,9 +67,9 @@ func resourceAwsIamUserCreate(d *schema.ResourceData, meta interface{}) error { func resourceAwsIamUserRead(d *schema.ResourceData, meta interface{}) error { iamconn := meta.(*AWSClient).iamconn - + name := d.Get("name").(string) request := &iam.GetUserInput{ - UserName: aws.String(d.Id()), + UserName: aws.String(name), } getResp, err := iamconn.GetUser(request) @@ -102,6 +100,29 @@ func resourceAwsIamUserReadResult(d *schema.ResourceData, user *iam.User) error return nil } +func resourceAwsIamUserUpdate(d *schema.ResourceData, meta interface{}) error { + if d.HasChange("name") || d.HasChange("path") { + iamconn := meta.(*AWSClient).iamconn + on, nn := d.GetChange("name") + op, np := d.GetChange("path") + fmt.Println(on, nn, op, np) + request := &iam.UpdateUserInput{ + UserName: aws.String(on.(string)), + NewUserName: aws.String(nn.(string)), + NewPath: aws.String(np.(string)), + } + _, err := iamconn.UpdateUser(request) + if err != nil { + if iamerr, ok := err.(awserr.Error); ok && iamerr.Code() == "NoSuchEntity" { + d.SetId("") + return nil + } + return fmt.Errorf("Error updating IAM User %s: %s", d.Id(), err) + } + return resourceAwsIamUserRead(d, meta) + } + return nil +} func resourceAwsIamUserDelete(d *schema.ResourceData, meta interface{}) error { iamconn := meta.(*AWSClient).iamconn diff --git a/builtin/providers/aws/resource_aws_iam_user_test.go b/builtin/providers/aws/resource_aws_iam_user_test.go index 0dd2530a1..d1ff3889e 100644 --- a/builtin/providers/aws/resource_aws_iam_user_test.go +++ b/builtin/providers/aws/resource_aws_iam_user_test.go @@ -23,7 +23,14 @@ func TestAccAWSUser_basic(t *testing.T) { Config: testAccAWSUserConfig, Check: resource.ComposeTestCheckFunc( testAccCheckAWSUserExists("aws_iam_user.user", &conf), - testAccCheckAWSUserAttributes(&conf), + testAccCheckAWSUserAttributes(&conf, "test-user", "/"), + ), + }, + resource.TestStep{ + Config: testAccAWSUserConfig2, + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSUserExists("aws_iam_user.user", &conf), + testAccCheckAWSUserAttributes(&conf, "test-user2", "/path2/"), ), }, }, @@ -85,13 +92,13 @@ func testAccCheckAWSUserExists(n string, res *iam.GetUserOutput) resource.TestCh } } -func testAccCheckAWSUserAttributes(user *iam.GetUserOutput) resource.TestCheckFunc { +func testAccCheckAWSUserAttributes(user *iam.GetUserOutput, name string, path string) resource.TestCheckFunc { return func(s *terraform.State) error { - if *user.User.UserName != "test-user" { + if *user.User.UserName != name { return fmt.Errorf("Bad name: %s", *user.User.UserName) } - if *user.User.Path != "/" { + if *user.User.Path != path { return fmt.Errorf("Bad path: %s", *user.User.Path) } @@ -105,3 +112,9 @@ resource "aws_iam_user" "user" { path = "/" } ` +const testAccAWSUserConfig2 = ` +resource "aws_iam_user" "user" { + name = "test-user2" + path = "/path2/" +} +`