diff --git a/playbooks/unifi_controller.yml b/playbooks/unifi_controller.yml new file mode 100644 index 0000000..c97babd --- /dev/null +++ b/playbooks/unifi_controller.yml @@ -0,0 +1,7 @@ +--- +- name: Deploy unifi controller + hosts: "{{ unifi_controller_hosts | default('unifi_controller') }}" + become: "{{ unifi_controller_become | default(false) }}" + gather_facts: "{{ unifi_controller_gather_facts | default(false) }}" + roles: + - role: finallycoffee.services.unifi_controller diff --git a/roles/unifi_controller/README.md b/roles/unifi_controller/README.md new file mode 100644 index 0000000..8849c67 --- /dev/null +++ b/roles/unifi_controller/README.md @@ -0,0 +1,16 @@ +# `finallycoffee.services.unifi_controller` ansible role + +Deploy [`jacobalberty/unifi-docker`](https://github.com/jacobalberty/unifi-docker) +using either `docker` or `podman` (configure using +`unifi_controller_deployment_method`). + +## Configuration + +Change the default bind IP of `::` by setting +`unifi_controller_bind_ip`. By default, the ports +`1900/udp` (SSDP), `3478/udp` (STUN), `10001/udp`, +`8080/tcp` (HTTP), `8443/tcp` (HTTPS) and `6789/tcp` +are exposed. + +For more information on which ports are needed when, see +[Unifi's required ports reference](https://help.ui.com/hc/en-us/articles/218506997-Required-Ports-Reference). diff --git a/roles/unifi_controller/defaults/main/container.yml b/roles/unifi_controller/defaults/main/container.yml new file mode 100644 index 0000000..e7729c4 --- /dev/null +++ b/roles/unifi_controller/defaults/main/container.yml @@ -0,0 +1,41 @@ +--- +unifi_controller_container_name: "unifi-controller" +unifi_controller_container_image_registry: "docker.io" +unifi_controller_container_image_namespace: "jacobalberty" +unifi_controller_container_image_repository: "unifi" +unifi_controller_container_image_tag: ~ +unifi_controller_container_image_name: >-2 + {{ [ + unifi_controller_container_image_registry | default([]), + unifi_controller_container_image_namespace | default([]), + unifi_controller_container_image_repository + ] | flatten | join('/') }} +unifi_controller_container_image: >-2 + {{ [ + unifi_controller_container_image_name, + unifi_controller_container_image_tag | default('v' + unifi_controller_version, true) + ] | join(':') }} +unifi_controller_container_image_source: "pull" +unifi_controller_container_image_force_source: >-2 + {{ unifi_controller_container_image_tag | default(false, true) | bool }} +unifi_controller_container_image_pull: >-2 + {{ unifi_controller_container_image_source == 'pull' }} +unifi_controller_container_image_force_pull: >-2 + {{ unifi_controller_container_image_pull and unifi_controller_container_image_force_source }} +unifi_controller_container_ports: + - "{{ unifi_controller_bind_ip }}:8080:8080/tcp" # HTTP: device + app communication + - "{{ unifi_controller_bind_ip }}:8443:8443/tcp" # HTTPS: app web page + API + - "{{ unifi_controller_bind_ip }}:1900:1900/udp" # SSDP: layer 2 discovery + - "{{ unifi_controller_bind_ip }}:3478:3478/udp" # STUN: device adoption and communication + - "{{ unifi_controller_bind_ip }}:10001:10001/udp" # device discovery (during adoption) +unifi_controller_container_user: >-2 + {{ unifi_controller_run_uid }}:{{ unifi_controller_run_gid }} +unifi_controller_container_restart_policy: "on-failure" +unifi_controller_container_default_volumes: + - "{{ unifi_controller_base_path }}:/unifi:rw" +unifi_controller_container_volumes: [] +unifi_controller_container_merged_volumes: >-2 + {{ unifi_controller_container_default_volumes | default([]) + + unifi_controller_container_volumes | default([]) }} +unifi_controller_container_state: >-2 + {{ (unifi_controller_state == 'present') | ternary('started', 'absent') }} diff --git a/roles/unifi_controller/defaults/main/main.yml b/roles/unifi_controller/defaults/main/main.yml new file mode 100644 index 0000000..98bffea --- /dev/null +++ b/roles/unifi_controller/defaults/main/main.yml @@ -0,0 +1,9 @@ +--- +unifi_controller_version: "9.4.19" +unifi_controller_base_path: "/var/lib/unifi-controller" +unifi_controller_log_path: "{{ unifi_controller_base_path }}/log" +unifi_controller_data_path: "{{ unifi_controller_base_path }}/data" +unifi_controller_bind_ip: "::" + +unifi_controller_state: "present" +unifi_controller_deployment_method: "docker" diff --git a/roles/unifi_controller/defaults/main/user.yml b/roles/unifi_controller/defaults/main/user.yml new file mode 100644 index 0000000..eb12e72 --- /dev/null +++ b/roles/unifi_controller/defaults/main/user.yml @@ -0,0 +1,8 @@ +--- +unifi_controller_user: unifi +unifi_controller_user_create_home: false +unifi_controller_user_system: true +unifi_controller_run_uid: >-2 + {{ unifi_controller_user_info.uid | default(unifi_controller_user) }} +unifi_controller_run_gid: >-2 + {{ unifi_controller_user_info.group | default(unifi_controller_user) }} diff --git a/roles/unifi_controller/meta/main.yml b/roles/unifi_controller/meta/main.yml new file mode 100644 index 0000000..5edb793 --- /dev/null +++ b/roles/unifi_controller/meta/main.yml @@ -0,0 +1,11 @@ +--- +allow_duplicates: true +dependencies: [] +galaxy_info: + role_name: unifi_controller + description: Ansible role to deploy unifi (network) controller in a container + galaxy_tags: + - unifi + - unifi_controller + - docker + - podman diff --git a/roles/unifi_controller/tasks/deploy-docker.yml b/roles/unifi_controller/tasks/deploy-docker.yml new file mode 100644 index 0000000..631770b --- /dev/null +++ b/roles/unifi_controller/tasks/deploy-docker.yml @@ -0,0 +1,17 @@ +--- +- name: Ensure container image '{{ unifi_controller_container_image }}' is {{ unifi_controller_state }} + community.docker.docker_image: + name: "{{ unifi_controller_container_image }}" + state: "{{ unifi_controller_state }}" + source: "{{ unifi_controller_container_image_source }}" + force_source: "{{ unifi_controller_container_image_force_source }}" + +- name: Ensure container '{{ unifi_controller_container_name }}' is {{ unifi_controller_container_state }} + community.docker.docker_container: + name: "{{ unifi_controller_container_name }}" + image: "{{ unifi_controller_container_image }}" + user: "{{ unifi_controller_container_user }}" + ports: "{{ unifi_controller_container_ports }}" + volumes: "{{ unifi_controller_container_merged_volumes }}" + restart_policy: "{{ unifi_controller_container_restart_policy }}" + state: "{{ unifi_controller_container_state }}" diff --git a/roles/unifi_controller/tasks/deploy-podman.yml b/roles/unifi_controller/tasks/deploy-podman.yml new file mode 100644 index 0000000..0f957d0 --- /dev/null +++ b/roles/unifi_controller/tasks/deploy-podman.yml @@ -0,0 +1,17 @@ +--- +- name: Ensure container image '{{ unifi_controller_container_image }}' is {{ unifi_controller_state }} + containers.podman.podman_image: + name: "{{ unifi_controller_container_image }}" + state: "{{ unifi_controller_state }}" + pull: "{{ unifi_controller_container_image_pull }}" + force: "{{ unifi_controller_container_image_force_pull }}" + +- name: Ensure container '{{ unifi_controller_container_name }}' is {{ unifi_controller_container_state }} + containers.podman.podman_container: + name: "{{ unifi_controller_container_name }}" + image: "{{ unifi_controller_container_image }}" + user: "{{ unifi_controller_container_user }}" + ports: "{{ unifi_controller_container_ports }}" + volumes: "{{ unifi_controller_container_merged_volumes }}" + restart_policy: "{{ unifi_controller_container_restart_policy }}" + state: "{{ unifi_controller_container_state }}" diff --git a/roles/unifi_controller/tasks/main.yml b/roles/unifi_controller/tasks/main.yml new file mode 100644 index 0000000..95d2641 --- /dev/null +++ b/roles/unifi_controller/tasks/main.yml @@ -0,0 +1,18 @@ +--- +- name: Ensure unifi controller run user '{{ unifi_controller_user }}' is {{ unifi_controller_state }} + ansible.builtin.user: + name: "{{ unifi_controller_user }}" + state: "{{ unifi_controller_state }}" + register: unifi_controller_user_info + +- name: Ensure unifi controller base path '{{ unifi_controller_base_path }}' is {{ unifi_controller_state }} + ansible.builtin.file: + path: "{{ unifi_controller_base_path }}" + state: "{{ (unifi_controller_state == 'present') | ternary('directory', 'absent') }}" + owner: "{{ unifi_controller_run_uid }}" + group: "{{ unifi_controller_run_gid }}" + mode: "0755" + +- name: Deploy unifi controller with {{ unifi_controller_deployment_method }} + ansible.builtin.include_tasks: + file: "deploy-{{ unifi_controller_deployment_method }}.yml" diff --git a/roles/unifi_controller/vars/main.yml b/roles/unifi_controller/vars/main.yml new file mode 100644 index 0000000..b932c84 --- /dev/null +++ b/roles/unifi_controller/vars/main.yml @@ -0,0 +1,7 @@ +--- +unifi_controller_states: + - "present" + - "absent" +unifi_controller_deployment_methods: + - "docker" + - "podman"