Merge pull request #3548 from MDL/aws_route
provider/aws: add aws_route resource (finish)
This commit is contained in:
commit
5c3c1e2327
|
@ -242,6 +242,7 @@ func Provider() terraform.ResourceProvider {
|
||||||
"aws_route53_zone_association": resourceAwsRoute53ZoneAssociation(),
|
"aws_route53_zone_association": resourceAwsRoute53ZoneAssociation(),
|
||||||
"aws_route53_zone": resourceAwsRoute53Zone(),
|
"aws_route53_zone": resourceAwsRoute53Zone(),
|
||||||
"aws_route53_health_check": resourceAwsRoute53HealthCheck(),
|
"aws_route53_health_check": resourceAwsRoute53HealthCheck(),
|
||||||
|
"aws_route": resourceAwsRoute(),
|
||||||
"aws_route_table": resourceAwsRouteTable(),
|
"aws_route_table": resourceAwsRouteTable(),
|
||||||
"aws_route_table_association": resourceAwsRouteTableAssociation(),
|
"aws_route_table_association": resourceAwsRouteTableAssociation(),
|
||||||
"aws_s3_bucket": resourceAwsS3Bucket(),
|
"aws_s3_bucket": resourceAwsS3Bucket(),
|
||||||
|
|
|
@ -0,0 +1,304 @@
|
||||||
|
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/hashcode"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AWS Route resource Schema declaration
|
||||||
|
func resourceAwsRoute() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceAwsRouteCreate,
|
||||||
|
Read: resourceAwsRouteRead,
|
||||||
|
Update: resourceAwsRouteUpdate,
|
||||||
|
Delete: resourceAwsRouteDelete,
|
||||||
|
Exists: resourceAwsRouteExists,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"destination_cidr_block": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"destination_prefix_list_id": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"gateway_id": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"instance_id": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"instance_owner_id": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"network_interface_id": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"origin": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"state": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"route_table_id": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"vpc_peering_connection_id": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsRouteCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).ec2conn
|
||||||
|
var numTargets int
|
||||||
|
var setTarget string
|
||||||
|
allowedTargets := []string{
|
||||||
|
"gateway_id",
|
||||||
|
"instance_id",
|
||||||
|
"network_interface_id",
|
||||||
|
"vpc_peering_connection_id",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if more than 1 target is specified
|
||||||
|
for _, target := range allowedTargets {
|
||||||
|
if len(d.Get(target).(string)) > 0 {
|
||||||
|
numTargets++
|
||||||
|
setTarget = target
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if numTargets > 1 {
|
||||||
|
fmt.Errorf("Error: more than 1 target specified. Only 1 of gateway_id" +
|
||||||
|
"instance_id, network_interface_id, route_table_id or" +
|
||||||
|
"vpc_peering_connection_id is allowed.")
|
||||||
|
}
|
||||||
|
|
||||||
|
createOpts := &ec2.CreateRouteInput{}
|
||||||
|
// Formulate CreateRouteInput based on the target type
|
||||||
|
switch setTarget {
|
||||||
|
case "gateway_id":
|
||||||
|
createOpts = &ec2.CreateRouteInput{
|
||||||
|
RouteTableId: aws.String(d.Get("route_table_id").(string)),
|
||||||
|
DestinationCidrBlock: aws.String(d.Get("destination_cidr_block").(string)),
|
||||||
|
GatewayId: aws.String(d.Get("gateway_id").(string)),
|
||||||
|
}
|
||||||
|
case "instance_id":
|
||||||
|
createOpts = &ec2.CreateRouteInput{
|
||||||
|
RouteTableId: aws.String(d.Get("route_table_id").(string)),
|
||||||
|
DestinationCidrBlock: aws.String(d.Get("destination_cidr_block").(string)),
|
||||||
|
InstanceId: aws.String(d.Get("instance_id").(string)),
|
||||||
|
}
|
||||||
|
case "network_interface_id":
|
||||||
|
createOpts = &ec2.CreateRouteInput{
|
||||||
|
RouteTableId: aws.String(d.Get("route_table_id").(string)),
|
||||||
|
DestinationCidrBlock: aws.String(d.Get("destination_cidr_block").(string)),
|
||||||
|
NetworkInterfaceId: aws.String(d.Get("network_interface_id").(string)),
|
||||||
|
}
|
||||||
|
case "vpc_peering_connection_id":
|
||||||
|
createOpts = &ec2.CreateRouteInput{
|
||||||
|
RouteTableId: aws.String(d.Get("route_table_id").(string)),
|
||||||
|
DestinationCidrBlock: aws.String(d.Get("destination_cidr_block").(string)),
|
||||||
|
VpcPeeringConnectionId: aws.String(d.Get("vpc_peering_connection_id").(string)),
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
fmt.Errorf("Error: invalid target type specified.")
|
||||||
|
}
|
||||||
|
log.Printf("[DEBUG] Route create config: %s", createOpts)
|
||||||
|
|
||||||
|
// Create the route
|
||||||
|
_, err := conn.CreateRoute(createOpts)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error creating route: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
route, err := findResourceRoute(conn, d.Get("route_table_id").(string), d.Get("destination_cidr_block").(string))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Errorf("Error: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(routeIDHash(d, route))
|
||||||
|
|
||||||
|
return resourceAwsRouteRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsRouteRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).ec2conn
|
||||||
|
route, err := findResourceRoute(conn, d.Get("route_table_id").(string), d.Get("destination_cidr_block").(string))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("destination_prefix_list_id", route.DestinationPrefixListId)
|
||||||
|
d.Set("gateway_id", route.GatewayId)
|
||||||
|
d.Set("instance_id", route.InstanceId)
|
||||||
|
d.Set("instance_owner_id", route.InstanceOwnerId)
|
||||||
|
d.Set("network_interface_id", route.NetworkInterfaceId)
|
||||||
|
d.Set("origin", route.Origin)
|
||||||
|
d.Set("state", route.State)
|
||||||
|
d.Set("vpc_peering_connection_id", route.VpcPeeringConnectionId)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsRouteUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).ec2conn
|
||||||
|
var numTargets int
|
||||||
|
var setTarget string
|
||||||
|
allowedTargets := []string{
|
||||||
|
"gateway_id",
|
||||||
|
"instance_id",
|
||||||
|
"network_interface_id",
|
||||||
|
"vpc_peering_connection_id",
|
||||||
|
}
|
||||||
|
replaceOpts := &ec2.ReplaceRouteInput{}
|
||||||
|
|
||||||
|
// Check if more than 1 target is specified
|
||||||
|
for _, target := range allowedTargets {
|
||||||
|
if len(d.Get(target).(string)) > 0 {
|
||||||
|
numTargets++
|
||||||
|
setTarget = target
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if numTargets > 1 {
|
||||||
|
fmt.Errorf("Error: more than 1 target specified. Only 1 of gateway_id" +
|
||||||
|
"instance_id, network_interface_id, route_table_id or" +
|
||||||
|
"vpc_peering_connection_id is allowed.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Formulate ReplaceRouteInput based on the target type
|
||||||
|
switch setTarget {
|
||||||
|
case "gateway_id":
|
||||||
|
replaceOpts = &ec2.ReplaceRouteInput{
|
||||||
|
RouteTableId: aws.String(d.Get("route_table_id").(string)),
|
||||||
|
DestinationCidrBlock: aws.String(d.Get("destination_cidr_block").(string)),
|
||||||
|
GatewayId: aws.String(d.Get("gateway_id").(string)),
|
||||||
|
}
|
||||||
|
case "instance_id":
|
||||||
|
replaceOpts = &ec2.ReplaceRouteInput{
|
||||||
|
RouteTableId: aws.String(d.Get("route_table_id").(string)),
|
||||||
|
DestinationCidrBlock: aws.String(d.Get("destination_cidr_block").(string)),
|
||||||
|
InstanceId: aws.String(d.Get("instance_id").(string)),
|
||||||
|
//NOOP: Ensure we don't blow away network interface id that is set after instance is launched
|
||||||
|
NetworkInterfaceId: aws.String(d.Get("network_interface_id").(string)),
|
||||||
|
}
|
||||||
|
case "network_interface_id":
|
||||||
|
replaceOpts = &ec2.ReplaceRouteInput{
|
||||||
|
RouteTableId: aws.String(d.Get("route_table_id").(string)),
|
||||||
|
DestinationCidrBlock: aws.String(d.Get("destination_cidr_block").(string)),
|
||||||
|
NetworkInterfaceId: aws.String(d.Get("network_interface_id").(string)),
|
||||||
|
}
|
||||||
|
case "vpc_peering_connection_id":
|
||||||
|
replaceOpts = &ec2.ReplaceRouteInput{
|
||||||
|
RouteTableId: aws.String(d.Get("route_table_id").(string)),
|
||||||
|
DestinationCidrBlock: aws.String(d.Get("destination_cidr_block").(string)),
|
||||||
|
VpcPeeringConnectionId: aws.String(d.Get("vpc_peering_connection_id").(string)),
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
fmt.Errorf("Error: invalid target type specified.")
|
||||||
|
}
|
||||||
|
log.Printf("[DEBUG] Route replace config: %s", replaceOpts)
|
||||||
|
|
||||||
|
// Replace the route
|
||||||
|
_, err := conn.ReplaceRoute(replaceOpts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsRouteDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).ec2conn
|
||||||
|
|
||||||
|
deleteOpts := &ec2.DeleteRouteInput{
|
||||||
|
RouteTableId: aws.String(d.Get("route_table_id").(string)),
|
||||||
|
DestinationCidrBlock: aws.String(d.Get("destination_cidr_block").(string)),
|
||||||
|
}
|
||||||
|
log.Printf("[DEBUG] Route delete opts: %s", deleteOpts)
|
||||||
|
|
||||||
|
resp, err := conn.DeleteRoute(deleteOpts)
|
||||||
|
log.Printf("[DEBUG] Route delete result: %s", resp)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsRouteExists(d *schema.ResourceData, meta interface{}) (bool, error) {
|
||||||
|
conn := meta.(*AWSClient).ec2conn
|
||||||
|
routeTableId := d.Get("route_table_id").(string)
|
||||||
|
|
||||||
|
findOpts := &ec2.DescribeRouteTablesInput{
|
||||||
|
RouteTableIds: []*string{&routeTableId},
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := conn.DescribeRouteTables(findOpts)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cidr := d.Get("destination_cidr_block").(string)
|
||||||
|
for _, route := range (*res.RouteTables[0]).Routes {
|
||||||
|
if *route.DestinationCidrBlock == cidr {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create an ID for a route
|
||||||
|
func routeIDHash(d *schema.ResourceData, r *ec2.Route) string {
|
||||||
|
return fmt.Sprintf("r-%s%d", d.Get("route_table_id").(string), hashcode.String(*r.DestinationCidrBlock))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper: retrieve a route
|
||||||
|
func findResourceRoute(conn *ec2.EC2, rtbid string, cidr string) (*ec2.Route, error) {
|
||||||
|
routeTableID := rtbid
|
||||||
|
|
||||||
|
findOpts := &ec2.DescribeRouteTablesInput{
|
||||||
|
RouteTableIds: []*string{&routeTableID},
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := conn.DescribeRouteTables(findOpts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, route := range (*resp.RouteTables[0]).Routes {
|
||||||
|
if *route.DestinationCidrBlock == cidr {
|
||||||
|
return route, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
|
@ -41,6 +41,7 @@ func resourceAwsRouteTable() *schema.Resource {
|
||||||
|
|
||||||
"route": &schema.Schema{
|
"route": &schema.Schema{
|
||||||
Type: schema.TypeSet,
|
Type: schema.TypeSet,
|
||||||
|
Computed: true,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Elem: &schema.Resource{
|
Elem: &schema.Resource{
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
|
|
|
@ -0,0 +1,298 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/service/ec2"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccAWSRoute_basic(t *testing.T) {
|
||||||
|
var route ec2.Route
|
||||||
|
|
||||||
|
//aws creates a default route
|
||||||
|
testCheck := func(s *terraform.State) error {
|
||||||
|
if *route.DestinationCidrBlock != "10.3.0.0/16" {
|
||||||
|
return fmt.Errorf("Destination Cidr (Expected=%s, Actual=%s)\n", "10.3.0.0/16", *route.DestinationCidrBlock)
|
||||||
|
}
|
||||||
|
|
||||||
|
name := "aws_internet_gateway.foo"
|
||||||
|
gwres, ok := s.RootModule().Resources[name]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not found: %s\n", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if *route.GatewayId != gwres.Primary.ID {
|
||||||
|
return fmt.Errorf("Internet Gateway Id (Expected=%s, Actual=%s)\n", gwres.Primary.ID, *route.GatewayId)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSRouteDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccAWSRouteBasicConfig,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSRouteExists("aws_route.bar", &route),
|
||||||
|
testCheck,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccAWSRoute_changeCidr(t *testing.T) {
|
||||||
|
var route ec2.Route
|
||||||
|
var routeTable ec2.RouteTable
|
||||||
|
|
||||||
|
//aws creates a default route
|
||||||
|
testCheck := func(s *terraform.State) error {
|
||||||
|
if *route.DestinationCidrBlock != "10.3.0.0/16" {
|
||||||
|
return fmt.Errorf("Destination Cidr (Expected=%s, Actual=%s)\n", "10.3.0.0/16", *route.DestinationCidrBlock)
|
||||||
|
}
|
||||||
|
|
||||||
|
name := "aws_internet_gateway.foo"
|
||||||
|
gwres, ok := s.RootModule().Resources[name]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not found: %s\n", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if *route.GatewayId != gwres.Primary.ID {
|
||||||
|
return fmt.Errorf("Internet Gateway Id (Expected=%s, Actual=%s)\n", gwres.Primary.ID, *route.GatewayId)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
testCheckChange := func(s *terraform.State) error {
|
||||||
|
if *route.DestinationCidrBlock != "10.2.0.0/16" {
|
||||||
|
return fmt.Errorf("Destination Cidr (Expected=%s, Actual=%s)\n", "10.2.0.0/16", *route.DestinationCidrBlock)
|
||||||
|
}
|
||||||
|
|
||||||
|
name := "aws_internet_gateway.foo"
|
||||||
|
gwres, ok := s.RootModule().Resources[name]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not found: %s\n", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if *route.GatewayId != gwres.Primary.ID {
|
||||||
|
return fmt.Errorf("Internet Gateway Id (Expected=%s, Actual=%s)\n", gwres.Primary.ID, *route.GatewayId)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rtlen := len(routeTable.Routes); rtlen != 2 {
|
||||||
|
return fmt.Errorf("Route Table has too many routes (Expected=%d, Actual=%d)\n", rtlen, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSRouteDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccAWSRouteBasicConfig,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSRouteExists("aws_route.bar", &route),
|
||||||
|
testCheck,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccAWSRouteBasicConfigChangeCidr,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSRouteExists("aws_route.bar", &route),
|
||||||
|
testAccCheckRouteTableExists("aws_route_table.foo", &routeTable),
|
||||||
|
testCheckChange,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Acceptance test if mixed inline and external routes are implemented
|
||||||
|
/*
|
||||||
|
func TestAccAWSRoute_mix(t *testing.T) {
|
||||||
|
var rt ec2.RouteTable
|
||||||
|
var route ec2.Route
|
||||||
|
|
||||||
|
//aws creates a default route
|
||||||
|
testCheck := func(s *terraform.State) error {
|
||||||
|
if *route.DestinationCidrBlock != "0.0.0.0/0" {
|
||||||
|
return fmt.Errorf("Destination Cidr (Expected=%s, Actual=%s)\n", "0.0.0.0/0", *route.DestinationCidrBlock)
|
||||||
|
}
|
||||||
|
|
||||||
|
name := "aws_internet_gateway.foo"
|
||||||
|
gwres, ok := s.RootModule().Resources[name]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not found: %s\n", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if *route.GatewayId != gwres.Primary.ID {
|
||||||
|
return fmt.Errorf("Internet Gateway Id (Expected=%s, Actual=%s)\n", gwres.Primary.ID, *route.GatewayId)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(rt.Routes) != 3 {
|
||||||
|
return fmt.Errorf("bad routes: %#v", rt.Routes)
|
||||||
|
}
|
||||||
|
|
||||||
|
routes := make(map[string]*ec2.Route)
|
||||||
|
for _, r := range rt.Routes {
|
||||||
|
routes[*r.DestinationCidrBlock] = r
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := routes["10.1.0.0/16"]; !ok {
|
||||||
|
return fmt.Errorf("Missing route %s: %#v", "10.1.0.0/16", rt.Routes)
|
||||||
|
}
|
||||||
|
if _, ok := routes["10.2.0.0/16"]; !ok {
|
||||||
|
return fmt.Errorf("Missing route %s: %#v", "10.2.0.0/16", rt.Routes)
|
||||||
|
}
|
||||||
|
if _, ok := routes["0.0.0.0/0"]; !ok {
|
||||||
|
return fmt.Errorf("Missing route %s: %#v", "0.0.0.0/0", rt.Routes)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSRouteDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccAWSRouteMixConfig,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckRouteTableExists("aws_route_table.foo", &rt),
|
||||||
|
testAccCheckAWSRouteExists("aws_route.bar", &route),
|
||||||
|
testCheck,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
func testAccCheckAWSRouteExists(n string, res *ec2.Route) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not found: %s\n", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("No ID is set")
|
||||||
|
}
|
||||||
|
|
||||||
|
conn := testAccProvider.Meta().(*AWSClient).ec2conn
|
||||||
|
r, err := findResourceRoute(
|
||||||
|
conn,
|
||||||
|
rs.Primary.Attributes["route_table_id"],
|
||||||
|
rs.Primary.Attributes["destination_cidr_block"],
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if r == nil {
|
||||||
|
return fmt.Errorf("Route not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
*res = *r
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckAWSRouteDestroy(s *terraform.State) error {
|
||||||
|
for _, rs := range s.RootModule().Resources {
|
||||||
|
if rs.Type != "aws_route" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
conn := testAccProvider.Meta().(*AWSClient).ec2conn
|
||||||
|
route, err := findResourceRoute(
|
||||||
|
conn,
|
||||||
|
rs.Primary.Attributes["route_table_id"],
|
||||||
|
rs.Primary.Attributes["destination_cidr_block"],
|
||||||
|
)
|
||||||
|
|
||||||
|
if route == nil && err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var testAccAWSRouteBasicConfig = fmt.Sprint(`
|
||||||
|
resource "aws_vpc" "foo" {
|
||||||
|
cidr_block = "10.1.0.0/16"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_internet_gateway" "foo" {
|
||||||
|
vpc_id = "${aws_vpc.foo.id}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_route_table" "foo" {
|
||||||
|
vpc_id = "${aws_vpc.foo.id}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_route" "bar" {
|
||||||
|
route_table_id = "${aws_route_table.foo.id}"
|
||||||
|
destination_cidr_block = "10.3.0.0/16"
|
||||||
|
gateway_id = "${aws_internet_gateway.foo.id}"
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
|
var testAccAWSRouteBasicConfigChangeCidr = fmt.Sprint(`
|
||||||
|
resource "aws_vpc" "foo" {
|
||||||
|
cidr_block = "10.1.0.0/16"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_internet_gateway" "foo" {
|
||||||
|
vpc_id = "${aws_vpc.foo.id}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_route_table" "foo" {
|
||||||
|
vpc_id = "${aws_vpc.foo.id}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_route" "bar" {
|
||||||
|
route_table_id = "${aws_route_table.foo.id}"
|
||||||
|
destination_cidr_block = "10.2.0.0/16"
|
||||||
|
gateway_id = "${aws_internet_gateway.foo.id}"
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
|
// Acceptance test if mixed inline and external routes are implemented
|
||||||
|
var testAccAWSRouteMixConfig = fmt.Sprint(`
|
||||||
|
resource "aws_vpc" "foo" {
|
||||||
|
cidr_block = "10.1.0.0/16"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_internet_gateway" "foo" {
|
||||||
|
vpc_id = "${aws_vpc.foo.id}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_route_table" "foo" {
|
||||||
|
vpc_id = "${aws_vpc.foo.id}"
|
||||||
|
|
||||||
|
route {
|
||||||
|
cidr_block = "10.2.0.0/16"
|
||||||
|
gateway_id = "${aws_internet_gateway.foo.id}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_route" "bar" {
|
||||||
|
route_table_id = "${aws_route_table.foo.id}"
|
||||||
|
destination_cidr_block = "0.0.0.0/0"
|
||||||
|
gateway_id = "${aws_internet_gateway.foo.id}"
|
||||||
|
}
|
||||||
|
`)
|
|
@ -0,0 +1,57 @@
|
||||||
|
---
|
||||||
|
layout: "aws"
|
||||||
|
page_title: "AWS: aws_route"
|
||||||
|
sidebar_current: "docs-aws-resource-route|"
|
||||||
|
description: |-
|
||||||
|
Provides a resource to create a routing entry in a VPC routing table.
|
||||||
|
---
|
||||||
|
|
||||||
|
# aws\_route
|
||||||
|
|
||||||
|
Provides a resource to create a routing table entry (a route) in a VPC routing table.
|
||||||
|
|
||||||
|
~> **NOTE on Route Tables and Routes:** Terraform currently
|
||||||
|
provides both a standalone [Route resource](route.html) and a Route Table resource with routes
|
||||||
|
defined in-line. At this time you cannot use a Route Table with in-line routes
|
||||||
|
in conjunction with any Route resources. Doing so will cause
|
||||||
|
a conflict of rule settings and will overwrite rules.
|
||||||
|
|
||||||
|
## Example usage:
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "aws_route" "r" {
|
||||||
|
route_table_id = "rtb-4fbb3ac4"
|
||||||
|
destination_cidr_block = "10.0.1.0/22"
|
||||||
|
vpc_peering_connection_id = "pcx-45ff3dc1"
|
||||||
|
depends_on = ["aws_route_table.testing"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `route_table_id` - (Required) The ID of the routing table.
|
||||||
|
* `destination_cidr_block` - (Required) The destination CIDR block.
|
||||||
|
* `vpc_peering_connection_id` - (Optional) An ID of a VPC peering connection.
|
||||||
|
* `gateway_id` - (Optional) An ID of a VPC internet gateway or a virtual private gateway.
|
||||||
|
* `instance_id` - (Optional) An ID of a NAT instance.
|
||||||
|
* `network_interface_id` - (Optional) An ID of a network interface.
|
||||||
|
|
||||||
|
Each route must contain either a `gateway_id`, an `instance_id` or a `vpc_peering_connection_id`
|
||||||
|
or a `network_interface_id`. Note that the default route, mapping the VPC's CIDR block to "local",
|
||||||
|
is created implicitly and cannot be specified.
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
The following attributes are exported:
|
||||||
|
|
||||||
|
~> **NOTE:** Only the target type that is specified (one of the above)
|
||||||
|
will be exported as an attribute once the resource is created.
|
||||||
|
|
||||||
|
* `route_table_id` - The ID of the routing table.
|
||||||
|
* `destination_cidr_block` - The destination CIDR block.
|
||||||
|
* `vpc_peering_connection_id` - An ID of a VPC peering connection.
|
||||||
|
* `gateway_id` - An ID of a VPC internet gateway or a virtual private gateway.
|
||||||
|
* `instance_id` - An ID of a NAT instance.
|
||||||
|
* `network_interface_id` - An ID of a network interface.
|
|
@ -10,6 +10,12 @@ description: |-
|
||||||
|
|
||||||
Provides a resource to create a VPC routing table.
|
Provides a resource to create a VPC routing table.
|
||||||
|
|
||||||
|
~> **NOTE on Route Tables and Routes:** Terraform currently
|
||||||
|
provides both a standalone [Route resource](route.html) and a Route Table resource with routes
|
||||||
|
defined in-line. At this time you cannot use a Route Table with in-line routes
|
||||||
|
in conjunction with any Route resources. Doing so will cause
|
||||||
|
a conflict of rule settings and will overwrite rules.
|
||||||
|
|
||||||
## Example usage with tags:
|
## Example usage with tags:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -50,5 +56,7 @@ is created implicitly and cannot be specified.
|
||||||
## Attributes Reference
|
## Attributes Reference
|
||||||
|
|
||||||
The following attributes are exported:
|
The following attributes are exported:
|
||||||
|
~> **NOTE:** Only the target that is entered is exported as a readable
|
||||||
|
attribute once the route resource is created.
|
||||||
|
|
||||||
* `id` - The ID of the routing table
|
* `id` - The ID of the routing table
|
||||||
|
|
|
@ -433,6 +433,10 @@
|
||||||
<a href="/docs/providers/aws/r/route53_zone_association.html">aws_route53_zone_association</a>
|
<a href="/docs/providers/aws/r/route53_zone_association.html">aws_route53_zone_association</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current("docs-aws-resource-route|") %>>
|
||||||
|
<a href="/docs/providers/aws/r/route.html">aws_route</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue