Configure Network Policies and Egress Firewalls for a ROSA Cluster
This content is authored by Red Hat experts, but has not yet been tested on every supported configuration. This guide has been validated on OpenShift 4.20. Operator CRD names, API versions, and console paths may differ on other versions.
It is common to restrict network access between namespaces and to control where traffic can leave the cluster. OpenShift implements both with NetworkPolicy and EgressFirewall resources on the OVN-Kubernetes network plugin.
These controls apply the same way on ROSA Hosted Control Planes (HCP) and ROSA Classic. Both architectures run OVN-Kubernetes on the data plane, so the project template, NetworkPolicy, and EgressFirewall objects in this guide work on either cluster type.
When to use this guide
Use this guide when you want a baseline namespace isolation pattern for multi-tenant ROSA clusters:
- Restrict pod-to-pod traffic across namespaces with
NetworkPolicy - Control which external destinations workloads can reach with
EgressFirewall - Automate those defaults for every new project through a project request template
These OpenShift resources complement (they do not replace) AWS edge controls such as security groups, NAT gateways, and transit gateway inspection. Pair EgressFirewall with
Egress IP
when external allowlists need predictable source IPs. For design rationale, see
Network isolation with NetworkPolicies and Egress Firewalls
in the ROSA best practices guide.
NetworkPolicy vs EgressFirewall
The two resources operate at different layers. The project template in this guide uses both:
| Goal | Resource | What the template does |
|---|---|---|
| Block pod-to-pod traffic across namespaces | NetworkPolicy |
Allows ingress only from the Ingress Controller namespace and from pods in the same namespace |
| Block or allow traffic leaving the cluster | EgressFirewall |
Denies egress to all external destinations except cluster DNS (see below) |
NetworkPolicy in this guide controls ingress only. It does not deny egress. EgressFirewall controls egress to destinations outside the pod network.
OVN-Kubernetes constraints
- Each namespace can have at most one
EgressFirewallobject. - Rules are evaluated in order. Place
Allowrules before catch-allDenyrules. - The project template applies only to new projects. Existing namespaces (including
openshift-*andkube-*) are unaffected until you apply policies manually. - For platform-wide rules on supported versions, cluster administrators can also use
AdminNetworkPolicy
. That is a separate cluster-level layer on top of namespace-scoped
NetworkPolicyobjects.
Prerequisites
- A ROSA cluster on OpenShift 4.20 or newer. This procedure is identical on HCP and Classic; only cluster provisioning differs:
- ROSA HCP: Follow the Deploying a ROSA HCP cluster with Terraform guide
- ROSA Classic: Follow the Deploying a ROSA Classic cluster with Terraform guide
- Cluster administrator access (
cluster-adminor equivalent). Creating the project template, patchingproject.config.openshift.io/cluster, and creatingEgressFirewallobjects require cluster-admin privileges. - OpenShift CLI (
oc)
Project template
The first step is to create a project template that contains NetworkPolicy and EgressFirewall objects with default deny rules.
-
Look up the cluster DNS service IP. Most ROSA clusters use
172.30.0.10, but confirm on your cluster:A deny-all
EgressFirewallwithout a DNS exception blocks name resolution for pods in affected namespaces. -
Create and apply a project template with default deny rules
NOTE This template ensures that any new project has an egress policy that allows cluster DNS and denies all other external traffic, plus a network policy that only allows ingress from an Ingress Controller and from pods in the same namespace.
Do not set
metadata.namespaceon theNetworkPolicyorEgressFirewallobjects. OpenShift assigns the new project namespace when it processes the template ( OCP 4.20 project template guidance ).Confirm the template object exists before you continue:
If this command returns
NotFound,oc new-projectfails later even after you patch the cluster project config. Re-run thecat <<EOF | oc apply -f -step and fix any apply errors first. -
Patch the project configuration to use the newly created project template
-
Create a new project to verify the policies
If you already created the demo project before the template was configured, delete it and wait until the namespace is gone. If the namespace still exists,
oc new-project egress-demoprintsAlready on project "egress-demo"and does not run the template. -
Verify the policies were created
Expected results:
egressfirewall.k8s.ovn.org/defaultexists in the demo namespacenetworkpolicy.networking.k8s.io/deny-by-defaultexists in the demo namespace- Egress firewall status is
EgressFirewall Rules applied(check withjsonpathordescribeif the table column is not shown)
If either object is missing, use the manual apply step in the next subsection, then continue with the tests.
If the template did not create policies
Some clusters (including certain ROSA HCP configurations) create the project and admin RoleBinding but skip NetworkPolicy or EgressFirewall objects from the template. Apply the policies directly:
Use DEMO_PROJECT=egress-demo-2 if you created a differently named project.
Test the Network Policy
These tests use oc exec against long-running pods in the target namespace. That keeps traffic in the namespace you intend to test. Avoid oc debug for these checks: recent OpenShift CLI versions create short-lived debug pods with different output formatting.
-
Create test pods in the
defaultandegress-demonamespaces -
Deploy a sample application and expose it
-
Access the application via its Route from your workstation (should succeed)
Expected: response body contains Hello OpenShift!
-
Access the application via its Route from the
defaultnamespace (should succeed)Traffic enters through the Ingress Controller, which matches the allowed
NetworkPolicysource.Expected: response body contains Hello OpenShift!
-
Access the application via its cluster service from within
egress-demo(should succeed)Expected: response body contains Hello OpenShift!
-
Access the application via its cluster service from
default(should fail)Expected: command times out or exits non-zero. No response body.
Test the Egress Firewall
-
Verify external access from the
defaultnamespace (should succeed)Expected: command prints a public IP address.
-
Verify external access from the
egress-demonamespace (should fail)Expected: command times out or exits non-zero. No public IP is returned.
Allow specific egress destinations
Production namespaces rarely stay on deny-all egress. Update the EgressFirewall to allow specific FQDNs or CIDR blocks before the catch-all deny rule.
-
Patch the
egress-demonamespaceEgressFirewallto allowicanhazip.comand keep the DNS exception:If you opened a new shell, set
CLUSTER_DNSagain with the lookup command from the project template section. -
Verify that the allowed external host is reachable from the
egress-demonamespaceExpected: command prints a public IP address.
-
Verify that other external hosts remain blocked
Expected: command times out or exits non-zero.
Cleanup
Remove demo resources and, if this was a lab cluster, revert the project template configuration.
-
Delete test workloads and the demo project
-
Remove the custom project template
-
Clear the project request template reference (restores OpenShift default project creation behavior)
On some OpenShift versions you may need to remove the
projectRequestTemplatekey with a strategic merge oroc edit project.config.openshift.io/clusterinstead. Confirm new project creation behaves as expected after cleanup.