Skip to content

Deploy to Production

  1. Run the deploy command

    Terminal window
    uds deploy uds-bundle-my-uds-core-*.tar.zst --confirm

    If you are using a uds-config.yaml for variables, it is picked up automatically from the current directory. You can also specify it explicitly:

    Terminal window
    UDS_CONFIG=uds-config.yaml uds deploy uds-bundle-my-uds-core-*.tar.zst --confirm
  2. Watch the rollout

    In a separate terminal, monitor the deployment as packages come up:

    Terminal window
    watch kubectl get pods -A

    Or use k9s:

    Terminal window
    uds zarf tools monitor

    Deployment order follows the package order in your bundle. The init package comes first (Zarf registry, agent), followed by core.

    Full deployment time varies based on cluster resources and image pull speed. Expect 10–30 minutes for a first deployment to a fresh cluster.


  1. Check pod health

    Terminal window
    # All pods should be Running or Completed
    kubectl get pods -A --no-headers | grep -Ev '(Running|Completed)'

    Any pods stuck in Pending, CrashLoopBackOff, or Error state indicate a problem. See Common Issues below.

  2. Confirm namespaces

    Terminal window
    kubectl get namespaces

    Expected namespaces:

    NamespaceComponent
    istio-systemIstio control plane
    istio-tenant-gatewayTenant ingress gateway
    istio-admin-gatewayAdmin ingress gateway
    keycloakKeycloak identity provider
    authserviceAuthservice SSO for mission applications
    monitoringPrometheus, Alertmanager, Blackbox Exporter
    grafanaGrafana
    loggingLoki log storage
    vectorVector log aggregation
    veleroVelero backup controller
    falcoFalco runtime security
    pepr-systemUDS Operator (Pepr)
  3. Verify Istio gateways

    Terminal window
    kubectl get svc -n istio-tenant-gateway
    kubectl get svc -n istio-admin-gateway

    Both LoadBalancer services should have an EXTERNAL-IP assigned. If they show <pending>, your load balancer provisioner may not be configured correctly.

  4. Configure DNS records

    Now that the gateways have external IPs, create (or update) your wildcard DNS records to point to them:

    RecordTypeValue
    *.yourdomain.comA (or CNAME)Tenant gateway EXTERNAL-IP
    *.admin.yourdomain.comA (or CNAME)Admin gateway EXTERNAL-IP
  5. Access the admin UIs

    Once DNS is resolving to your load balancer, access:

    ServiceURL
    Keycloakhttps://keycloak.<your-admin-domain>
    Grafanahttps://grafana.<your-admin-domain>

    The Keycloak admin console login verifies that identity and ingress are working end-to-end.


Usually indicates insufficient cluster resources or a missing storage class.

Terminal window
kubectl describe pod <pod-name> -n <namespace>

Look for Insufficient cpu, Insufficient memory, or no persistent volumes available in the events.

Often caused by incorrect object storage credentials or unreachable storage endpoint. Check the pod logs:

Terminal window
kubectl logs -n logging -l app.kubernetes.io/name=loki --tail=50
kubectl logs -n velero -l app.kubernetes.io/name=velero --tail=50

Istio gateway EXTERNAL-IP stuck in <pending>

Section titled “Istio gateway EXTERNAL-IP stuck in <pending>”

Your load balancer provisioner is not assigning IPs. Verify the provisioner is installed and configured in your cluster. For on-premises deployments, ensure MetalLB or kube-vip is running and has an IP pool configured.

Check that:

  1. The Keycloak pod is Running: kubectl get pods -n keycloak
  2. DNS resolves to the load balancer IP
  3. The TLS certificate is valid for your admin domain

If Keycloak is running but crashing on startup, check the logs for database connection errors:

Terminal window
kubectl logs -n keycloak -l app.kubernetes.io/name=keycloak --tail=50

Common causes: incorrect hostname, wrong credentials, database user lacks privileges, or the database server is not reachable from the cluster. Verify the values in your uds-config.yaml match what was provisioned in the Provision External Services step.


Congratulations — you’ve completed the UDS Core production deployment tutorial. You’ve provisioned the external services, built a production bundle, and deployed UDS Core to your cluster.

Here’s what you’ve stood up:

  • Istio service mesh with admin and tenant ingress gateways, TLS-terminated with your certificates
  • Keycloak identity provider backed by an external database
  • Authservice providing SSO flows for your mission applications
  • Loki log storage with Vector for log aggregation, backed by persistent object storage
  • Velero cluster backups configured to your storage backend
  • Prometheus, Grafana, Alertmanager for platform observability
  • Falco for runtime security

From here, explore the How-To Guides for topics like configuring log retention, setting up SSO, and managing policy exemptions. To configure high availability for UDS Core components, see the High Availability Overview.