github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/builtin/providers/aws/resource_aws_iam_instance_profile.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 resourceAwsIamInstanceProfile() *schema.Resource { 15 return &schema.Resource{ 16 Create: resourceAwsIamInstanceProfileCreate, 17 Read: resourceAwsIamInstanceProfileRead, 18 Update: resourceAwsIamInstanceProfileUpdate, 19 Delete: resourceAwsIamInstanceProfileDelete, 20 21 Schema: map[string]*schema.Schema{ 22 "arn": &schema.Schema{ 23 Type: schema.TypeString, 24 Computed: true, 25 }, 26 "create_date": &schema.Schema{ 27 Type: schema.TypeString, 28 Computed: true, 29 }, 30 "unique_id": &schema.Schema{ 31 Type: schema.TypeString, 32 Computed: true, 33 }, 34 "name": &schema.Schema{ 35 Type: schema.TypeString, 36 Required: true, 37 ForceNew: true, 38 ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { 39 // https://github.com/boto/botocore/blob/2485f5c/botocore/data/iam/2010-05-08/service-2.json#L8196-L8201 40 value := v.(string) 41 if len(value) > 128 { 42 errors = append(errors, fmt.Errorf( 43 "%q cannot be longer than 128 characters", k)) 44 } 45 if !regexp.MustCompile("^[\\w+=,.@-]+$").MatchString(value) { 46 errors = append(errors, fmt.Errorf( 47 "%q must match [\\w+=,.@-]", k)) 48 } 49 return 50 }, 51 }, 52 "path": &schema.Schema{ 53 Type: schema.TypeString, 54 Optional: true, 55 Default: "/", 56 ForceNew: true, 57 }, 58 "roles": &schema.Schema{ 59 Type: schema.TypeSet, 60 Required: true, 61 Elem: &schema.Schema{Type: schema.TypeString}, 62 Set: schema.HashString, 63 }, 64 }, 65 } 66 } 67 68 func resourceAwsIamInstanceProfileCreate(d *schema.ResourceData, meta interface{}) error { 69 iamconn := meta.(*AWSClient).iamconn 70 name := d.Get("name").(string) 71 72 request := &iam.CreateInstanceProfileInput{ 73 InstanceProfileName: aws.String(name), 74 Path: aws.String(d.Get("path").(string)), 75 } 76 77 var err error 78 response, err := iamconn.CreateInstanceProfile(request) 79 if err == nil { 80 err = instanceProfileReadResult(d, response.InstanceProfile) 81 } 82 if err != nil { 83 return fmt.Errorf("Error creating IAM instance profile %s: %s", name, err) 84 } 85 86 return instanceProfileSetRoles(d, iamconn) 87 } 88 89 func instanceProfileAddRole(iamconn *iam.IAM, profileName, roleName string) error { 90 request := &iam.AddRoleToInstanceProfileInput{ 91 InstanceProfileName: aws.String(profileName), 92 RoleName: aws.String(roleName), 93 } 94 95 _, err := iamconn.AddRoleToInstanceProfile(request) 96 return err 97 } 98 99 func instanceProfileRemoveRole(iamconn *iam.IAM, profileName, roleName string) error { 100 request := &iam.RemoveRoleFromInstanceProfileInput{ 101 InstanceProfileName: aws.String(profileName), 102 RoleName: aws.String(roleName), 103 } 104 105 _, err := iamconn.RemoveRoleFromInstanceProfile(request) 106 if iamerr, ok := err.(awserr.Error); ok && iamerr.Code() == "NoSuchEntity" { 107 return nil 108 } 109 return err 110 } 111 112 func instanceProfileSetRoles(d *schema.ResourceData, iamconn *iam.IAM) error { 113 oldInterface, newInterface := d.GetChange("roles") 114 oldRoles := oldInterface.(*schema.Set) 115 newRoles := newInterface.(*schema.Set) 116 117 currentRoles := schema.CopySet(oldRoles) 118 119 d.Partial(true) 120 121 for _, role := range oldRoles.Difference(newRoles).List() { 122 err := instanceProfileRemoveRole(iamconn, d.Id(), role.(string)) 123 if err != nil { 124 return fmt.Errorf("Error removing role %s from IAM instance profile %s: %s", role, d.Id(), err) 125 } 126 currentRoles.Remove(role) 127 d.Set("roles", currentRoles) 128 d.SetPartial("roles") 129 } 130 131 for _, role := range newRoles.Difference(oldRoles).List() { 132 err := instanceProfileAddRole(iamconn, d.Id(), role.(string)) 133 if err != nil { 134 return fmt.Errorf("Error adding role %s to IAM instance profile %s: %s", role, d.Id(), err) 135 } 136 currentRoles.Add(role) 137 d.Set("roles", currentRoles) 138 d.SetPartial("roles") 139 } 140 141 d.Partial(false) 142 143 return nil 144 } 145 146 func instanceProfileRemoveAllRoles(d *schema.ResourceData, iamconn *iam.IAM) error { 147 for _, role := range d.Get("roles").(*schema.Set).List() { 148 err := instanceProfileRemoveRole(iamconn, d.Id(), role.(string)) 149 if err != nil { 150 return fmt.Errorf("Error removing role %s from IAM instance profile %s: %s", role, d.Id(), err) 151 } 152 } 153 return nil 154 } 155 156 func resourceAwsIamInstanceProfileUpdate(d *schema.ResourceData, meta interface{}) error { 157 iamconn := meta.(*AWSClient).iamconn 158 159 if !d.HasChange("roles") { 160 return nil 161 } 162 163 return instanceProfileSetRoles(d, iamconn) 164 } 165 166 func resourceAwsIamInstanceProfileRead(d *schema.ResourceData, meta interface{}) error { 167 iamconn := meta.(*AWSClient).iamconn 168 169 request := &iam.GetInstanceProfileInput{ 170 InstanceProfileName: aws.String(d.Id()), 171 } 172 173 result, err := iamconn.GetInstanceProfile(request) 174 if err != nil { 175 if iamerr, ok := err.(awserr.Error); ok && iamerr.Code() == "NoSuchEntity" { 176 d.SetId("") 177 return nil 178 } 179 return fmt.Errorf("Error reading IAM instance profile %s: %s", d.Id(), err) 180 } 181 182 return instanceProfileReadResult(d, result.InstanceProfile) 183 } 184 185 func resourceAwsIamInstanceProfileDelete(d *schema.ResourceData, meta interface{}) error { 186 iamconn := meta.(*AWSClient).iamconn 187 188 if err := instanceProfileRemoveAllRoles(d, iamconn); err != nil { 189 return err 190 } 191 192 request := &iam.DeleteInstanceProfileInput{ 193 InstanceProfileName: aws.String(d.Id()), 194 } 195 _, err := iamconn.DeleteInstanceProfile(request) 196 if err != nil { 197 return fmt.Errorf("Error deleting IAM instance profile %s: %s", d.Id(), err) 198 } 199 d.SetId("") 200 return nil 201 } 202 203 func instanceProfileReadResult(d *schema.ResourceData, result *iam.InstanceProfile) error { 204 d.SetId(*result.InstanceProfileName) 205 if err := d.Set("name", result.InstanceProfileName); err != nil { 206 return err 207 } 208 if err := d.Set("arn", result.Arn); err != nil { 209 return err 210 } 211 if err := d.Set("path", result.Path); err != nil { 212 return err 213 } 214 215 roles := &schema.Set{F: schema.HashString} 216 for _, role := range result.Roles { 217 roles.Add(*role.RoleName) 218 } 219 if err := d.Set("roles", roles); err != nil { 220 return err 221 } 222 223 return nil 224 }