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 }