github.com/mhlias/terraform@v0.6.12-0.20161118140322-a5d6410b912a/builtin/providers/aws/resource_aws_dc_virtual_interface.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"time"
     7  
     8  	"github.com/aws/aws-sdk-go/aws"
     9  	"github.com/aws/aws-sdk-go/service/directconnect"
    10  
    11  	"github.com/hashicorp/terraform/helper/hashcode"
    12  	"github.com/hashicorp/terraform/helper/resource"
    13  	"github.com/hashicorp/terraform/helper/schema"
    14  )
    15  
    16  func resourceAwsDirectConnectVirtualInterface() *schema.Resource {
    17  	return &schema.Resource{
    18  		Create: resourceAwsDirectConnectVirtualInterfaceCreate,
    19  		Read:   resourceAwsDirectConnectVirtualInterfaceRead,
    20  		Delete: resourceAwsDirectConnectVirtualInterfaceDelete,
    21  
    22  		Schema: map[string]*schema.Schema{
    23  			"connection_id": &schema.Schema{
    24  				Type:     schema.TypeString,
    25  				Required: true,
    26  				ForceNew: true,
    27  			},
    28  
    29  			"asn": &schema.Schema{
    30  				Type:     schema.TypeInt,
    31  				Required: true,
    32  				ForceNew: true,
    33  			},
    34  
    35  			"virtual_interface_name": &schema.Schema{
    36  				Type:     schema.TypeString,
    37  				Required: true,
    38  				ForceNew: true,
    39  			},
    40  
    41  			"virtual_gateway_id": &schema.Schema{
    42  				Type:     schema.TypeString,
    43  				Optional: true,
    44  				ForceNew: true,
    45  			},
    46  
    47  			"vlan": &schema.Schema{
    48  				Type:     schema.TypeInt,
    49  				Required: true,
    50  				ForceNew: true,
    51  			},
    52  
    53  			"amazon_address": &schema.Schema{
    54  				Type:     schema.TypeString,
    55  				Optional: true,
    56  				Computed: true,
    57  				ForceNew: true,
    58  			},
    59  
    60  			"customer_address": &schema.Schema{
    61  				Type:     schema.TypeString,
    62  				Optional: true,
    63  				Computed: true,
    64  				ForceNew: true,
    65  			},
    66  
    67  			"auth_key": &schema.Schema{
    68  				Type:     schema.TypeString,
    69  				Optional: true,
    70  				Computed: true,
    71  				ForceNew: true,
    72  			},
    73  
    74  			"interface_type": &schema.Schema{
    75  				Type:     schema.TypeString,
    76  				Optional: true,
    77  				ForceNew: true,
    78  			},
    79  
    80  			"route_filter_prefixes": &schema.Schema{
    81  				Type:     schema.TypeSet,
    82  				Optional: true,
    83  				ForceNew: true,
    84  				Elem:     &schema.Schema{Type: schema.TypeString},
    85  				Set: func(v interface{}) int {
    86  					return hashcode.String(v.(string))
    87  				},
    88  			},
    89  		},
    90  	}
    91  }
    92  
    93  func resourceAwsDirectConnectVirtualInterfaceCreate(d *schema.ResourceData, meta interface{}) error {
    94  	conn := meta.(*AWSClient).dcconn
    95  
    96  	var err error
    97  	var resp *directconnect.VirtualInterface
    98  
    99  	if v, ok := d.GetOk("interface_type"); ok && v.(string) == "public" {
   100  
   101  		createOpts := &directconnect.CreatePublicVirtualInterfaceInput{
   102  			ConnectionId: aws.String(d.Get("connection_id").(string)),
   103  			NewPublicVirtualInterface: &directconnect.NewPublicVirtualInterface{
   104  				Asn:                  aws.Int64(int64(d.Get("asn").(int))),
   105  				VirtualInterfaceName: aws.String(d.Get("virtual_interface_name").(string)),
   106  				Vlan:                 aws.Int64(int64(d.Get("vlan").(int))),
   107  			},
   108  		}
   109  
   110  		if v, ok := d.GetOk("amazon_address"); ok {
   111  			createOpts.NewPublicVirtualInterface.AmazonAddress = aws.String(v.(string))
   112  		}
   113  
   114  		if v, ok := d.GetOk("auth_key"); ok {
   115  			createOpts.NewPublicVirtualInterface.AuthKey = aws.String(v.(string))
   116  		}
   117  
   118  		if v, ok := d.GetOk("customer_address"); ok {
   119  			createOpts.NewPublicVirtualInterface.CustomerAddress = aws.String(v.(string))
   120  		}
   121  
   122  		if prefixesSet, ok := d.Get("route_filter_prefixes").(*schema.Set); ok {
   123  
   124  			createOpts.NewPublicVirtualInterface.RouteFilterPrefixes = []*directconnect.RouteFilterPrefix{}
   125  
   126  			for _, cidr := range prefixesSet.List() {
   127  				createOpts.NewPublicVirtualInterface.RouteFilterPrefixes = append(createOpts.NewPublicVirtualInterface.RouteFilterPrefixes, &directconnect.RouteFilterPrefix{Cidr: aws.String(cidr.(string))})
   128  			}
   129  
   130  		}
   131  
   132  		log.Println("[DEBUG] request structure: ", createOpts)
   133  		// Create the DirectConnect Connection
   134  		log.Printf("[DEBUG] Creating DirectConnect public virtual interface")
   135  		resp, err = conn.CreatePublicVirtualInterface(createOpts)
   136  		if err != nil {
   137  			return fmt.Errorf("Error creating DirectConnect public virtual interface: %s", err)
   138  		}
   139  
   140  	} else {
   141  
   142  		createOpts := &directconnect.CreatePrivateVirtualInterfaceInput{
   143  			ConnectionId: aws.String(d.Get("connection_id").(string)),
   144  			NewPrivateVirtualInterface: &directconnect.NewPrivateVirtualInterface{
   145  				Asn:                  aws.Int64(int64(d.Get("asn").(int))),
   146  				VirtualGatewayId:     aws.String(d.Get("virtual_gateway_id").(string)),
   147  				VirtualInterfaceName: aws.String(d.Get("virtual_interface_name").(string)),
   148  				Vlan:                 aws.Int64(int64(d.Get("vlan").(int))),
   149  			},
   150  		}
   151  
   152  		if v, ok := d.GetOk("amazon_address"); ok {
   153  			createOpts.NewPrivateVirtualInterface.AmazonAddress = aws.String(v.(string))
   154  		}
   155  
   156  		if v, ok := d.GetOk("auth_key"); ok {
   157  			createOpts.NewPrivateVirtualInterface.AuthKey = aws.String(v.(string))
   158  		}
   159  
   160  		if v, ok := d.GetOk("customer_address"); ok {
   161  			createOpts.NewPrivateVirtualInterface.CustomerAddress = aws.String(v.(string))
   162  		}
   163  
   164  		log.Println("[DEBUG] request structure: ", createOpts)
   165  		// Create the DirectConnect Connection
   166  		log.Printf("[DEBUG] Creating DirectConnect private virtual interface")
   167  		resp, err = conn.CreatePrivateVirtualInterface(createOpts)
   168  		if err != nil {
   169  			return fmt.Errorf("Error creating DirectConnect connection: %s", err)
   170  		}
   171  
   172  	}
   173  
   174  	// Store the ID
   175  	VirtualInterface := resp
   176  	d.SetId(*VirtualInterface.VirtualInterfaceId)
   177  	log.Printf("[INFO] PrivateVirtualInterface ID: %s", *VirtualInterface.VirtualInterfaceId)
   178  
   179  	stateConf := &resource.StateChangeConf{
   180  		Pending:    []string{"pending", "down"},
   181  		Target:     []string{"available", "confirming", "verifying"},
   182  		Refresh:    DirectConnectVirtualInterfaceRefreshFunc(conn, *VirtualInterface.VirtualInterfaceId),
   183  		Timeout:    10 * time.Minute,
   184  		Delay:      10 * time.Second,
   185  		MinTimeout: 10 * time.Second,
   186  	}
   187  
   188  	_, stateErr := stateConf.WaitForState()
   189  	if stateErr != nil {
   190  		return fmt.Errorf(
   191  			"Error waiting for DirectConnect PrivateVirtualInterface (%s) to become ready: %s",
   192  			*VirtualInterface.VirtualInterfaceId, err)
   193  	}
   194  
   195  	// Read off the API to populate our RO fields.
   196  	return resourceAwsDirectConnectVirtualInterfaceRead(d, meta)
   197  }
   198  
   199  func DirectConnectVirtualInterfaceRefreshFunc(conn *directconnect.DirectConnect, virtualinterfaceId string) resource.StateRefreshFunc {
   200  	return func() (interface{}, string, error) {
   201  
   202  		resp, err := conn.DescribeVirtualInterfaces(&directconnect.DescribeVirtualInterfacesInput{
   203  			VirtualInterfaceId: aws.String(virtualinterfaceId),
   204  		})
   205  
   206  		if err != nil {
   207  
   208  			log.Printf("Error on DirectConnectPrivateVirtualInterfaceRefresh: %s", err)
   209  			return nil, "", err
   210  
   211  		}
   212  
   213  		if resp == nil || len(resp.VirtualInterfaces) == 0 {
   214  			return nil, "", nil
   215  		}
   216  
   217  		virtualInterface := resp.VirtualInterfaces[0]
   218  		return virtualInterface, *virtualInterface.VirtualInterfaceState, nil
   219  	}
   220  }
   221  
   222  func resourceAwsDirectConnectVirtualInterfaceRead(d *schema.ResourceData, meta interface{}) error {
   223  	conn := meta.(*AWSClient).dcconn
   224  
   225  	resp, err := conn.DescribeVirtualInterfaces(&directconnect.DescribeVirtualInterfacesInput{
   226  		VirtualInterfaceId: aws.String(d.Id()),
   227  	})
   228  
   229  	if err != nil {
   230  
   231  		log.Printf("[ERROR] Error finding DirectConnect VirtualInterface: %s", err)
   232  		return err
   233  
   234  	}
   235  
   236  	if len(resp.VirtualInterfaces) != 1 {
   237  		return fmt.Errorf("[ERROR] Error finding DirectConnect VirtualInterface: %s", d.Id())
   238  	}
   239  
   240  	virtualInterface := resp.VirtualInterfaces[0]
   241  
   242  	// Set attributes under the user's control.
   243  	d.Set("connection_id", *virtualInterface.ConnectionId)
   244  	d.Set("asn", *virtualInterface.Asn)
   245  	d.Set("virtual_interface_name", *virtualInterface.VirtualInterfaceName)
   246  
   247  	if v, ok := d.GetOk("interface_type"); !ok || (ok && v.(string) == "private") {
   248  		d.Set("virtual_gateway_id", *virtualInterface.VirtualGatewayId)
   249  	}
   250  
   251  	d.Set("vlan", *virtualInterface.Vlan)
   252  	d.Set("amazon_address", *virtualInterface.AmazonAddress)
   253  	d.Set("customer_address", *virtualInterface.CustomerAddress)
   254  
   255  	// Set read only attributes.
   256  	d.SetId(*virtualInterface.VirtualInterfaceId)
   257  
   258  	return nil
   259  }
   260  
   261  func resourceAwsDirectConnectVirtualInterfaceDelete(d *schema.ResourceData, meta interface{}) error {
   262  	conn := meta.(*AWSClient).dcconn
   263  
   264  	_, err := conn.DeleteVirtualInterface(&directconnect.DeleteVirtualInterfaceInput{
   265  		VirtualInterfaceId: aws.String(d.Id()),
   266  	})
   267  
   268  	if err != nil {
   269  
   270  		log.Printf("[ERROR] Error deleting DirectConnect VirtualInterface connection: %s", err)
   271  		return err
   272  
   273  	}
   274  
   275  	stateConf := &resource.StateChangeConf{
   276  		Pending:    []string{"deleting"},
   277  		Target:     []string{"deleted"},
   278  		Refresh:    DirectConnectVirtualInterfaceRefreshFunc(conn, d.Id()),
   279  		Timeout:    10 * time.Minute,
   280  		Delay:      10 * time.Second,
   281  		MinTimeout: 10 * time.Second,
   282  	}
   283  
   284  	_, stateErr := stateConf.WaitForState()
   285  	if stateErr != nil {
   286  		return fmt.Errorf(
   287  			"Error waiting for DirectConnect VirtualInterface (%s) to delete: %s", d.Id(), err)
   288  	}
   289  
   290  	return nil
   291  }