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 theapt_keymodule to import the GPG keys fromhttps://dl.ui.com/unifi/unifi-repo.gpgand the MongoDB server keys. Once trust is established, theapt_repositorymodule 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 asjava_pkgsandmongoDB_pkgs, allows the administrator to update versions across the entire fleet by changing a single value in avars.ymlfile.Handling Legacy Libraries
In some Ubuntu environments, specifically those moving toward newer releases, thelibssl1.0.0library is missing. To resolve this, the Ansible playbook can be configured to download the.debpackage 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 theunifipackage 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 statusTo apply configuration changes or recover from a hang:
sudo service unifi restartTo 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 unifiInstalling necessary Ansible collections:
ansible-galaxy collection install -r requirements.ymlPreparing the inventory and variable files from templates:
cp inventory.ini.j2 inventory.ini
cp vars.yml.j2 vars.ymlExecuting 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:
- Setup the certificate request and automatic renewal on a reverse proxy (e.g., Nginx, Traefik, or HAProxy).
- The reverse proxy handles the ACME challenge and manages the valid certificates.
- Use Ansible or a recurring cron job to copy the valid certificate from the proxy to the UniFi server.
- 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.