github.com/mohanarpit/terraform@v0.6.16-0.20160909104007-291f29853544/builtin/providers/aws/resource_aws_vpc_endpoint.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     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/ec2"
    10  	"github.com/hashicorp/terraform/helper/schema"
    11  )
    12  
    13  func resourceAwsVpcEndpoint() *schema.Resource {
    14  	return &schema.Resource{
    15  		Create: resourceAwsVPCEndpointCreate,
    16  		Read:   resourceAwsVPCEndpointRead,
    17  		Update: resourceAwsVPCEndpointUpdate,
    18  		Delete: resourceAwsVPCEndpointDelete,
    19  		Importer: &schema.ResourceImporter{
    20  			State: schema.ImportStatePassthrough,
    21  		},
    22  
    23  		Schema: map[string]*schema.Schema{
    24  			"policy": &schema.Schema{
    25  				Type:      schema.TypeString,
    26  				Optional:  true,
    27  				Computed:  true,
    28  				StateFunc: normalizeJson,
    29  			},
    30  			"vpc_id": &schema.Schema{
    31  				Type:     schema.TypeString,
    32  				Required: true,
    33  				ForceNew: true,
    34  			},
    35  			"service_name": &schema.Schema{
    36  				Type:     schema.TypeString,
    37  				Required: true,
    38  				ForceNew: true,
    39  			},
    40  			"route_table_ids": &schema.Schema{
    41  				Type:     schema.TypeSet,
    42  				Optional: true,
    43  				Elem:     &schema.Schema{Type: schema.TypeString},
    44  				Set:      schema.HashString,
    45  			},
    46  			"prefix_list_id": &schema.Schema{
    47  				Type:     schema.TypeString,
    48  				Computed: true,
    49  			},
    50  		},
    51  	}
    52  }
    53  
    54  func resourceAwsVPCEndpointCreate(d *schema.ResourceData, meta interface{}) error {
    55  	conn := meta.(*AWSClient).ec2conn
    56  	input := &ec2.CreateVpcEndpointInput{
    57  		VpcId:         aws.String(d.Get("vpc_id").(string)),
    58  		RouteTableIds: expandStringList(d.Get("route_table_ids").(*schema.Set).List()),
    59  		ServiceName:   aws.String(d.Get("service_name").(string)),
    60  	}
    61  
    62  	if v, ok := d.GetOk("policy"); ok {
    63  		policy := normalizeJson(v)
    64  		input.PolicyDocument = aws.String(policy)
    65  	}
    66  
    67  	log.Printf("[DEBUG] Creating VPC Endpoint: %#v", input)
    68  	output, err := conn.CreateVpcEndpoint(input)
    69  	if err != nil {
    70  		return fmt.Errorf("Error creating VPC Endpoint: %s", err)
    71  	}
    72  	log.Printf("[DEBUG] VPC Endpoint %q created.", *output.VpcEndpoint.VpcEndpointId)
    73  
    74  	d.SetId(*output.VpcEndpoint.VpcEndpointId)
    75  
    76  	return resourceAwsVPCEndpointRead(d, meta)
    77  }
    78  
    79  func resourceAwsVPCEndpointRead(d *schema.ResourceData, meta interface{}) error {
    80  	conn := meta.(*AWSClient).ec2conn
    81  	input := &ec2.DescribeVpcEndpointsInput{
    82  		VpcEndpointIds: []*string{aws.String(d.Id())},
    83  	}
    84  
    85  	log.Printf("[DEBUG] Reading VPC Endpoint: %q", d.Id())
    86  	output, err := conn.DescribeVpcEndpoints(input)
    87  
    88  	if err != nil {
    89  		ec2err, ok := err.(awserr.Error)
    90  		if !ok {
    91  			return fmt.Errorf("Error reading VPC Endpoint: %s", err.Error())
    92  		}
    93  
    94  		if ec2err.Code() == "InvalidVpcEndpointId.NotFound" {
    95  			return nil
    96  		}
    97  
    98  		return fmt.Errorf("Error reading VPC Endpoint: %s", err.Error())
    99  	}
   100  
   101  	if len(output.VpcEndpoints) != 1 {
   102  		return fmt.Errorf("There's no unique VPC Endpoint, but %d endpoints: %#v",
   103  			len(output.VpcEndpoints), output.VpcEndpoints)
   104  	}
   105  
   106  	vpce := output.VpcEndpoints[0]
   107  
   108  	// A VPC Endpoint is associated with exactly one prefix list name (also called Service Name).
   109  	// The prefix list ID can be used in security groups, so retrieve it to support that capability.
   110  	prefixListServiceName := *vpce.ServiceName
   111  	prefixListInput := &ec2.DescribePrefixListsInput{
   112  		Filters: []*ec2.Filter{
   113  			{Name: aws.String("prefix-list-name"), Values: []*string{aws.String(prefixListServiceName)}},
   114  		},
   115  	}
   116  
   117  	log.Printf("[DEBUG] Reading VPC Endpoint prefix list: %s", prefixListServiceName)
   118  	prefixListsOutput, err := conn.DescribePrefixLists(prefixListInput)
   119  
   120  	if err != nil {
   121  		_, ok := err.(awserr.Error)
   122  		if !ok {
   123  			return fmt.Errorf("Error reading VPC Endpoint prefix list: %s", err.Error())
   124  		}
   125  	}
   126  
   127  	if len(prefixListsOutput.PrefixLists) != 1 {
   128  		return fmt.Errorf("There are multiple prefix lists associated with the service name '%s'. Unexpected", prefixListServiceName)
   129  	}
   130  
   131  	d.Set("vpc_id", vpce.VpcId)
   132  	d.Set("policy", normalizeJson(*vpce.PolicyDocument))
   133  	d.Set("service_name", vpce.ServiceName)
   134  	if err := d.Set("route_table_ids", aws.StringValueSlice(vpce.RouteTableIds)); err != nil {
   135  		return err
   136  	}
   137  	d.Set("prefix_list_id", prefixListsOutput.PrefixLists[0].PrefixListId)
   138  
   139  	return nil
   140  }
   141  
   142  func resourceAwsVPCEndpointUpdate(d *schema.ResourceData, meta interface{}) error {
   143  	conn := meta.(*AWSClient).ec2conn
   144  	input := &ec2.ModifyVpcEndpointInput{
   145  		VpcEndpointId: aws.String(d.Id()),
   146  	}
   147  
   148  	if d.HasChange("route_table_ids") {
   149  		o, n := d.GetChange("route_table_ids")
   150  		os := o.(*schema.Set)
   151  		ns := n.(*schema.Set)
   152  
   153  		add := expandStringList(ns.Difference(os).List())
   154  		if len(add) > 0 {
   155  			input.AddRouteTableIds = add
   156  		}
   157  
   158  		remove := expandStringList(os.Difference(ns).List())
   159  		if len(remove) > 0 {
   160  			input.RemoveRouteTableIds = remove
   161  		}
   162  	}
   163  
   164  	if d.HasChange("policy") {
   165  		policy := normalizeJson(d.Get("policy"))
   166  		input.PolicyDocument = aws.String(policy)
   167  	}
   168  
   169  	log.Printf("[DEBUG] Updating VPC Endpoint: %#v", input)
   170  	_, err := conn.ModifyVpcEndpoint(input)
   171  	if err != nil {
   172  		return fmt.Errorf("Error updating VPC Endpoint: %s", err)
   173  	}
   174  	log.Printf("[DEBUG] VPC Endpoint %q updated", input.VpcEndpointId)
   175  
   176  	return resourceAwsVPCEndpointRead(d, meta)
   177  }
   178  
   179  func resourceAwsVPCEndpointDelete(d *schema.ResourceData, meta interface{}) error {
   180  	conn := meta.(*AWSClient).ec2conn
   181  	input := &ec2.DeleteVpcEndpointsInput{
   182  		VpcEndpointIds: []*string{aws.String(d.Id())},
   183  	}
   184  
   185  	log.Printf("[DEBUG] Deleting VPC Endpoint: %#v", input)
   186  	_, err := conn.DeleteVpcEndpoints(input)
   187  
   188  	if err != nil {
   189  		ec2err, ok := err.(awserr.Error)
   190  		if !ok {
   191  			return fmt.Errorf("Error deleting VPC Endpoint: %s", err.Error())
   192  		}
   193  
   194  		if ec2err.Code() == "InvalidVpcEndpointId.NotFound" {
   195  			log.Printf("[DEBUG] VPC Endpoint %q is already gone", d.Id())
   196  		} else {
   197  			return fmt.Errorf("Error deleting VPC Endpoint: %s", err.Error())
   198  		}
   199  	}
   200  
   201  	log.Printf("[DEBUG] VPC Endpoint %q deleted", d.Id())
   202  	d.SetId("")
   203  
   204  	return nil
   205  }