Automating F5 ADSP — Part 2: F5 XC and NGINX for Delivery and Security

What this use case demonstrates

This use case deploys NGINX Ingress Controller (NIC) running NGINX Plus with NGINX App Protect V5 (NAP V5) as the in-cluster data plane on GKE. WAF runs on two layers: NAP V5 enforcing inside the cluster, F5 Distributed Cloud (XC) enforcing at the edge. XC also provides API discovery and protection driven by an OpenAPI spec.

It covers all four ADSP areas: Delivery, Security, Deployment, and xOps.

  • Delivery: F5 Distributed Cloud HTTPS load balancer at the edge, NGINX Ingress Controller handling in-cluster delivery through the NIC VirtualServer CRD.
  • Security: Two layers of WAF. NAP V5 runs as NIC sidecars (waf-enforcer and waf-config-mgr) and enforces the WAF policy attached to the VirtualServer. XC WAF runs at the edge in blocking mode. XC API protection is driven by an OpenAPI spec.
  • Deployment: XC consumed as SaaS, GKE Standard with private nodes, NIC and NAP installed via OCI Helm chart, the application installed via a separate OCI Helm chart.
  • xOps: NAP policy lives in config/uc2/nap/policy.json. The workflow compiles it with the NAP waf-compiler container, uploads the compiled bundle to GCS, and NIC mounts the bundle read-only via the GCS Fuse CSI driver. The waf-config-mgr sidecar watches the mount and pushes updates to the waf-enforcer. Change the policy, push, and NAP follows.

Architecture

What gets deployed:

  • A GCP VPC with a dedicated k8s subnet (with secondary ranges for pods and services), management subnet, and NAT for private nodes
  • A GKE Standard zonal cluster with private nodes and a control plane locked down by authorized networks
  • NGINX Ingress Controller running NGINX Plus, with NAP V5 enforcer and config-mgr sidecars
  • Comfy Capybara deployed via an OCI Helm chart, exposed through a NIC VirtualServer that references the waf-policy CRD in the nginx-ingress namespace
  • An F5 Distributed Cloud HTTP load balancer with WAF and API protection. The origin pool is resolved from the NIC LoadBalancer IP via Terraform remote state.

The VirtualServer attaches waf-policy both server-wide and on the /api route by default, so the policy enforces everywhere as a baseline.

DevSecOps in practice for UC2

The lead-in covers the approach. For UC2, that means:

  • Terraform handles infrastructure, the GKE cluster, NIC and NAP, the application Helm release, and all F5 Distributed Cloud objects. No click-ops.
    • State lives in a GCS bucket the workflow creates on the first run, with a separate state file per module. The same bucket carries the compiled NAP policy bundle that NIC mounts via the GCS Fuse CSI driver. The XC origin pool reads the NIC LoadBalancer IP from state/uc2/nic, so no IP is pasted between configs.
  • GitHub Actions runs the pipeline.
  • Branch names trigger deployments, so git history shows what was meant to happen.
  • GCP Workload Identity Federation replaces static service account keys for the runner. NIC pods also use Workload Identity to impersonate the runtime service account when mounting the NAP bundle from GCS.
  • The XC API certificate, NGINX Plus JWT, and NGINX registry credentials live in GitHub Actions secrets, not the repo.
  • The OpenAPI spec at config/uc2/app/oas/openapi.json is base64-encoded by the workflow and referenced inline by the XC API definition. Change the spec, push, and API protection follows.

The pipeline

Pushing to a branch runs the workflow. There is no manual terraform apply or helm install.

Action Branch
Validate, plan, and apply deploy-adsp-uc2
Validate only (no apply) test-adsp-uc2
Destroy all resources destroy-adsp-uc2

Modules deploy sequentially: state bucket - infra - GKE - compile NAP policy - NIC and NAP - app - XC. Destroy runs in reverse.

What’s in the repo

f5devcentral/F5-ADSP-Automation:

Directory Purpose
infra/gcp/ VPC, subnets with pod and service secondary ranges, NAT, firewall
k8s/gcp/ GKE Standard cluster and node pool
f5/nic/gcp/ NGINX Ingress Controller and NAP V5 Helm release
f5/xc/ F5 Distributed Cloud HTTP LB, WAF, API definition (shared with other XC use cases)
app/gcp/ Comfy Capybara Helm release and VirtualServer
config/uc2/gcp/env.json GCP, GKE, and NIC config
config/uc2/nap/policy.json NAP policy source, compiled in the workflow
config/uc2/app/env.json Application chart and VirtualServer config
config/uc2/app/oas/openapi.json OpenAPI spec the XC API definition is built from
config/uc2/xc/env.json XC tenant, LoadBalancer, WAF and API feature flags
.github/workflows/ CI/CD workflows

Prerequisites, secrets, and troubleshooting are in the UC2 deployment guide.

Demo

Try it

Fork f5devcentral/F5-ADSP-Automation, set the secrets and tfvars from the deployment guide, and push to deploy-adsp-uc2. Push to destroy-adsp-uc2 to tear it down.

Contribute

Issues and PRs welcome at f5devcentral/F5-ADSP-Automation.

Resources:

F5 Application Delivery and Security Platform GitHub Repo and Automation Guide

ADSP Architecture Article Series:

Automating F5 ADSP Deployments (Intro)
Automating F5 ADSP Deployments (Part 1 - F5 XC WAF and BIG-IP Adv. WAF) 
Automating F5 ADSP Deployments (Part 2 - F5 XC API Security and NGINX Ingress & App Protect) 
Automating F5 ADSP Deployments (Part 3 - F5 XC API Protection and NGINX Ingress) 
Automating F5 ADSP Deployments (Part 4 - F5 XC API Security and NGINX Gateway Fabric) 
Automating F5 ADSP Deployments (Part 5 - F5 XC, BIG-IP APM, CIS, and NGINX Ingress) 
Minimizing Security Complexity: Managing Distributed WAF Policies

3 Likes