Expose applications on gateways
What you’ll accomplish
Section titled “What you’ll accomplish”After completing this guide, your application will be accessible through one of UDS Core’s ingress gateways, either the tenant gateway (for end-user applications) or the admin gateway (for admin-facing interfaces).
Prerequisites
Section titled “Prerequisites”- UDS CLI installed
- UDS Registry account created and authenticated locally with a read token
- Access to a Kubernetes cluster with UDS Core deployed and TLS configured (see Configure TLS certificates)
- A domain configured in your
uds-config.yaml:uds-config.yaml shared:domain: yourdomain.comadmin_domain: admin.yourdomain.com # optional, defaults to admin.<domain> - Wildcard DNS records for
*.yourdomain.comand*.admin.yourdomain.compointing to the tenant and admin gateway load balancer IPs - Familiarity with Zarf packages
-
(Optional) Enable root domain support
By default, UDS Core gateways use wildcard hosts (e.g.,
*.yourdomain.com), which match subdomains but not the root domain itself. If you need to serve traffic athttps://yourdomain.com, enable root domain support in your UDS Core bundle:uds-bundle.yaml packages:- name: corerepository: registry.defenseunicorns.com/public/coreref: x.x.x-upstreamoverrides:istio-tenant-gateway:uds-istio-config:values:- path: rootDomain.enabledvalue: true- path: rootDomain.tls.modevalue: SIMPLE- path: rootDomain.tls.credentialNamevalue: "" # Leave blank to auto-create the secret from cert data- path: rootDomain.tls.supportTLSV1_2value: truevariables:- path: rootDomain.tls.certname: "ROOT_TLS_CERT"- path: rootDomain.tls.keyname: "ROOT_TLS_KEY"sensitive: true- path: rootDomain.tls.cacertname: "ROOT_TLS_CACERT"Create and deploy the bundle:
Terminal window uds create --confirm && uds deploy uds-bundle-*.tar.zst --confirmEnsure your DNS has an A record for the root domain pointing to your ingress gateway.
-
Define a
PackageCR for your applicationAdd an
exposeentry to route traffic through a gateway. The UDS Operator creates the necessaryVirtualServiceandAuthorizationPolicyresources automatically.Expose on the tenant gateway for end-user traffic:
uds-package.yaml apiVersion: uds.dev/v1alpha1kind: Packagemetadata:name: my-appnamespace: my-appspec:network:expose:- service: my-app-serviceselector:app.kubernetes.io/name: my-apphost: my-appgateway: tenantport: 8080This exposes the application at
https://my-app.yourdomain.com, routing traffic to port 8080 on pods matching the selector.Expose on the admin gateway for admin-facing interfaces:
uds-package.yaml apiVersion: uds.dev/v1alpha1kind: Packagemetadata:name: my-appnamespace: my-appspec:network:expose:- service: my-app-adminselector:app.kubernetes.io/name: my-apphost: my-appgateway: adminport: 9090This exposes the application at
https://my-app.admin.yourdomain.com. Since the admin and tenant gateways are logically separated, you can apply different security controls to each (IP allowlisting, mTLS client certificates, etc.).Expose on the root (apex) domain (requires step 1):
uds-package.yaml apiVersion: uds.dev/v1alpha1kind: Packagemetadata:name: my-appnamespace: my-appspec:network:expose:- service: my-app-serviceselector:app.kubernetes.io/name: my-apphost: "."gateway: tenantport: 80The special
host: "."value routes traffic fromhttps://yourdomain.comto your application. -
(Optional) Configure advanced HTTP routing
Add an
advancedHTTPblock to an expose entry to configure routing rules like header manipulation, CORS policies, URI rewrites, redirects, retries, and timeouts. TheadvancedHTTPfields map directly to Istio VirtualService HTTPRoute; refer to the Istio docs for the full field reference.Example: Add response headers and configure retries
uds-package.yaml spec:network:expose:- service: my-app-serviceselector:app.kubernetes.io/name: my-apphost: my-appgateway: tenantport: 8080advancedHTTP:headers:response:add:strict-transport-security: "max-age=31536000; includeSubDomains"remove:- servertimeout: "30s"retries:attempts: 3perTryTimeout: "10s"retryOn: "5xx,reset,connect-failure"Example: CORS policy for a browser-consumed API
uds-package.yaml spec:network:expose:- service: my-apiselector:app.kubernetes.io/name: my-apihost: apigateway: tenantport: 8080advancedHTTP:corsPolicy:allowOrigins:- exact: "https://my-frontend.uds.dev"allowMethods:- GET- POSTallowHeaders:- Authorization- Content-TypeallowCredentials: truemaxAge: "86400s"All
advancedHTTPoptions are composable; you can combine match conditions, headers, CORS, retries, and timeouts in a single expose entry. See thePackageCR reference for the full list of supported fields. -
Deploy your application
(Recommended) Include the
PackageCR manifest in your Zarf package alongside your application’s Helm chart and create/deploy. See Packaging applications for general packaging guidance.Terminal window uds zarf package create --confirmuds zarf package deploy zarf-package-*.tar.zst --confirmOr apply the
PackageCR directly for quick testing:Terminal window uds zarf tools kubectl apply -f uds-package.yamlIf your application is part of a UDS Bundle, include the Zarf package in your bundle and deploy it with
uds createanduds deployinstead.
Verification
Section titled “Verification”Check that the Package CR was reconciled and shows the expected endpoints:
uds zarf tools kubectl get package my-app -n my-appThe ENDPOINTS column should show your application’s URL(s). Test access:
curl -v https://my-app.yourdomain.comTroubleshooting
Section titled “Troubleshooting”Problem: Service not reachable
Section titled “Problem: Service not reachable”Symptom: Browser or curl returns connection refused or timeout.
Solution:
- Verify the
PackageCR was reconciled:uds zarf tools kubectl get package my-app -n my-app(check theSTATUScolumn) - Ensure your DNS resolves the hostname to the gateway load balancer IP
Problem: Wrong gateway or domain
Section titled “Problem: Wrong gateway or domain”Symptom: Application accessible on an unexpected URL or not at all.
Solution:
- Check the
gatewayfield in yourPackageCR matches your intent (tenantoradmin) - Verify the
hostfield, which becomes the subdomain prefix (e.g.,host: my-appbecomesmy-app.yourdomain.com) - Check
shared.domainin youruds-config.yaml
Problem: Root domain not working
Section titled “Problem: Root domain not working”Symptom: Subdomains work but https://yourdomain.com does not.
Solution:
- Confirm
rootDomain.enabledis set totruein your bundle overrides - Verify DNS has an A record for the root domain (not just a wildcard)
- Check that TLS certificates are provided for the root domain configuration
Related documentation
Section titled “Related documentation”- Networking & Service Mesh Concepts - how the service mesh, gateways, and network policies work together in UDS Core
PackageCR Reference - full CR schema and field reference for network, SSO, and monitoring configuration- Enable the passthrough gateway - Deploy the optional passthrough gateway for apps that handle their own TLS.
- Define network access - Configure intra-cluster and external network access for your application.
- Create a custom gateway - Deploy a gateway with independent domain, TLS, and security controls.
- Istio VirtualService HTTPRoute - upstream reference for the full set of
advancedHTTPfields