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  }