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