The OCI Terraform provider terraform-provider-oci v3.33.0 introduces support for Network Security Groups. This, in my opinion, is a game-changer for how to define security rules in your Terraform configurations.

Network Security Groups

With the current VCN Security Lists, security rules are applied to all instance vNICs within the subnet that uses the security list. In contrast, Network Security Group security rules are applied to a defined subset of vNICs across the entire VCN, regardless of the subnet, the vNIC is located in. This separation of the security context from the network topology allows for more fine-grained security control.

For users coming for Oracle Cloud Infrastructure Classic, this is somewhat analogous to defining the IP Network vNIC Sets

Let's consider a few potential use cases where we can use the new network security groups:

Consolidation of database and application tier instances into a single subnet. A common security architecture best practice to separate out access the database and application tiers into separate database and application subnets, and use subnet security lists to control the permitted traffic between the two. With network security groups the database and application instances can be deployed in the same subnet, while maintaining separate sets of security rules.

Fine grained access controls across subnets. Even when an application architecture retains network separation between, for example, the database and application tiers, network security groups can ensure that only the subset of app tier instances that need direct access to specific DB instances are permitted, preventing other app tier instances that not part of the security context from accessing the DB.

Single security group for a common instance type across all subnets. If you have a mix of Windows and Linux servers you could define a Windows specific network security group that enables access to Windows specific ports, like WinRM, that can be applied only to Windows instances regardless of the subnet they are deployed in. Any Linux instance in the same subnets (and not in the security group) would not have the Windows specific port access enabled.

Separation of application specific security rules from baseline infrastructure. Use of network security groups can eliminate the tight coupling between the baseline network provisioning and application resource provisioning. Modules, or even separate configurations, can overlay application specific security rules on an existing network without needing to modify the baseline network security lists and subnet resources.

Provisioning Network Security Groups with Terraform

Using the new network security group resources is straightforward. We start by creating the oci_core_network_security_group resource.

resource "oci_core_network_security_group" "example" {
compartment_id = var.compartment_id
vcn_id =
display_name = "Example Security Group"

We can now add one or more security rules to the security group. Unlike the VCN Security List rules, each network security group security rule is defined as a separate oci_core_network_security_group_security_rule resource.

resource "oci_core_network_security_group_security_rule" "https" {
network_security_group_id =

description = "HTTPS"
direction = "INGRESS"
protocol = 6
source_type = "CIDR_BLOCK"
source = ""
  tcp_options {
destination_port_range {
min = 443
max = 443

It’s worth highlighting that in addition to setting the rule source (or destination for egress rules) to a network or service CIDR, the network security group security rule has some unique powers that allow rules to control traffic between either two separate networks security groups in the same VCN, or the rule’s own network security group to control traffic just between the vNICs within the same group.

Finally we associate the network security group to a specific vNIC of an instance by adding the nsg_ids attribute in the create_vnic_details of either the instance resource, or the vNIC attachment resource for secondary vNICs.

resource "oci_core_instance" "instance1" {
availability_domain = local.availability_domain
compartment_id = var.compartment_id
display_name = "instance1"
 create_vnic_details {
subnet_id =
assign_public_ip = true
hostname_label = "instance1"
nsg_ids = [

Note: depending on the base OS used, local instance firewall rules may need to be modified appropriately to allow traffic on interfaces / ports enabled by the security rules.

New network security groups can be added to existing interfaces without forcing re-provisioning of the instance.


Always know your limits. The limits to be aware of for the network security group resources are covered here. In summary:

  • You can define up to 1000 network security groups in VCN
  • You can define up to 120 security rules in a network security group
  • A single vNIC can be in up to 5 network security groups

Related links

Security Rules