github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/aws/resource_aws_main_route_table_association.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 resourceAwsMainRouteTableAssociation() *schema.Resource {
    13  	return &schema.Resource{
    14  		Create: resourceAwsMainRouteTableAssociationCreate,
    15  		Read:   resourceAwsMainRouteTableAssociationRead,
    16  		Update: resourceAwsMainRouteTableAssociationUpdate,
    17  		Delete: resourceAwsMainRouteTableAssociationDelete,
    18  
    19  		Schema: map[string]*schema.Schema{
    20  			"vpc_id": &schema.Schema{
    21  				Type:     schema.TypeString,
    22  				Required: true,
    23  			},
    24  
    25  			"route_table_id": &schema.Schema{
    26  				Type:     schema.TypeString,
    27  				Required: true,
    28  			},
    29  
    30  			// We use this field to record the main route table that is automatically
    31  			// created when the VPC is created. We need this to be able to "destroy"
    32  			// our main route table association, which we do by returning this route
    33  			// table to its original place as the Main Route Table for the VPC.
    34  			"original_route_table_id": &schema.Schema{
    35  				Type:     schema.TypeString,
    36  				Computed: true,
    37  			},
    38  		},
    39  	}
    40  }
    41  
    42  func resourceAwsMainRouteTableAssociationCreate(d *schema.ResourceData, meta interface{}) error {
    43  	conn := meta.(*AWSClient).ec2conn
    44  	vpcId := d.Get("vpc_id").(string)
    45  	routeTableId := d.Get("route_table_id").(string)
    46  
    47  	log.Printf("[INFO] Creating main route table association: %s => %s", vpcId, routeTableId)
    48  
    49  	mainAssociation, err := findMainRouteTableAssociation(conn, vpcId)
    50  	if err != nil {
    51  		return err
    52  	}
    53  
    54  	resp, err := conn.ReplaceRouteTableAssociation(&ec2.ReplaceRouteTableAssociationInput{
    55  		AssociationId: mainAssociation.RouteTableAssociationId,
    56  		RouteTableId:  aws.String(routeTableId),
    57  	})
    58  	if err != nil {
    59  		return err
    60  	}
    61  
    62  	d.Set("original_route_table_id", mainAssociation.RouteTableId)
    63  	d.SetId(*resp.NewAssociationId)
    64  	log.Printf("[INFO] New main route table association ID: %s", d.Id())
    65  
    66  	return nil
    67  }
    68  
    69  func resourceAwsMainRouteTableAssociationRead(d *schema.ResourceData, meta interface{}) error {
    70  	conn := meta.(*AWSClient).ec2conn
    71  
    72  	mainAssociation, err := findMainRouteTableAssociation(
    73  		conn,
    74  		d.Get("vpc_id").(string))
    75  	if err != nil {
    76  		return err
    77  	}
    78  
    79  	if mainAssociation == nil || *mainAssociation.RouteTableAssociationId != d.Id() {
    80  		// It seems it doesn't exist anymore, so clear the ID
    81  		d.SetId("")
    82  	}
    83  
    84  	return nil
    85  }
    86  
    87  // Update is almost exactly like Create, except we want to retain the
    88  // original_route_table_id - this needs to stay recorded as the AWS-created
    89  // table from VPC creation.
    90  func resourceAwsMainRouteTableAssociationUpdate(d *schema.ResourceData, meta interface{}) error {
    91  	conn := meta.(*AWSClient).ec2conn
    92  	vpcId := d.Get("vpc_id").(string)
    93  	routeTableId := d.Get("route_table_id").(string)
    94  
    95  	log.Printf("[INFO] Updating main route table association: %s => %s", vpcId, routeTableId)
    96  
    97  	resp, err := conn.ReplaceRouteTableAssociation(&ec2.ReplaceRouteTableAssociationInput{
    98  		AssociationId: aws.String(d.Id()),
    99  		RouteTableId:  aws.String(routeTableId),
   100  	})
   101  	if err != nil {
   102  		return err
   103  	}
   104  
   105  	d.SetId(*resp.NewAssociationId)
   106  	log.Printf("[INFO] New main route table association ID: %s", d.Id())
   107  
   108  	return nil
   109  }
   110  
   111  func resourceAwsMainRouteTableAssociationDelete(d *schema.ResourceData, meta interface{}) error {
   112  	conn := meta.(*AWSClient).ec2conn
   113  	vpcId := d.Get("vpc_id").(string)
   114  	originalRouteTableId := d.Get("original_route_table_id").(string)
   115  
   116  	log.Printf("[INFO] Deleting main route table association by resetting Main Route Table for VPC: %s to its original Route Table: %s",
   117  		vpcId,
   118  		originalRouteTableId)
   119  
   120  	resp, err := conn.ReplaceRouteTableAssociation(&ec2.ReplaceRouteTableAssociationInput{
   121  		AssociationId: aws.String(d.Id()),
   122  		RouteTableId:  aws.String(originalRouteTableId),
   123  	})
   124  	if err != nil {
   125  		return err
   126  	}
   127  
   128  	log.Printf("[INFO] Resulting Association ID: %s", *resp.NewAssociationId)
   129  
   130  	return nil
   131  }
   132  
   133  func findMainRouteTableAssociation(conn *ec2.EC2, vpcId string) (*ec2.RouteTableAssociation, error) {
   134  	mainRouteTable, err := findMainRouteTable(conn, vpcId)
   135  	if err != nil {
   136  		return nil, err
   137  	}
   138  	if mainRouteTable == nil {
   139  		return nil, nil
   140  	}
   141  
   142  	for _, a := range mainRouteTable.Associations {
   143  		if *a.Main {
   144  			return a, nil
   145  		}
   146  	}
   147  	return nil, fmt.Errorf("Could not find main routing table association for VPC: %s", vpcId)
   148  }
   149  
   150  func findMainRouteTable(conn *ec2.EC2, vpcId string) (*ec2.RouteTable, error) {
   151  	mainFilter := &ec2.Filter{
   152  		Name:   aws.String("association.main"),
   153  		Values: []*string{aws.String("true")},
   154  	}
   155  	vpcFilter := &ec2.Filter{
   156  		Name:   aws.String("vpc-id"),
   157  		Values: []*string{aws.String(vpcId)},
   158  	}
   159  	routeResp, err := conn.DescribeRouteTables(&ec2.DescribeRouteTablesInput{
   160  		Filters: []*ec2.Filter{mainFilter, vpcFilter},
   161  	})
   162  	if err != nil {
   163  		return nil, err
   164  	} else if len(routeResp.RouteTables) != 1 {
   165  		return nil, nil
   166  	}
   167  
   168  	return routeResp.RouteTables[0], nil
   169  }