Now when we have created IGW and NAT GW on previous post it’s time to create route tables which will send traffic outside from your VCN to the destination you require. It can be for example to your on-premise network (via DRG) or to object storage (via Service GW). Or it can be towards public internet like in this example.

You can always create multiple rules per route table.

Since we have the existing IGW and NAT GW what we will now do is create two new route tables. One which will be assigned to our public subnet and another one which will be assigned to our private subnet. During creation we will link them with our IGW and NAT GW.

One important concept to remember with OCI is that the traffic inside your VCN CIDR block gets routed without adding VCN CIDR to a route table.

When we create route table we need to define a name then assign compartment and a VCN where it gets created.

In addition we define destination which is IP range of routed traffic or CIDR block value for a service when routed through service gateway. Finally you need to have network entity id which is OCID of the target we are using for the route.

You can read more about route tables from here.

Terraform

Once again we continue adding these to our existing main.tf and variables.tf.

Following lines get added to main.tf

//Create two route tables - one public which has route to internet gateway and another one for private with a route to NAT GW

resource "oci_core_route_table" "CreatePublicRouteTable" {
  compartment_id = "${oci_identity_compartment.CreateCompartment.id}"

  route_rules = [{
    destination       = "${var.igw_route_cidr_block}"
    network_entity_id = "${oci_core_internet_gateway.CreateIGW.id}"
  }]

  vcn_id       = "${oci_core_virtual_network.CreateVCN.id}"
  display_name = "${var.public_route_table_display_name}"
}

resource "oci_core_route_table" "CreatePrivateRouteTable" {
  compartment_id = "${oci_identity_compartment.CreateCompartment.id}"

  route_rules = [{
    destination       = "${var.natgw_route_cidr_block}"
    network_entity_id = "${oci_core_nat_gateway.CreateNatGateway.id}"
  }]

  vcn_id       = "${oci_core_virtual_network.CreateVCN.id}"
  display_name = "${var.private_route_table_display_name}"
}

Highlighted the previously created IGW and NAT GW usage on creating route table.

And in the variables.tf just name and cidr_block for destination.

// PUBLIC AND PRIVATE ROUTETABLE VARIABLES

variable "public_route_table_display_name" {
  default = "PublicRoute"
} // Name for the public routetable

variable "private_route_table_display_name" {
  default = "PrivateRoute"
} // Name for the private routetable

variable "igw_route_cidr_block" {
  default = "0.0.0.0/0"
} 

variable "natgw_route_cidr_block" {
  default = "0.0.0.0/0"
} 

After running terraform plan I see two new resources are getting created and I’m ready to run terraform apply.

PS C:\builddemo> terraform.exe apply
oci_identity_compartment.CreateCompartment: Refreshing state... (ID: ocid1.compartment.oc1..aaaaaaaav43jwd5o...xxxxx)
data.oci_identity_availability_domains.ADs: Refreshing state...
oci_core_virtual_network.CreateVCN: Refreshing state... (ID: ocid1.vcn.oc1.eu-frankfurt-1.aaaaaaaar2...xxxxx)
oci_core_internet_gateway.CreateIGW: Refreshing state... (ID: ocid1.internetgateway.oc1.eu-frankfurt-...xxxxx)
oci_core_nat_gateway.CreateNatGateway: Refreshing state... (ID: ocid1.natgateway.oc1.eu-frankfurt-1.aaa...xxxxx)

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  + oci_core_route_table.CreatePrivateRouteTable
      id:                                       <computed>
      compartment_id:                           "ocid1.compartment.oc1..xxxxx"
      display_name:                             "PrivateRoute"
      freeform_tags.%:                          <computed>
      route_rules.#:                            "1"
      route_rules.2309354893.cidr_block:        <computed>
      route_rules.2309354893.destination:       "0.0.0.0/0"
      route_rules.2309354893.destination_type:  <computed>
      route_rules.2309354893.network_entity_id: "ocid1.natgateway.oc1.eu-frankfurt-1.xxxxx"
      state:                                    <computed>
      time_created:                             <computed>
      time_modified:                            <computed>
      vcn_id:                                   "ocid1.vcn.oc1.eu-frankfurt-1.xxxxx"

  + oci_core_route_table.CreatePublicRouteTable
      id:                                       <computed>
      compartment_id:                           "ocid1.compartment.oc1..xxxxx"
      display_name:                             "PublicRoute"
      freeform_tags.%:                          <computed>
      route_rules.#:                            "1"
      route_rules.2660137267.cidr_block:        <computed>
      route_rules.2660137267.destination:       "0.0.0.0/0"
      route_rules.2660137267.destination_type:  <computed>
      route_rules.2660137267.network_entity_id: "ocid1.internetgateway.oc1.eu-frankfurt-1.xxxxx"
      state:                                    <computed>
      time_created:                             <computed>
      time_modified:                            <computed>
      vcn_id:                                   "ocid1.vcn.oc1.eu-frankfurt-1.xxxxx"


Plan: 2 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

oci_core_route_table.CreatePrivateRouteTable: Creating...
  compartment_id:                           "" => "ocid1.compartment.oc1..xxxxx"
  display_name:                             "" => "PrivateRoute"
  freeform_tags.%:                          "" => "<computed>"
  route_rules.#:                            "" => "1"
  route_rules.2309354893.cidr_block:        "" => "<computed>"
  route_rules.2309354893.destination:       "" => "0.0.0.0/0"
  route_rules.2309354893.destination_type:  "" => "<computed>"
  route_rules.2309354893.network_entity_id: "" => "ocid1.natgateway.oc1.eu-frankfurt-1.xxxxx"
  state:                                    "" => "<computed>"
  time_created:                             "" => "<computed>"
  time_modified:                            "" => "<computed>"
  vcn_id:                                   "" => "ocid1.vcn.oc1.eu-frankfurt-1.xxxxx"
oci_core_route_table.CreatePublicRouteTable: Creating...
  compartment_id:                           "" => "ocid1.compartment.oc1..xxxxx"
  display_name:                             "" => "PublicRoute"
  freeform_tags.%:                          "" => "<computed>"
  route_rules.#:                            "" => "1"
  route_rules.2660137267.cidr_block:        "" => "<computed>"
  route_rules.2660137267.destination:       "" => "0.0.0.0/0"
  route_rules.2660137267.destination_type:  "" => "<computed>"
  route_rules.2660137267.network_entity_id: "" => "ocid1.internetgateway.oc1.eu-frankfurt-1.xxxxx"
  state:                                    "" => "<computed>"
  time_created:                             "" => "<computed>"
  time_modified:                            "" => "<computed>"
  vcn_id:                                   "" => "ocid1.vcn.oc1.eu-frankfurt-1.xxxxx"
oci_core_route_table.CreatePublicRouteTable: Creation complete after 1s (ID: ocid1.routetable.oc1.eu-frankfurt-1.aaa...xxxxx)
oci_core_route_table.CreatePrivateRouteTable: Creation complete after 1s (ID: ocid1.routetable.oc1.eu-frankfurt-1.aaa...xxxxx)

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Just as an example in case you would need to add DRG to route traffic to on-premise and still keep the NAT GW then the route rules must be passed as a list.

        route_rules = [{
                destination = "${var.drg_route_table_route_rules_cidr_block}"
                network_entity_id = "${var.drg_network_id}"
        }, {
           destination = "${var.natgw_route_table_route_rules_cidr_block}"
                network_entity_id = "${var.natgw_network_id}"
        }]

See the highlighted parts so list is defined with [] and values separated with a comma.

Next part will jump into security lists which are created to allow certain ingress and egress traffic to our subnets.

2 thoughts on “Series – Get your database running with Terraform part 5: Route Tables”

  1. Hi- Thanks so much for putting these examples together. This has become my starting point of exploring Terraform on OCI.

    Quick input on this, while testing this, released we don’t need “=” sine in main.tf for route_rules

    route_rules = [{

    It should be just
    route_rules {

    1. Thanks Deepak! Did you test this with Terraform 0.12? I think it changed with between 0.11 and 0.12 so you don’t need = sign anymore. Also the reason I have it with [] is so I can send it as list for multiple rules. Obviously if you need only one then this wouldn’t be needed.

Leave a Reply

Your email address will not be published. Required fields are marked *