github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/aws/resource_aws_default_route_table.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/service/ec2"
     9  	"github.com/hashicorp/terraform/helper/schema"
    10  )
    11  
    12  func resourceAwsDefaultRouteTable() *schema.Resource {
    13  	return &schema.Resource{
    14  		Create: resourceAwsDefaultRouteTableCreate,
    15  		Read:   resourceAwsDefaultRouteTableRead,
    16  		Update: resourceAwsRouteTableUpdate,
    17  		Delete: resourceAwsDefaultRouteTableDelete,
    18  
    19  		Schema: map[string]*schema.Schema{
    20  			"default_route_table_id": &schema.Schema{
    21  				Type:     schema.TypeString,
    22  				Required: true,
    23  				ForceNew: true,
    24  			},
    25  
    26  			"vpc_id": &schema.Schema{
    27  				Type:     schema.TypeString,
    28  				Computed: true,
    29  			},
    30  
    31  			"propagating_vgws": &schema.Schema{
    32  				Type:     schema.TypeSet,
    33  				Optional: true,
    34  				Elem:     &schema.Schema{Type: schema.TypeString},
    35  				Set:      schema.HashString,
    36  			},
    37  
    38  			"route": &schema.Schema{
    39  				Type:     schema.TypeSet,
    40  				Computed: true,
    41  				Optional: true,
    42  				Elem: &schema.Resource{
    43  					Schema: map[string]*schema.Schema{
    44  						"cidr_block": &schema.Schema{
    45  							Type:     schema.TypeString,
    46  							Required: true,
    47  						},
    48  
    49  						"gateway_id": &schema.Schema{
    50  							Type:     schema.TypeString,
    51  							Optional: true,
    52  						},
    53  
    54  						"instance_id": &schema.Schema{
    55  							Type:     schema.TypeString,
    56  							Optional: true,
    57  						},
    58  
    59  						"nat_gateway_id": &schema.Schema{
    60  							Type:     schema.TypeString,
    61  							Optional: true,
    62  						},
    63  
    64  						"vpc_peering_connection_id": &schema.Schema{
    65  							Type:     schema.TypeString,
    66  							Optional: true,
    67  						},
    68  
    69  						"network_interface_id": &schema.Schema{
    70  							Type:     schema.TypeString,
    71  							Optional: true,
    72  						},
    73  					},
    74  				},
    75  				Set: resourceAwsRouteTableHash,
    76  			},
    77  
    78  			"tags": tagsSchema(),
    79  		},
    80  	}
    81  }
    82  
    83  func resourceAwsDefaultRouteTableCreate(d *schema.ResourceData, meta interface{}) error {
    84  	d.SetId(d.Get("default_route_table_id").(string))
    85  
    86  	conn := meta.(*AWSClient).ec2conn
    87  	rtRaw, _, err := resourceAwsRouteTableStateRefreshFunc(conn, d.Id())()
    88  	if err != nil {
    89  		return err
    90  	}
    91  	if rtRaw == nil {
    92  		log.Printf("[WARN] Default Route Table not found")
    93  		d.SetId("")
    94  		return nil
    95  	}
    96  
    97  	rt := rtRaw.(*ec2.RouteTable)
    98  
    99  	d.Set("vpc_id", rt.VpcId)
   100  
   101  	// revoke all default and pre-existing routes on the default route table.
   102  	// In the UPDATE method, we'll apply only the rules in the configuration.
   103  	log.Printf("[DEBUG] Revoking default routes for Default Route Table for %s", d.Id())
   104  	if err := revokeAllRouteTableRules(d.Id(), meta); err != nil {
   105  		return err
   106  	}
   107  
   108  	return resourceAwsRouteTableUpdate(d, meta)
   109  }
   110  
   111  func resourceAwsDefaultRouteTableRead(d *schema.ResourceData, meta interface{}) error {
   112  	conn := meta.(*AWSClient).ec2conn
   113  	// look up default route table for VPC
   114  	filter1 := &ec2.Filter{
   115  		Name:   aws.String("association.main"),
   116  		Values: []*string{aws.String("true")},
   117  	}
   118  	filter2 := &ec2.Filter{
   119  		Name:   aws.String("vpc-id"),
   120  		Values: []*string{aws.String(d.Get("vpc_id").(string))},
   121  	}
   122  
   123  	findOpts := &ec2.DescribeRouteTablesInput{
   124  		Filters: []*ec2.Filter{filter1, filter2},
   125  	}
   126  
   127  	resp, err := conn.DescribeRouteTables(findOpts)
   128  	if err != nil {
   129  		return err
   130  	}
   131  
   132  	if len(resp.RouteTables) < 1 || resp.RouteTables[0] == nil {
   133  		return fmt.Errorf("Default Route table not found")
   134  	}
   135  
   136  	rt := resp.RouteTables[0]
   137  
   138  	d.Set("default_route_table_id", rt.RouteTableId)
   139  	d.SetId(*rt.RouteTableId)
   140  
   141  	// re-use regular AWS Route Table READ. This is an extra API call but saves us
   142  	// from trying to manually keep parity
   143  	return resourceAwsRouteTableRead(d, meta)
   144  }
   145  
   146  func resourceAwsDefaultRouteTableDelete(d *schema.ResourceData, meta interface{}) error {
   147  	log.Printf("[WARN] Cannot destroy Default Route Table. Terraform will remove this resource from the state file, however resources may remain.")
   148  	d.SetId("")
   149  	return nil
   150  }
   151  
   152  // revokeAllRouteTableRules revoke all routes on the Default Route Table
   153  // This should only be ran once at creation time of this resource
   154  func revokeAllRouteTableRules(defaultRouteTableId string, meta interface{}) error {
   155  	conn := meta.(*AWSClient).ec2conn
   156  	log.Printf("\n***\nrevokeAllRouteTableRules\n***\n")
   157  
   158  	resp, err := conn.DescribeRouteTables(&ec2.DescribeRouteTablesInput{
   159  		RouteTableIds: []*string{aws.String(defaultRouteTableId)},
   160  	})
   161  	if err != nil {
   162  		return err
   163  	}
   164  
   165  	if len(resp.RouteTables) < 1 || resp.RouteTables[0] == nil {
   166  		return fmt.Errorf("Default Route table not found")
   167  	}
   168  
   169  	rt := resp.RouteTables[0]
   170  
   171  	// Remove all Gateway association
   172  	for _, r := range rt.PropagatingVgws {
   173  		log.Printf(
   174  			"[INFO] Deleting VGW propagation from %s: %s",
   175  			defaultRouteTableId, *r.GatewayId)
   176  		_, err := conn.DisableVgwRoutePropagation(&ec2.DisableVgwRoutePropagationInput{
   177  			RouteTableId: aws.String(defaultRouteTableId),
   178  			GatewayId:    r.GatewayId,
   179  		})
   180  		if err != nil {
   181  			return err
   182  		}
   183  	}
   184  
   185  	// Delete all routes
   186  	for _, r := range rt.Routes {
   187  		// you cannot delete the local route
   188  		if r.GatewayId != nil && *r.GatewayId == "local" {
   189  			continue
   190  		}
   191  		if r.DestinationPrefixListId != nil {
   192  			// Skipping because VPC endpoint routes are handled separately
   193  			// See aws_vpc_endpoint
   194  			continue
   195  		}
   196  		log.Printf(
   197  			"[INFO] Deleting route from %s: %s",
   198  			defaultRouteTableId, *r.DestinationCidrBlock)
   199  		_, err := conn.DeleteRoute(&ec2.DeleteRouteInput{
   200  			RouteTableId:         aws.String(defaultRouteTableId),
   201  			DestinationCidrBlock: r.DestinationCidrBlock,
   202  		})
   203  		if err != nil {
   204  			return err
   205  		}
   206  	}
   207  
   208  	return nil
   209  }