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