github.com/minamijoyo/terraform@v0.7.8-0.20161029001309-18b3736ba44b/builtin/providers/aws/resource_aws_iam_role_policy.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "net/url" 6 "regexp" 7 "strings" 8 9 "github.com/aws/aws-sdk-go/aws" 10 "github.com/aws/aws-sdk-go/aws/awserr" 11 "github.com/aws/aws-sdk-go/service/iam" 12 13 "github.com/hashicorp/terraform/helper/schema" 14 ) 15 16 func resourceAwsIamRolePolicy() *schema.Resource { 17 return &schema.Resource{ 18 // PutRolePolicy API is idempotent, so these can be the same. 19 Create: resourceAwsIamRolePolicyPut, 20 Update: resourceAwsIamRolePolicyPut, 21 22 Read: resourceAwsIamRolePolicyRead, 23 Delete: resourceAwsIamRolePolicyDelete, 24 25 Schema: map[string]*schema.Schema{ 26 "policy": &schema.Schema{ 27 Type: schema.TypeString, 28 Required: 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#L8291-L8296 36 value := v.(string) 37 if len(value) > 128 { 38 errors = append(errors, fmt.Errorf( 39 "%q cannot be longer than 128 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 "role": &schema.Schema{ 49 Type: schema.TypeString, 50 Required: true, 51 ForceNew: true, 52 }, 53 }, 54 } 55 } 56 57 func resourceAwsIamRolePolicyPut(d *schema.ResourceData, meta interface{}) error { 58 iamconn := meta.(*AWSClient).iamconn 59 60 request := &iam.PutRolePolicyInput{ 61 RoleName: aws.String(d.Get("role").(string)), 62 PolicyName: aws.String(d.Get("name").(string)), 63 PolicyDocument: aws.String(d.Get("policy").(string)), 64 } 65 66 if _, err := iamconn.PutRolePolicy(request); err != nil { 67 return fmt.Errorf("Error putting IAM role policy %s: %s", *request.PolicyName, err) 68 } 69 70 d.SetId(fmt.Sprintf("%s:%s", *request.RoleName, *request.PolicyName)) 71 return nil 72 } 73 74 func resourceAwsIamRolePolicyRead(d *schema.ResourceData, meta interface{}) error { 75 iamconn := meta.(*AWSClient).iamconn 76 77 role, name := resourceAwsIamRolePolicyParseId(d.Id()) 78 79 request := &iam.GetRolePolicyInput{ 80 PolicyName: aws.String(name), 81 RoleName: aws.String(role), 82 } 83 84 var err error 85 getResp, err := iamconn.GetRolePolicy(request) 86 if err != nil { 87 if iamerr, ok := err.(awserr.Error); ok && iamerr.Code() == "NoSuchEntity" { // XXX test me 88 d.SetId("") 89 return nil 90 } 91 return fmt.Errorf("Error reading IAM policy %s from role %s: %s", name, role, err) 92 } 93 94 if getResp.PolicyDocument == nil { 95 return fmt.Errorf("GetRolePolicy returned a nil policy document") 96 } 97 98 policy, err := url.QueryUnescape(*getResp.PolicyDocument) 99 if err != nil { 100 return err 101 } 102 return d.Set("policy", policy) 103 } 104 105 func resourceAwsIamRolePolicyDelete(d *schema.ResourceData, meta interface{}) error { 106 iamconn := meta.(*AWSClient).iamconn 107 108 role, name := resourceAwsIamRolePolicyParseId(d.Id()) 109 110 request := &iam.DeleteRolePolicyInput{ 111 PolicyName: aws.String(name), 112 RoleName: aws.String(role), 113 } 114 115 if _, err := iamconn.DeleteRolePolicy(request); err != nil { 116 return fmt.Errorf("Error deleting IAM role policy %s: %s", d.Id(), err) 117 } 118 return nil 119 } 120 121 func resourceAwsIamRolePolicyParseId(id string) (roleName, policyName string) { 122 parts := strings.SplitN(id, ":", 2) 123 roleName = parts[0] 124 policyName = parts[1] 125 return 126 }