Architecting Network Control: The Definitive Guide to UniFi Controller Deployment via Ansible

The administration of Ubiquiti UniFi networking ecosystems presents a distinct dichotomy in deployment strategies. For the administrator, the choice typically fluctuates between the procurement of proprietary hardware, such as the CloudKey—a dedicated appliance designed for those with the budget to offload management overhead—and the self-hosted installation of the UniFi Controller software on independent hardware. While the latter provides immense flexibility and cost savings, the manual installation and maintenance of the controller software are historically fraught with complexity. Traditional deployment methods often rely on monolithic bash scripts. These scripts, while functional, are frequently characterized by extreme complexity, making them difficult to audit and prone to catastrophic failure during operating system upgrades. When a host OS is updated, the rigid logic of a bash script often breaks, requiring the administrator to wait for community-maintained updates or manually debug the code.

Ansible emerges as the professional alternative to these fragile scripts. By leveraging an idempotent, declarative approach, Ansible allows network engineers to define the desired state of the UniFi Controller—including its dependencies, repository configurations, and service states—without the risk of "script rot." This transition from imperative bash scripting to declarative automation ensures that the deployment is repeatable, readable, and maintainable. Whether deploying to a fresh Ubuntu installation using a "cattle" infrastructure philosophy—where servers are treated as disposable and easily replaceable—or managing a long-term stable host, Ansible provides the precision required to handle the specific dependencies of the UniFi stack, such as Java and MongoDB.

The Technical Anatomy of UniFi Controller Dependencies

The UniFi Controller does not operate as a standalone binary but relies on a specific stack of software prerequisites. Failure to align these versions exactly can lead to service instability or a total failure of the controller to boot.

The following table details the critical software dependencies required for a successful deployment:

Dependency Version/Component Purpose
Java OpenJDK 8 JRE Headless The primary runtime environment for the controller application.
Database MongoDB (e.g., 3.4) Used for data persistence, configuration storage, and device tracking.
MongoDB Tools mongodb-org-tools, shell, server Essential utilities for database management and interaction.
Security libssl1.0.0 Required for legacy SSL support in specific Ubuntu versions.
Network Tools curl, ca-certificates Used for fetching remote repositories and verifying SSL certificates.
System Utils jsvc, tar, apt-transport-https Necessary for service wrapping and secure package transportation.

The requirement for OpenJDK 8 is a critical technical constraint. While newer versions of Java exist, the UniFi Controller's architecture is specifically tuned for Java 8. Using a headless JRE (Java Runtime Environment) is the optimal choice for server deployments as it removes the overhead of a Graphical User Interface (GUI), reducing the attack surface and resource consumption.

MongoDB 3.4 is specifically cited as a stable version for these deployments. Because MongoDB's installation process involves adding external GPG keys and specific repositories, managing this via Ansible ensures that the apt package manager is correctly configured before the installation attempt begins. This prevents the common "package not found" errors encountered during manual installations.

Detailed Ansible Deployment Workflow

A professional deployment of the UniFi Controller using Ansible involves a series of orchestrated tasks designed to move the system from a "vanilla" state to a fully operational network controller.

The execution flow begins with the configuration of the control node. For an environment running Ubuntu 20.04 LTS with Ansible 2.14.0, the initial setup requires the installation of the Python package manager:

sudo apt install python3-pip -y

Following the installation of pip, the Ansible environment is established. While a simple pip install ansible suffices for basic needs, a comprehensive setup utilizing a requirements.txt file allows for the inclusion of critical linting tools such as ansible-lint and yamllint, which ensure the playbooks adhere to industry standards.

The deployment process follows these specific technical stages:

  • Repository Configuration
    The Ansible playbook must first establish trust with the Ubiquiti and MongoDB servers. This is achieved using the apt_key module to import the GPG keys from https://dl.ui.com/unifi/unifi-repo.gpg and the MongoDB server keys. Once trust is established, the apt_repository module adds the official Debian stable ubiquiti repository (deb https://www.ui.com/downloads/unifi/debian stable ubiquiti) and the MongoDB repository. This ensures that all software is sourced from official channels rather than third-party mirrors.

  • Dependency Installation
    Once the repositories are active, Ansible triggers the installation of the Java and MongoDB packages. The use of variables, such as java_pkgs and mongoDB_pkgs, allows the administrator to update versions across the entire fleet by changing a single value in a vars.yml file.

  • Handling Legacy Libraries
    In some Ubuntu environments, specifically those moving toward newer releases, the libssl1.0.0 library is missing. To resolve this, the Ansible playbook can be configured to download the .deb package from a secure Ubuntu pool:

http://security.ubuntu.com/ubuntu/pool/main/o/openssl1.0.0/libssl1.0.0_1.0.2n-1ubuntu5.3_amd64.deb

The playbook saves this file to /tmp/libssl1.0.0.deb before installing it, ensuring the controller has the legacy SSL support it requires to communicate with older hardware.

  • Final Controller Deployment
    The final step is the installation of the unifi package itself. Because Ansible is idempotent, re-running the playbook will check for newer versions of the software and update the controller if a newer release is available in the repository.

Post-Deployment Management and Operational Commands

Once the Ansible playbook has successfully executed, the controller is hosted on the server and accessible via a web browser. The standard access point is:

https://HOST-IP:8043/

To maintain the health of the service, administrators must use the following system commands to manage the controller process:

  • To check if the service is currently active and running:
    sudo service unifi status

  • To apply configuration changes or recover from a hang:
    sudo service unifi restart

  • To gracefully shut down the controller for maintenance:
    sudo service unifi stop

For those utilizing the kdpuvvadi/unifi GitHub repository for their deployment, the workflow involves several preparatory steps to align the environment variables and inventory:

  • Cloning the source code:
    git clone https://github.com/kdpuvvadi/unifi.git unifi

  • Installing necessary Ansible collections:
    ansible-galaxy collection install -r requirements.yml

  • Preparing the inventory and variable files from templates:
    cp inventory.ini.j2 inventory.ini
    cp vars.yml.j2 vars.yml

  • Executing the playbook with sudo password elevation:
    ansible-playbook main.yml -K

Advanced Network Automation and API Integration

Beyond simple installation, Ansible can be used to interact with the UniFi OS Server to perform active network management. This represents a shift from "Installation Automation" to "Configuration Automation."

The UniFi OS Server acts as a comprehensive self-hosted stack. By utilizing the uri module in Ansible, administrators can authenticate with the controller and send commands directly to the network hardware.

Authentication is the first critical step. The following YAML structure demonstrates how to log into the controller and capture the session cookie for subsequent requests:

yaml - name: Provisioning (Authenticating) uri: url: https://unifi.REDACTED.local:8443/api/login method: POST validate_certs: false body_format: json body: '{"username": "Sfascia17", "password": "REDACTED"}' register: logincookie

Once the logincookie is registered, it can be passed into other API calls. For example, to force a USG (UniFi Security Gateway) to provision a new config.gateway.json file, the following task is used:

yaml - name: force-provision uri: url: https://unifi.REDACTED.local:8443/api/s/default/cmd/devmgr method: POST validate_certs: false body_format: json body: '{"mac":"xx:xx:xx:xx:xx:xx","cmd":"force-provision"}' headers: Cookie: "{{ logincookie.cookies_string }}"

This level of automation prevents "setting drift," which occurs when manual changes are made to the network that are not documented in the configuration files. By keeping the configuration files alongside the Ansible playbooks in a Git repository, the administrator ensures that the source of truth is always version-controlled.

Infrastructure Philosophy: Cattle vs. Pets

The approach to deploying the UniFi Controller via Ansible highlights a fundamental shift in infrastructure philosophy. Traditional bash-scripted installations often lead to "Pet" servers—systems that are uniquely configured over time, become undocumented, and are feared by administrators because they cannot be easily recreated.

The Ansible-driven approach promotes the "Cattle" methodology. In this paradigm, the server is viewed as a commodity. If a system becomes unstable or the OS requires a major upgrade, the administrator does not spend hours troubleshooting "cruft" or manual configurations. Instead, they deploy a fresh Ubuntu installation and run the Ansible playbook. This ensures a clean, predictable, and fully documented state every time.

This philosophy extends to the use of Virtual Machines. For those using KVM (Kernel-based Virtual Machine), the transition to an Ansible-managed deployment allows for a generalized playbook that works across different cloud-base images, such as Fedora Server and Ubuntu Server. This removes the reliance on specific Cloud-Init configurations that may only work for a single distribution.

Strategic Handling of Certificates and Security

A common gap in automated deployment scripts is the management of SSL certificates. While some scripts attempt to bundle Let's Encrypt management, a more robust architectural decision is to offload certificate handling to a dedicated reverse proxy.

In a professional production environment, the following certificate management flow is recommended:

  1. Setup the certificate request and automatic renewal on a reverse proxy (e.g., Nginx, Traefik, or HAProxy).
  2. The reverse proxy handles the ACME challenge and manages the valid certificates.
  3. Use Ansible or a recurring cron job to copy the valid certificate from the proxy to the UniFi server.
  4. Trigger a restart of the UniFi services via Ansible to apply the new certificates.

This separation of concerns ensures that the UniFi Controller does not need to manage its own DNS challenges or interact directly with Let's Encrypt, reducing the complexity of the controller's internal configuration.

Conclusion

The deployment of the UniFi Controller via Ansible transforms a burdensome manual process into a streamlined, professional operation. By replacing fragile bash scripts with a declarative YAML-based approach, administrators gain total visibility into the installation process. The use of specific GPG keys for Ubiquiti and MongoDB, the precise selection of OpenJDK 8, and the handling of legacy libraries like libssl1.0.0 create a stable environment that is resistant to the failures common in manual setups.

Furthermore, the ability to integrate with the UniFi API allows for the automation of hardware provisioning and the elimination of setting drift. By treating the controller host as "cattle" and utilizing Git for version control of both the playbooks and the network configurations, the network engineer ensures that the entire infrastructure is reproducible. This methodology not only reduces the risk of network downtime—a critical concern when using powerful tools like Ansible—but also provides a scalable framework for managing increasingly complex Ubiquiti ecosystems.

Sources

  1. Kalfeher - Unifi Controller Software with Ansible
  2. GitHub - kdpuvvadi/unifi
  3. XDA-Developers - Automated my entire home network with Ansible
  4. Oxcrag - Deploying a Ubiquiti Appliance with Ansible

Related Posts