Note:
- This tutorial requires access to Oracle Cloud. To sign up for a free account, see Get started with Oracle Cloud Infrastructure Free Tier.
- It uses example values for Oracle Cloud Infrastructure credentials, tenancy, and compartments. When completing your lab, substitute these values with ones specific to your cloud environment.
Configure Per-resource Routing in Oracle Cloud Infrastructure
Introduction
Per-resource Routing refers to the ability to define routing rules directly on a specific VNIC or an individual IP address associated with that Virtual Network Interface Card (VNIC). This offers enhanced routing control tailored to each resource in a single subnet, in case they have different requirements, rather than relying solely on the subnet-level route table. This allows organizations to optimize network traffic and ensure better performance by routing data to the appropriate destination resource based on the source.
With Per-resource Routing, Oracle Cloud Infrastructure (OCI) users can configure routing policies that apply to individual resources, ensuring that traffic is directed in a way that optimally supports the application architecture. It enhances network control, making it easier to manage complex cloud environments. This method of routing helps in improving traffic flow by defining how traffic should be routed to specific resources.
Objectives
In this tutorial, we will provide a comprehensive understanding of Per-resource Routing within OCI.
-
Understand the concept of Per-resource Routing: Learn how routing policies can be applied to specific OCI resources for better traffic management and performance optimization.
-
Set up Routing Rules: Gain hands-on experience in creating and configuring Per-resource routing rules in OCI to direct network traffic effectively to different resources based on the source VNIC.
Prerequisites
-
Access to an OCI tenancy and permissions to manage the required network, compute, and storage services.
-
Basic understanding of OCI network routing and security and their functionalities: Virtual Cloud Network (VCN), Route Table, Security List, and Bastion service. Also, some knowledge in Oracle Cloud Infrastructure Identity and Access Management (OCI IAM) dynamic groups and policies will be helpful.
-
Review the following documents to gain a solid understanding of OCI routing, with a focus on Per-resource Routing. This will provide valuable context before moving on to the practical implementation.
Note: Each example is prepared independently from the other. You can work on them in any order.
Example 1: Inspect Internet Traffic for only one Virtual Machine (VM) through OCI Network Firewall
Example Objectives:
In this example, we focus on routing the outbound Internet traffic of one specific VM through an OCI Network Firewall to inspect and secure it before it reaches the NAT gateway, and bypass firewall for the second VM in the same subnet. Without Per-resource Routing, you will have to place each instance in a different subnet in order to achieve this scenario.
Example Prerequisites:
Configure some essential components to align with this design. It is basically two compute instances in a private subnet, in addition to a network firewall in a separate subnet in the same VCN.
-
Create a Virtual Cloud Network (for example,
MyVCN
(192.168.0.0/16
)). For more information, see Creating a VCN. -
Create two private subnets. For more information, see Creating a Subnet.
Application-Private-Subnet
(192.168.0.0/24
): In this tutorial, we are assigning the default route table and default security list to the subnet.Firewall-Private-Subnet
(192.168.1.0/24
).
-
Create a NAT gateway in a VCN. A NAT gateway allows cloud resources without public IP addresses to access the Internet, providing only outbound connectivity without exposing those resources to inbound internet connections. For more information, see Creating a NAT Gateway
-
Create two compute instances
Linux-VM-1
andLinux-VM-2
. For more information, see Task 2: Provision an OCI Compute Instance. Take into consideration the following points:- The name of each OCI Compute instance.
- Use Oracle Linux as the Operating System (OS).
- Place both of the instances in
Application-Private-Subnet
and assign the IPs manually as per the design. - Enable OCI Bastion plugin.
-
Create an OCI Bastion service and a session, you will need it to securely access the instances since they reside in a private subnet, and then test at the end of the setup. Take into consideration the differences such as the target network and instance to suit the components you created for this tutorial. For more information, see Task 6.1: Access FE-VM Compute Instance using Bastion and Test.
-
Provision a firewall solution, it can be:
- An OCI firewall (we are using this in the tutorial).
- A third-party firewall instance (FortiGate, Palo Alto, and so on). Another good example is pfSense firewall. To install, see Task 3: Install and Configure pfSense Firewall.
- Any Linux-based firewall instance.
Task 1: Prepare OCI Network Firewall to Inspect Traffic from Linux-VM-2
to Internet
- With Default Security List, we will permit all traffic to pass through the firewall for thorough evaluation, ensuring full control over it with the firewall instead of OCI security rules, including allowing, denying, or monitoring through Identity Services.
- Default Route Table for MyVCN: Empty, not used.
- With Firewall Subnet Route Table, we will route all traffic to the Internet (one way) through NAT gateway.
- With NAT Route Table, to route response traffic coming from the Internet to the firewall to be inspected before sending it back to the source (
Linux-VM-2
).
Task 1.1: Set up Firewall Subnet Routing and Security
-
Log in to the OCI Console, go to the Virtual Cloud Network Details page.
-
Scroll down.
- Click Security Lists.
- Click the default security list.
- Allow all ingress traffic.
- Allow all egress traffic.
- Navigate to the Virtual Cloud Network Details page.
- Scroll down.
- Click Route Tables.
- Click Create Route Table.
- Enter Name for the route table.
- Click + Another Route Rule.
-
In Rule, enter the following information.
- In Target Type, select NAT Gateway.
- In Destination CIDR Block, enter
0.0.0.0/0
. - In Target NAT Gateway, select the NAT gateway created in Prerequisites.
- Click Create.
-
The
Firewall Subnet Route Table
is created successfully. -
Now, let us assign the route table to the firewall subnet. Go to the Virtual Cloud Network Details page.
- Click Subnets.
- Click Firewall-Private-Subnet.
-
Click Edit.
- Use the route table created above.
- Click Save changes.
-
Route table is changed successfully.
In this task, we have created and assigned a subnet-level route table, meaning that all resources deployed within this subnet will be governed by the defined routing rules.
Task 1.2: Create and Assign NAT Gateway Route Table
-
Make sure to create a NAT gateway before proceeding. Go to the Virtual Cloud Network Details page.
- Click Route Tables.
- Click Create Route Table.
- Enter Name for the route table.
- Click +Another Route Rule.
-
In Rule, enter the following information.
- In Target Type, select Private IP.
- In Destination Type, enter
192.168.0.0/24
which is the Application-Private-Subnet CIDR, that has the source VM. - In Target Selection, enter the private IP of the firewall
192.168.1.100
. - Click Create.
-
The
NAT Route Table
is created successfully. -
Let us assign the route table to the NAT gateway. Go to the Virtual Cloud Network Details page.
- Click NAT Gateways.
- Click the gateway’s three dots on the right.
- Click Associate Route Table.
- Select NAT Route Table.
- Click Associate Route Table.
-
Route table is associated successfully.
Task 1.3: Enable Firewall Logs and Check the Policy
Note: In this tutorial, we use OCI Network Firewall, but you can replicate the same scenario with any third-party firewall.
-
Navigate to the Network Firewall details page.
-
Scroll down.
- Click Logs.
- Enable Traffic Log (traffic log provides details on traffic passing through the firewall).
- Select Log group, if you do not have any then create one.
- Enter Log name.
- Click Enable log.
- Traffic log is enabled successfully.
- Click the associated Network firewall policy.
-
We are using
network_firewall_policy_v1
policy. -
Scroll down and check the policy existing configuration.
- Click Security rules.
- Click the three dots on the right of the
IPS_VM2_Internet
rule. - Click View details.
-
Notice the used security rule details.
- Any traffic coming from
Linux-VM-2
to anywhere, regardless of the protocol or port used. - Use Intrusion prevention as Rule action, to monitor traffic for malicious activity. Log information, report, or block the activity.
- Any traffic coming from
Task 2: Create Custom Route Tables
-
Navigate to the Virtual Cloud Network Details page.
-
Scroll down.
- Click Route Tables.
- Notice that we have a default route table which is created with the VCN automatically. This table is assigned to the
Application-Private-Subnet
and all VMs inside the subnet will use it (in this example, this route table is empty). - However, for this tutorial, we are going to create custom route tables and assign each one of them to its respective VM’s VNIC. This method offers more granular control over routing, avoiding dependency on the subnet route table. Click Create Route Table.
-
Create the second table (
Custom Route Table 1
), which will be assigned toLinux-VM-1
in order to route traffic to NAT gateway directly without inspecting traffic through the firewall.- Enter Name for the route table.
- Click +Another Route Rule.
-
In Rule, enter the following information.
- In Target Type, select NAT Gateway.
- In Destination CIDR Block, enter
0.0.0.0/0
. - In Target NAT Gateway, select the NAT Gateway created in Prerequisites
- Click Create.
-
The
Custom Route Table 1
is created successfully. -
To create the second table (
Custom Route Table 2
), click Create Route Table. -
The
Custom Route Table 2
will be assigned toLinux-VM-2
in order to route traffic to firewall to be inspected first before sending it to NAT gateway.- Enter Name for the route table.
- Click +Another Route Rule.
-
In Rule, enter the following information.
- In Target Type, select Private IP.
- In Destination CIDR Block, enter
0.0.0.0/0
. - In Target Selection, enter the private IP of the firewall
192.168.1.100
. - Click Create.
-
The
Custom Route Table 2
is created successfully.
Task 3: Assign Custom Route Tables to the VNICs
-
Let us start with
Linux-VM-1
.- Notice that by default, the instance’s VNIC will use the route table attached to the subnet where the VM resides. In this tutorial, it is
Default Route Table for MyVCN
. Our goal here is to change the route table to be Per-resource Routing, where the instance (VNIC) will have its own route table. - Scroll down.
- Click Attached VNICs.
- Click the three dots on the right of the primary VNIC.
- Click Edit VNIC.
- By default, each VNIC will use the route table associated with the subnet.
- Click Select custom route table for the VNIC.
- In Route table, select Custom Route Table 1.
- Note that default route table will not be looked at when making routing decisions once you save your configuration here.
- Click Save changes.
- Notice that by default, the instance’s VNIC will use the route table attached to the subnet where the VM resides. In this tutorial, it is
-
The
Custom Route Table 1
is assigned toLinux-VM-1
’s primary VNIC successfully. -
Now, assign for
Linux-VM-2
.- Notice that by default, the instance VNIC will use the route table attached to the subnet where the VM resides. In this tutorial, it is
Default Route Table for MyVCN
. Our goal here is to change the route table here to be Per-resource Routing, where the instance (VNIC) will have its own route table. - Scroll down.
- Click Attached VNICs.
- Click the three dots on the right of the primary VNIC.
- Click Edit VNIC.
- By default, each VNIC will use the route table associated with the subnet.
- Click Select custom route table for the VNIC.
- In Route table, select Custom Route Table 2.
- Note that default route table will not be looked at when making routing decisions once you save your configuration here.
- Click Save changes.
- Notice that by default, the instance VNIC will use the route table attached to the subnet where the VM resides. In this tutorial, it is
-
The
Custom Route Table 2
is assigned toLinux-VM-2
’s primary VNIC successfully.
Task 4: Test and Validate
-
Test 1: Test
Linux-VM-1
to Internet Access without Firewall Inspection-
Log in to
Linux-VM-1
.Note: We used the OCI Bastion service to access the instance, as it is located in a private subnet. You can use any other method, such as a traditional jump box (Windows, Linux), Site-to-Site VPN, or other alternatives.
-
Ping
8.8.8.8
, which is the public IP of Google’s DNS server. According to the configuration we set up, the traffic will route through the NAT gateway directly without being inspected by the firewall. -
Go to the Network Firewall details page.
- Click Logs.
- Click the log name.
-
Set up the filter to check the ping traffic in the previous test.
- IP Address of
Linux-VM-1
is192.168.0.10
. - Protocol is
ICMP
. - Click Search.
- Note that there is no indication of traffic from
Linux-VM-1
passing through the firewall, which is the expected result since we configured the custom route table to route traffic directly to the NAT gateway.
- IP Address of
-
-
Test 2: Test
Linux-VM-2
to Internet Access with Firewall Inspection-
Log in to
Linux-VM-2
.Note: We used the OCI Bastion service to access the instance, as it is located in a private subnet. You can use any other method, such as a traditional jump box (Windows, Linux), Site-to-Site VPN, or other alternatives.
-
Ping
8.8.8.8
, which is the public IP of Google’s DNS server. According to the configuration we set up, the traffic will route through the NAT gateway after being inspected by the firewall. -
Go to the Network Firewall details page.
- Click Logs.
- Click the log name.
-
Set up the filter to check the ping traffic in the previous test.
- IP Address of
Linux-VM-2
is192.168.0.20
. - Protocol is
ICMP
. - Click Search.
- IP Address of
-
You can see from the logs that traffic to Internet passed through the firewall.
- Destination IP Address is
8.8.8.8
. - Protocol is
ICMP
. - Source IP Address is
192.168.0.20
.
- Destination IP Address is
This shows how we managed to give each VM different routing configuration with Per-resource Routing even though they are within the same subnet, providing fine-grained control over traffic flow and optimizing network management.
-
Example 2: Separate Internet Traffic from Oracle Services Network only Traffic
Example Objectives:
In this example, we will demonstrate how two resources within the same subnet can be configured with different routes, directing traffic to the Oracle services network and the Internet through separate gateways. Linux-VM-1
requires access only to the Oracle services network especially OCI Object Storage without routing through the public Internet, restricted to Oracle Jeddah data center, whereas Linux-VM-2
requires outbound Internet access, that means access to any public IP address, including those within the Oracle services network. Without Per-resource Routing, you will have to place each instance in a different subnet in order to achieve this scenario.
Example Prerequisites:
Configure some essential components to align with this design. It is basically two compute instances in a private subnet.
-
Create a Virtual Cloud Network (for example,
MyVCN
(192.168.0.0/16
)). For more information, see Creating a VCN. -
Create a private subnet. For more information, see Creating a Subnet.
Application-Private-Subnet
(192.168.0.0/24
). In this tutorial, we are assigning the default route table and default security list to the subnet.
-
Create a NAT gateway in a VCN. A NAT gateway allows cloud resources without public IP addresses to access the internet, providing only outbound connectivity without exposing those resources to inbound internet connections. For more information, see Creating a NAT Gateway.
-
Create a service gateway in a VCN. A service gateway lets your VCN privately access specific Oracle services without exposing the data to the public internet. No internet gateway or NAT gateway is required to reach those specific services. For more information, see Creating a Service Gateway.
-
Create two compute instances
Linux-VM-1
andLinux-VM-2
. For more information, see Task 2: Provision an OCI Compute Instance. Take into consideration the following points:- The name of each instance.
- Use Oracle Linux as the OS.
- Place both of the instances in the same subnet you created earlier and assign the IPs manually as per the design.
- Enable OCI Bastion plugin.
-
Create an OCI Bastion service and a session, you will need it to securely access the instances since they reside in a private subnet, and then test at the end of the setup. Take into consideration the differences such as the target network and instance to suit the components you created for this tutorial. For more information, see Task 6.1: Access FE-VM Compute Instance using Bastion and Test.
Task 1: Create Custom Route Tables
-
Go to the OCI Console.
- Navigate to the VCN.
- Scroll down.
- Click Route Tables.
- Notice that we have a default route table which is created with the VCN automatically. This table is assigned to the
Application-Private-Subnet
and all VMs inside the subnet will use it.
-
However, for this tutorial, we are going to create custom route tables and assign each one of them to its respective VM’s VNIC. This method offers more granular control over routing, avoiding dependency on the subnet route table. Click Create Route Table.
-
Create first table (
Custom Route Table 1
), which will be assigned toLinux-VM-1
to route traffic through the service gateway, enabling connectivity to Oracle services network, specifically for accessing OCI Object Storage.- Enter Name for the route table.
- Click +Another Route Rule.
-
In Rule, enter the following information.
- In Target Type, select Service Gateway.
- In Destination CIDR Block, select All JED Services In Oracle Services Network. This ensures access to all Oracle services including OCI Object Storage, which we will test at the end. Additionally, if you are using OCI Bastion to connect to the VMs, you must select the all services option we mentioned rather than limiting it to OCI Object Storage.
- In Target Service Gateway, select the service gateway created in Prerequisites.
- Click Create.
-
The
Custom Route Table 1
is created successfully. -
To create the second table (
Custom Route Table 2
), click Create Route Table. -
The
Custom Route Table 2
will be assigned toLinux-VM-2
in order to route traffic through NAT gateway, enabling unidirectional connectivity to the Internet including OCI Object Storage endpoint.- Enter Name for the route table.
- Click +Another Route Rule.
-
In Rule, enter the following information.
- In Target Type, select NAT Gateway.
- In Destination CIDR Block, enter
0.0.0.0/0
. - In Target NAT Gateway, select the NAT gateway created in Prerequisites.
- Click Create.
-
The
Custom Route Table 2
is created successfully.
Task 2: Assign Custom Route Tables to the VNICs
-
Let us start with
Linux-VM-1
.- Notice that by default, the instance’s VNIC will use the route table attached to the subnet where the VM resides. In this tutorial, it is
Default Route Table for MyVCN
. Our goal here is to change the route table to be Per-resource Routing, where the instance (VNIC) will have its own route table. - Scroll down.
- Click Attached VNICs.
- Click the three dots on the right of the primary VNIC.
- Click Edit VNIC.
- By default, each VNIC will use the route table associated with the subnet.
- Click Select custom route table for the VNIC.
- In Route Table, select
Custom Route Table 1
. - Note that default route table will not be looked at when making routing decisions once you save your configuration here.
- Click Save changes.
- Notice that by default, the instance’s VNIC will use the route table attached to the subnet where the VM resides. In this tutorial, it is
-
The
Custom Route Table 1
is assigned toLinux-VM-1
’s primary VNIC successfully. -
Now, assign for
Linux-VM-2
.- Notice that by default, the instance’s VNIC will use the route table attached to the subnet where the VM resides. In this tutorial, it is
Default Route Table for MyVCN
. Our goal here is to change the route table to be Per-resource Routing, where the instance (VNIC) will have its own route table. - Scroll down.
- Click Attached VNICs.
- Click the three dots on the right of the primary VNIC.
- Click Edit VNIC.
- By default, each VNIC will use the route table associated with the subnet.
- Click Select custom route table for the VNIC.
- In Route Table, select
Custom Route Table 2
. - Note that default route table will not be looked at when making routing decisions once you save your configuration here.
- Click Save changes.
- Notice that by default, the instance’s VNIC will use the route table attached to the subnet where the VM resides. In this tutorial, it is
-
The
Custom Route Table 2
is assigned toLinux-VM-2
’s primary VNIC successfully.
Task 3: Create an OCI Object Storage Bucket
An OCI Object Storage bucket is a logical container used to store and organize objects (files and data) in OCI.
-
Go to the OCI Console, click the hamburger menu (≡) from the upper left corner.
- Click Storage.
- Click Buckets.
-
Click Create Bucket.
- Enter Bucket Name.
- Click Create.
-
The
Test-Bucket
bucket is created successfully. Now, click the bucket. -
Since the bucket is still new, you will notice that it is empty.
Task 4: Test and Validate
Task 4.1: Prepare the VMs to have access to Oracle Services Network
-
Instance principal is the capability in the OCI IAM service that allows you to make service calls from an instance. We will use instance principals to access OCI Object Storage from a compute instance without credentials. For more information, see Calling OCI CLI Using Instance Principal.
Steps to do:
-
Create a dynamic group (
TestDG
) to include all instances in a specific compartment (Linux-VM-1
andLinux-VM-2
).Any {instance.compartment.id = 'ocid1.compartment.oc1..aaaaaaaacmshv5fxxxxxxxxxxxxxxxykxgy3qvetychowq'}
-
Create an OCI IAM policy.
Allow dynamic-group TestDG to manage object-family in compartment AnasAbdallah
Note: Make sure to use your dynamic group name, compartment name and OCID in the above policies.
-
-
Repeat the following steps after you log in to both of the instances,
Linux-VM-1
andLinux-VM-2
.-
Run the following command to install OCI CLI on Oracle Linux 8. For more information, see Installing the CLI.
sudo dnf -y install oraclelinux-developer-release-el8 sudo dnf install python36-oci-cli
-
To have the OCI CLI guide you through the first-time setup process, run the
oci setup config
command.- Press Enter.
- Enter your Username OCID.
- Enter the Tenancy OCID.
- Enter the Region index, we are deploying this environment in Jeddah region, which is
49
. - Type
Y
and press Enter - Press Enter.
- Press Enter.
- Public API key is saved in this path, we will use it shortly.
- Type a new passphrase.
- Repeat the passphrase.
- Run the
cat /home/opc/.oci/oci_api_key_public.pem
command to display the public key. - Copy the public key.
- Go to the OCI Console and navigate to your profile.
- Scroll down.
- Click API keys.
- Click Add API key.
- Select Paste a public key.
- Paste the public key.
- Click Add.
-
API key is added successfully.
-
Task 4.2: Test Linux-VM-1
to Oracle Services Network Access
-
As per the configuration,
Linux-VM-1
should have access to OCI Object Storage only, without any internet access, and it will use service gateway.- To check the name of the OCI Object Storage namespace, run the
oci os ns get
command. - Take note of the namespace as you will use it in the next command.
- Run the
oci os object list --bucket-name <bucket-name> --namespace <namespace>
command to list the objects inTest-Bucket
. - The bucket is empty.
Note: OCI Object Storage namespace serves as the top-level container for all buckets and objects in the tenancy. At account creation time, each OCI tenancy is assigned one unique system-generated and immutable OCI Object Storage namespace name.
- Create a text file named
object1.txt
, and write abc into it. - Show the content of the file.
- We can see abc as the output.
- To upload
object1.txt
toTest-Bucket
, run theoci os object put -ns <namespace> -bn <bucket-name> --file <file-path>
command. - Upload is completed.
- To check the name of the OCI Object Storage namespace, run the
-
To check if the file is uploaded, go to the Bucket Details page.
-
Scroll down.
- Click Objects.
- Note that the
object1.txt
file is uploaded successfully toTest-Bucket
. You can verify the content of the file by downloading it.
-
One more thing to test is the Internet connectivity from
Linux-VM-1
.- Ping
8.8.8.8
, which is the public IP of Google’s DNS server. According to the configuration we set up,Linux-VM-1
should not have Internet connectivity. - As you see ping is failing.
- Ping
Task 4.3: Test Linux-VM-2
to Internet Access
-
As per the configuration,
Linux-VM-2
should have Internet connectivity, this includes access to OCI Object Storage, which is done through NAT gateway. Although both VMs are in the same subnet, Per-resource Routing enables them to use different network paths, which is the key concept behind this setup.- To check the name of the OCI Object Storage namespace, run the
oci os ns get
command. - Take note of the namespace as you will use it in the next command.
- Run the
oci os object list --bucket-name <bucket-name> --namespace <namespace>
command to list the objects inTest-Bucket
. - We can see the
object1.txt
file stored in the bucket which we uploaded in Task 4.2.
Note: OCI Object Storage namespace serves as the top-level container for all buckets and objects in the tenancy. At account creation time, each OCI tenancy is assigned one unique system-generated and immutable OCI Object Storage namespace name.
- Create a text file named
object2.txt
, and write def into it. - Show the content of the file.
- We can see def as the output.
- To upload
object2.txt
toTest-Bucket
, run theoci os object put -ns <namespace> -bn <bucket-name> --file <file-path>
command. - Upload is completed.
- To check the name of the OCI Object Storage namespace, run the
-
To check if the file is uploaded, go to Bucket Details.
-
Scroll down.
- Click Objects.
- Note that the
object2.txt
file is uploaded successfully toTest-Bucket
. You can verify the content of the file by downloading it.
-
One more thing to test is the Internet connectivity from
Linux-VM-2
.- Ping
8.8.8.8
, which is the public IP of Google’s DNS server. According to the configuration we set up,Linux-VM-2
should also have Internet connectivity. - Ping is successful.
- Ping
Conclusion
With two in-depth technical examples, this tutorial showcased how Per-resource Routing in OCI provides precise control over network traffic by allowing custom route tables to be applied directly to individual VNICs within the same subnet. It also highlighted the key differences between Per-resource Routing and traditional subnet-level route tables, emphasizing the flexibility and efficiency this feature brings to modern cloud network design.
Acknowledgments
- Authors - Anas Abdallah (Cloud Networking Specialist), Sachin Sharma (Cloud Networking Specialist)
More Learning Resources
Explore other labs on docs.oracle.com/learn or access more free learning content on the Oracle Learning YouTube channel. Additionally, visit education.oracle.com/learning-explorer to become an Oracle Learning Explorer.
For product documentation, visit Oracle Help Center.
Configure Per-resource Routing in Oracle Cloud Infrastructure
G31421-02
Copyright ©2025, Oracle and/or its affiliates.