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 }