It's been a while since I set up my UniFi controller and it's about time to move to a bigger box. This time I want to set it up using Ansible so I don't have to do all the research again when I want to move it again.
There are third-party docker containers available that have the UniFi controller in them, but I want the UniFi controller updated as soon as possible so I'm installing natively.
I'm using Debian 12 for this recap because Ubuntu is pushing their snaps a bit too hard.
There are a few steps to go from a blank system to a UniFi controller:
First we want to update and upgrade the installed system packages, easy since there's a builtin for apt.
- name: Update and upgrade apt packages
become: true
apt:
upgrade: yes
update_cache: yes
There's official instructions for this at the UniFi help site but there's some caveats to how they do it that I don't like:
apt-key
is deprecated/etc/apt/trusted.gpg.d
is insecure.With all of those in mind, we'll add the keyring to another folder and use the new sources list.
- name: Ensure dependencies for using apt repo over HTTPS are installed
become: true
ansible.builtin.apt:
name: "{{ item }}"
state: present
loop:
- ca-certificates
- apt-transport-https
- name: Add UniFi apt key
become: true
ansible.builtin.get_url:
url: https://dl.ui.com/unifi/unifi-repo.gpg
dest: /etc/apt/keyrings/unifi-repo.gpg
mode: '0644'
- name: Add unifi repository to apt
become: true
ansible.builtin.deb822_repository:
name: 100-ubnt-unifi
types: deb
architectures:
- amd64
- arm64
uris: https://www.ui.com/downloads/unifi/debian
suites: stable
components: ubiquiti
signed_by: /etc/apt/keyrings/unifi-repo.gpg
The UniFi install docs have us installing the ancient MongoDB 3.6. Eww. UniFi 9.0+ supports the latest (at writing) MongoDB 8.0 so we'll be installing that.
This somewhat mirrors the official MongoDB docs barring some slight changes to put the gpg key next to where we put the UniFi key.
Once we've installed MongoDB we'll install UniFi and make sure both are running and set to start at boot.
- name: Add MongoDB apt key
become: true
ansible.builtin.get_url:
url: https://www.mongodb.org/static/pgp/server-8.0.asc
dest: /etc/apt/keyrings/mongodb-server-8.0.asc
mode: '0644'
- name: Add mongodb repository to apt
become: true
ansible.builtin.deb822_repository:
name: mongodb-org-8.0
types: deb
uris: http://repo.mongodb.org/apt/debian
suites: bookworm/mongodb-org/8.0
components: main
signed_by: /etc/apt/keyrings/mongodb-server-8.0.asc
# install
- name: Install
become: true
ansible.builtin.apt:
update_cache: true
name: "{{ item }}"
state: present
loop:
- mongodb-org
- unifi
- name: Ensure services start on boot
become: true
ansible.builtin.service:
name: "{{ item }}"
state: started
enabled: true
loop:
- mongod
- unifi
2 big parts here in a single section.
First up is installing certbot, for which we'll use the OS packages rather than installing from pip.
Second up we'll issue a certificate, for which we'll use DNS validation so we can serve other things on the 80/443 of this server.
We're going to register without an email since they're not sending out expiration notices anymore.
You'll want to produce a template file with your DNS credentials and place it in the templates
directory relative to this playbook.
- name: Install certbot
become: true
ansible.builtin.apt:
name: "{{ item }}"
state: present
loop:
- python3-certbot
- python3-certbot-dns-cloudflare
- cron
- name: Copy certbot dns credentials
ansible.builtin.template:
dest: ~/cfdnscreds.ini
src: templates/cfdnscreds.ini
mode: '0600'
- name: Create a certificate
ansible.builtin.command:
argv:
- sudo
- certbot
- certonly
- --noninteractive
- --agree-tos
- --register-unsafely-without-email
- -d
- <your domain>
- --dns-cloudflare
- --dns-cloudflare-credentials
- ~/cfdnscreds.ini
- name: Add autorenew certbot crontab entry
ansible.builtin.cron:
name: "certbot renew"
minute: 38
hour: 0,12
job: sudo certbot renew -q
This section relies on a script created by Steve Jenkins, which takes care of loading our cert into the UniFi keystore so it can serve HTTPS directly. Download this script and modify the config options at the top to fit your environment, uncommenting the "Debian/Ubuntu" section.
This section doesn't actually run the script, it just sets it up to be run. You can run it manually if you want to confirm that it's all working before you let it go.
- name: Copy unifi dns certificate helper
ansible.builtin.template:
dest: ~/unifi_ssl_import.sh
src: templates/unifi_ssl_import.sh
mode: '0700'
- name: Add cron entry for unifi sll import
become: true
ansible.builtin.cron:
name: "unifi ssl import"
user: root
minute: 45
hour: 0,12
job: /home/<your user>/unifi_ssl_import.sh
This was a fun side task and helped me learn a bit more about Ansible and apt. I welcome your feedback and hope this helps you set up an Ansible playbook that sets up a UniFi controller.