205 lines
5.2 KiB
Go
205 lines
5.2 KiB
Go
|
package aws
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"log"
|
||
|
|
||
|
"github.com/aws/aws-sdk-go/aws"
|
||
|
"github.com/aws/aws-sdk-go/service/ec2"
|
||
|
"github.com/hashicorp/terraform/helper/schema"
|
||
|
)
|
||
|
|
||
|
func resourceAwsDefaultRouteTable() *schema.Resource {
|
||
|
return &schema.Resource{
|
||
|
Create: resourceAwsDefaultRouteTableCreate,
|
||
|
Read: resourceAwsDefaultRouteTableRead,
|
||
|
Update: resourceAwsRouteTableUpdate,
|
||
|
Delete: resourceAwsDefaultRouteTableDelete,
|
||
|
|
||
|
Schema: map[string]*schema.Schema{
|
||
|
"default_route_table_id": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Required: true,
|
||
|
ForceNew: true,
|
||
|
},
|
||
|
|
||
|
"vpc_id": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Computed: true,
|
||
|
},
|
||
|
|
||
|
"propagating_vgws": &schema.Schema{
|
||
|
Type: schema.TypeSet,
|
||
|
Optional: true,
|
||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||
|
Set: schema.HashString,
|
||
|
},
|
||
|
|
||
|
"route": &schema.Schema{
|
||
|
Type: schema.TypeSet,
|
||
|
Computed: true,
|
||
|
Optional: true,
|
||
|
Elem: &schema.Resource{
|
||
|
Schema: map[string]*schema.Schema{
|
||
|
"cidr_block": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Required: true,
|
||
|
},
|
||
|
|
||
|
"gateway_id": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
},
|
||
|
|
||
|
"instance_id": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
},
|
||
|
|
||
|
"nat_gateway_id": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
},
|
||
|
|
||
|
"vpc_peering_connection_id": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
},
|
||
|
|
||
|
"network_interface_id": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Optional: true,
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
Set: resourceAwsRouteTableHash,
|
||
|
},
|
||
|
|
||
|
"tags": tagsSchema(),
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func resourceAwsDefaultRouteTableCreate(d *schema.ResourceData, meta interface{}) error {
|
||
|
d.SetId(d.Get("default_route_table_id").(string))
|
||
|
|
||
|
conn := meta.(*AWSClient).ec2conn
|
||
|
rtRaw, _, err := resourceAwsRouteTableStateRefreshFunc(conn, d.Id())()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
if rtRaw == nil {
|
||
|
log.Printf("[WARN] Default Route Table not found")
|
||
|
d.SetId("")
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
rt := rtRaw.(*ec2.RouteTable)
|
||
|
|
||
|
d.Set("vpc_id", rt.VpcId)
|
||
|
|
||
|
// revoke all default and pre-existing routes on the default route table.
|
||
|
// In the UPDATE method, we'll apply only the rules in the configuration.
|
||
|
log.Printf("[DEBUG] Revoking default routes for Default Route Table for %s", d.Id())
|
||
|
if err := revokeAllRouteTableRules(d.Id(), meta); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return resourceAwsRouteTableUpdate(d, meta)
|
||
|
}
|
||
|
|
||
|
func resourceAwsDefaultRouteTableRead(d *schema.ResourceData, meta interface{}) error {
|
||
|
conn := meta.(*AWSClient).ec2conn
|
||
|
// look up default route table for VPC
|
||
|
filter1 := &ec2.Filter{
|
||
|
Name: aws.String("association.main"),
|
||
|
Values: []*string{aws.String("true")},
|
||
|
}
|
||
|
filter2 := &ec2.Filter{
|
||
|
Name: aws.String("vpc-id"),
|
||
|
Values: []*string{aws.String(d.Get("vpc_id").(string))},
|
||
|
}
|
||
|
|
||
|
findOpts := &ec2.DescribeRouteTablesInput{
|
||
|
Filters: []*ec2.Filter{filter1, filter2},
|
||
|
}
|
||
|
|
||
|
resp, err := conn.DescribeRouteTables(findOpts)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
if len(resp.RouteTables) < 1 || resp.RouteTables[0] == nil {
|
||
|
return fmt.Errorf("Default Route table not found")
|
||
|
}
|
||
|
|
||
|
rt := resp.RouteTables[0]
|
||
|
|
||
|
d.Set("default_route_table_id", rt.RouteTableId)
|
||
|
d.SetId(*rt.RouteTableId)
|
||
|
|
||
|
// re-use regular AWS Route Table READ. This is an extra API call but saves us
|
||
|
// from trying to manually keep parity
|
||
|
return resourceAwsRouteTableRead(d, meta)
|
||
|
}
|
||
|
|
||
|
func resourceAwsDefaultRouteTableDelete(d *schema.ResourceData, meta interface{}) error {
|
||
|
log.Printf("[WARN] Cannot destroy Default Route Table. Terraform will remove this resource from the state file, however resources may remain.")
|
||
|
d.SetId("")
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// revokeAllRouteTableRules revoke all routes on the Default Route Table
|
||
|
// This should only be ran once at creation time of this resource
|
||
|
func revokeAllRouteTableRules(defaultRouteTableId string, meta interface{}) error {
|
||
|
conn := meta.(*AWSClient).ec2conn
|
||
|
log.Printf("\n***\nrevokeAllRouteTableRules\n***\n")
|
||
|
|
||
|
resp, err := conn.DescribeRouteTables(&ec2.DescribeRouteTablesInput{
|
||
|
RouteTableIds: []*string{aws.String(defaultRouteTableId)},
|
||
|
})
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
if len(resp.RouteTables) < 1 || resp.RouteTables[0] == nil {
|
||
|
return fmt.Errorf("Default Route table not found")
|
||
|
}
|
||
|
|
||
|
rt := resp.RouteTables[0]
|
||
|
|
||
|
// Remove all Gateway association
|
||
|
for _, r := range rt.PropagatingVgws {
|
||
|
log.Printf(
|
||
|
"[INFO] Deleting VGW propagation from %s: %s",
|
||
|
defaultRouteTableId, *r.GatewayId)
|
||
|
_, err := conn.DisableVgwRoutePropagation(&ec2.DisableVgwRoutePropagationInput{
|
||
|
RouteTableId: aws.String(defaultRouteTableId),
|
||
|
GatewayId: r.GatewayId,
|
||
|
})
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Delete all routes
|
||
|
for _, r := range rt.Routes {
|
||
|
// you cannot delete the local route
|
||
|
if r.GatewayId != nil && *r.GatewayId == "local" {
|
||
|
continue
|
||
|
}
|
||
|
log.Printf(
|
||
|
"[INFO] Deleting route from %s: %s",
|
||
|
defaultRouteTableId, *r.DestinationCidrBlock)
|
||
|
_, err := conn.DeleteRoute(&ec2.DeleteRouteInput{
|
||
|
RouteTableId: aws.String(defaultRouteTableId),
|
||
|
DestinationCidrBlock: r.DestinationCidrBlock,
|
||
|
})
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|