github.com/koding/terraform@v0.6.4-0.20170608090606-5d7e0339779d/builtin/providers/aws/resource_aws_iam_role_policy.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"net/url"
     6  	"strings"
     7  
     8  	"github.com/aws/aws-sdk-go/aws"
     9  	"github.com/aws/aws-sdk-go/aws/awserr"
    10  	"github.com/aws/aws-sdk-go/service/iam"
    11  
    12  	"github.com/hashicorp/terraform/helper/resource"
    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  		Importer: &schema.ResourceImporter{
    25  			State: schema.ImportStatePassthrough,
    26  		},
    27  
    28  		Schema: map[string]*schema.Schema{
    29  			"policy": {
    30  				Type:             schema.TypeString,
    31  				Required:         true,
    32  				ValidateFunc:     validateIAMPolicyJson,
    33  				DiffSuppressFunc: suppressEquivalentAwsPolicyDiffs,
    34  			},
    35  			"name": {
    36  				Type:          schema.TypeString,
    37  				Optional:      true,
    38  				Computed:      true,
    39  				ForceNew:      true,
    40  				ConflictsWith: []string{"name_prefix"},
    41  				ValidateFunc:  validateIamRolePolicyName,
    42  			},
    43  			"name_prefix": {
    44  				Type:         schema.TypeString,
    45  				Optional:     true,
    46  				ForceNew:     true,
    47  				ValidateFunc: validateIamRolePolicyNamePrefix,
    48  			},
    49  			"role": {
    50  				Type:     schema.TypeString,
    51  				Required: true,
    52  				ForceNew: true,
    53  			},
    54  		},
    55  	}
    56  }
    57  
    58  func resourceAwsIamRolePolicyPut(d *schema.ResourceData, meta interface{}) error {
    59  	iamconn := meta.(*AWSClient).iamconn
    60  
    61  	request := &iam.PutRolePolicyInput{
    62  		RoleName:       aws.String(d.Get("role").(string)),
    63  		PolicyDocument: aws.String(d.Get("policy").(string)),
    64  	}
    65  
    66  	var policyName string
    67  	if v, ok := d.GetOk("name"); ok {
    68  		policyName = v.(string)
    69  	} else if v, ok := d.GetOk("name_prefix"); ok {
    70  		policyName = resource.PrefixedUniqueId(v.(string))
    71  	} else {
    72  		policyName = resource.UniqueId()
    73  	}
    74  	request.PolicyName = aws.String(policyName)
    75  
    76  	if _, err := iamconn.PutRolePolicy(request); err != nil {
    77  		return fmt.Errorf("Error putting IAM role policy %s: %s", *request.PolicyName, err)
    78  	}
    79  
    80  	d.SetId(fmt.Sprintf("%s:%s", *request.RoleName, *request.PolicyName))
    81  	return nil
    82  }
    83  
    84  func resourceAwsIamRolePolicyRead(d *schema.ResourceData, meta interface{}) error {
    85  	iamconn := meta.(*AWSClient).iamconn
    86  
    87  	role, name, err := resourceAwsIamRolePolicyParseId(d.Id())
    88  	if err != nil {
    89  		return err
    90  	}
    91  
    92  	request := &iam.GetRolePolicyInput{
    93  		PolicyName: aws.String(name),
    94  		RoleName:   aws.String(role),
    95  	}
    96  
    97  	getResp, err := iamconn.GetRolePolicy(request)
    98  	if err != nil {
    99  		if iamerr, ok := err.(awserr.Error); ok && iamerr.Code() == "NoSuchEntity" { // XXX test me
   100  			d.SetId("")
   101  			return nil
   102  		}
   103  		return fmt.Errorf("Error reading IAM policy %s from role %s: %s", name, role, err)
   104  	}
   105  
   106  	if getResp.PolicyDocument == nil {
   107  		return fmt.Errorf("GetRolePolicy returned a nil policy document")
   108  	}
   109  
   110  	policy, err := url.QueryUnescape(*getResp.PolicyDocument)
   111  	if err != nil {
   112  		return err
   113  	}
   114  	if err := d.Set("policy", policy); err != nil {
   115  		return err
   116  	}
   117  	if err := d.Set("name", name); err != nil {
   118  		return err
   119  	}
   120  	return d.Set("role", role)
   121  }
   122  
   123  func resourceAwsIamRolePolicyDelete(d *schema.ResourceData, meta interface{}) error {
   124  	iamconn := meta.(*AWSClient).iamconn
   125  
   126  	role, name, err := resourceAwsIamRolePolicyParseId(d.Id())
   127  	if err != nil {
   128  		return err
   129  	}
   130  
   131  	request := &iam.DeleteRolePolicyInput{
   132  		PolicyName: aws.String(name),
   133  		RoleName:   aws.String(role),
   134  	}
   135  
   136  	if _, err := iamconn.DeleteRolePolicy(request); err != nil {
   137  		return fmt.Errorf("Error deleting IAM role policy %s: %s", d.Id(), err)
   138  	}
   139  	return nil
   140  }
   141  
   142  func resourceAwsIamRolePolicyParseId(id string) (roleName, policyName string, err error) {
   143  	parts := strings.SplitN(id, ":", 2)
   144  	if len(parts) != 2 {
   145  		err = fmt.Errorf("role_policy id must be of the form <role name>:<policy name>")
   146  		return
   147  	}
   148  
   149  	roleName = parts[0]
   150  	policyName = parts[1]
   151  	return
   152  }