Deploy Network Policies with Terraform

A network policy controls which projects in your organisation can reach a workload (ingress), and which external networks a workload is allowed to reach (egress). Network policies are scoped to your organisation and reusable — define one, then attach it to a project or scope it to a single container or Memcached instance.

Updated 9 Jul 20262 min read

A network policy controls which projects in your organisation can reach a workload (ingress), and which external networks a workload is allowed to reach (egress). Network policies are scoped to your organisation and reusable — define one, then attach it to a project or scope it to a single container or Memcached instance.

Attaching a policy with any egress rules switches the target to deny-by-default for outbound traffic: only the ranges you allow (plus name resolution) get through. A policy with no egress rules leaves outbound traffic open and only constrains ingress.

Fields

FieldTypeDescription
handlestringUnique identifier (DNS-1123 compliant: lowercase, alphanumeric, hyphens). Required.
namestringDisplay name. Required.
ingresspeerslist(string)Handles of other projects in your organisation allowed to reach this policy's targets.
egresscidrslist(string)CIDR ranges the targets are allowed to send outbound traffic to. Adding any range switches outbound traffic to deny-by-default; name resolution stays allowed.
egressfqdnslist(string)Domain names allowed for outbound traffic. Restricts outbound HTTPS to these domains. Setting any domain turns on application-layer (L7) controls, billed per container replica in each region the policy is applied to.
l7enabledboolTurn on application-layer (L7) controls explicitly. Computed — automatically true when egressfqdns is set. Optional to set directly.
portslist(object)Optional port/protocol scoping applied to the rules above. Omit to allow all ports.

Each entry in ports has a port (1–65535, required) and an optional protocol (TCP or UDP, defaults to TCP).

Note

Application-layer (L7) controls carry a per-replica charge because each container the policy applies to runs a lightweight proxy. Layer 3/4 rules (ingress peers, egress CIDRs, ports) do not — they are billed only per attachment.

Example

resource "bahriya_network_policy" "web_tier" {
  handle = "web-tier"
  name   = "Web tier ingress"
 
  ingresspeers = ["frontend", "gateway"]
  egresscidrs  = ["10.0.0.0/8", "203.0.113.0/24"]
 
  ports = [
    {
      port     = 443
      protocol = "TCP"
    },
  ]
}

Attaching to a project

Attach the policy to a project so it applies to every workload in that project:

resource "bahriya_project" "production" {
  handle  = "production"
  name    = "Production"
  regions = ["helsinki-1", "falkenstein-1"]
}
 
resource "bahriya_project_network_policy_attachment" "web_tier" {
  project_id = bahriya_project.production.id
  handle     = bahriya_network_policy.web_tier.handle
}

Scoping to a single workload

To apply a policy to just one workload rather than the whole project, reference the handle on the container or Memcached resource:

resource "bahriya_container" "api" {
  # ... other fields ...
  networkpolicies = [bahriya_network_policy.web_tier.handle]
}

Importing

Network policies import by UUID; attachments import by their composite id:

terraform import bahriya_network_policy.web_tier 065df92e-4e46-436a-a0a0-aaaaaaaaaaaa
terraform import bahriya_project_network_policy_attachment.web_tier \
  8a3d0000-1111-2222-3333-444444444444:web-tier

See also