github.com/jsoriano/terraform@v0.6.7-0.20151026070445-8b70867fdd95/builtin/providers/aws/resource_aws_iam_role.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     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 resourceAwsIamRole() *schema.Resource {
    15  	return &schema.Resource{
    16  		Create: resourceAwsIamRoleCreate,
    17  		Read:   resourceAwsIamRoleRead,
    18  		// TODO
    19  		//Update: resourceAwsIamRoleUpdate,
    20  		Delete: resourceAwsIamRoleDelete,
    21  
    22  		Schema: map[string]*schema.Schema{
    23  			"arn": &schema.Schema{
    24  				Type:     schema.TypeString,
    25  				Computed: true,
    26  			},
    27  			"unique_id": &schema.Schema{
    28  				Type:     schema.TypeString,
    29  				Computed: true,
    30  			},
    31  			"name": &schema.Schema{
    32  				Type:     schema.TypeString,
    33  				Required: true,
    34  				ForceNew: true,
    35  				ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
    36  					// https://github.com/boto/botocore/blob/2485f5c/botocore/data/iam/2010-05-08/service-2.json#L8329-L8334
    37  					value := v.(string)
    38  					if len(value) > 64 {
    39  						errors = append(errors, fmt.Errorf(
    40  							"%q cannot be longer than 64 characters", k))
    41  					}
    42  					if !regexp.MustCompile("^[\\w+=,.@-]*$").MatchString(value) {
    43  						errors = append(errors, fmt.Errorf(
    44  							"%q must match [\\w+=,.@-]", k))
    45  					}
    46  					return
    47  				},
    48  			},
    49  			"path": &schema.Schema{
    50  				Type:     schema.TypeString,
    51  				Optional: true,
    52  				Default:  "/",
    53  				ForceNew: true,
    54  			},
    55  			"assume_role_policy": &schema.Schema{
    56  				Type:     schema.TypeString,
    57  				Required: true,
    58  				ForceNew: true,
    59  			},
    60  		},
    61  	}
    62  }
    63  
    64  func resourceAwsIamRoleCreate(d *schema.ResourceData, meta interface{}) error {
    65  	iamconn := meta.(*AWSClient).iamconn
    66  	name := d.Get("name").(string)
    67  
    68  	request := &iam.CreateRoleInput{
    69  		Path:                     aws.String(d.Get("path").(string)),
    70  		RoleName:                 aws.String(name),
    71  		AssumeRolePolicyDocument: aws.String(d.Get("assume_role_policy").(string)),
    72  	}
    73  
    74  	createResp, err := iamconn.CreateRole(request)
    75  	if err != nil {
    76  		return fmt.Errorf("Error creating IAM Role %s: %s", name, err)
    77  	}
    78  	return resourceAwsIamRoleReadResult(d, createResp.Role)
    79  }
    80  
    81  func resourceAwsIamRoleRead(d *schema.ResourceData, meta interface{}) error {
    82  	iamconn := meta.(*AWSClient).iamconn
    83  
    84  	request := &iam.GetRoleInput{
    85  		RoleName: aws.String(d.Id()),
    86  	}
    87  
    88  	getResp, err := iamconn.GetRole(request)
    89  	if err != nil {
    90  		if iamerr, ok := err.(awserr.Error); ok && iamerr.Code() == "NoSuchEntity" { // XXX test me
    91  			d.SetId("")
    92  			return nil
    93  		}
    94  		return fmt.Errorf("Error reading IAM Role %s: %s", d.Id(), err)
    95  	}
    96  	return resourceAwsIamRoleReadResult(d, getResp.Role)
    97  }
    98  
    99  func resourceAwsIamRoleReadResult(d *schema.ResourceData, role *iam.Role) error {
   100  	d.SetId(*role.RoleName)
   101  	if err := d.Set("name", role.RoleName); err != nil {
   102  		return err
   103  	}
   104  	if err := d.Set("arn", role.Arn); err != nil {
   105  		return err
   106  	}
   107  	if err := d.Set("path", role.Path); err != nil {
   108  		return err
   109  	}
   110  	if err := d.Set("unique_id", role.RoleId); err != nil {
   111  		return err
   112  	}
   113  	return nil
   114  }
   115  
   116  func resourceAwsIamRoleDelete(d *schema.ResourceData, meta interface{}) error {
   117  	iamconn := meta.(*AWSClient).iamconn
   118  
   119  	// Roles cannot be destroyed when attached to an existing Instance Profile
   120  	resp, err := iamconn.ListInstanceProfilesForRole(&iam.ListInstanceProfilesForRoleInput{
   121  		RoleName: aws.String(d.Id()),
   122  	})
   123  	if err != nil {
   124  		return fmt.Errorf("Error listing Profiles for IAM Role (%s) when trying to delete: %s", d.Id(), err)
   125  	}
   126  
   127  	// Loop and remove this Role from any Profiles
   128  	if len(resp.InstanceProfiles) > 0 {
   129  		for _, i := range resp.InstanceProfiles {
   130  			_, err := iamconn.RemoveRoleFromInstanceProfile(&iam.RemoveRoleFromInstanceProfileInput{
   131  				InstanceProfileName: i.InstanceProfileName,
   132  				RoleName:            aws.String(d.Id()),
   133  			})
   134  			if err != nil {
   135  				return fmt.Errorf("Error deleting IAM Role %s: %s", d.Id(), err)
   136  			}
   137  		}
   138  	}
   139  
   140  	request := &iam.DeleteRoleInput{
   141  		RoleName: aws.String(d.Id()),
   142  	}
   143  
   144  	if _, err := iamconn.DeleteRole(request); err != nil {
   145  		return fmt.Errorf("Error deleting IAM Role %s: %s", d.Id(), err)
   146  	}
   147  	return nil
   148  }