From b4e8b5f82e942dc5861198d26d19edc3d273b7c2 Mon Sep 17 00:00:00 2001 From: Jonas Gunz Date: Thu, 15 Feb 2024 23:01:26 +0100 Subject: netbox --- roles/netbox/Readme.md | 53 +++++++++++ roles/netbox/defaults/main.yaml | 42 +++++++++ roles/netbox/handlers/main.yaml | 22 +++++ roles/netbox/tasks/main.yaml | 146 +++++++++++++++++++++++++++++ roles/netbox/tasks/postgres.yaml | 59 ++++++++++++ roles/netbox/templates/configuration.py.j2 | 18 ++++ roles/netbox/templates/gunicorn.py.j2 | 18 ++++ 7 files changed, 358 insertions(+) create mode 100644 roles/netbox/Readme.md create mode 100644 roles/netbox/defaults/main.yaml create mode 100644 roles/netbox/handlers/main.yaml create mode 100644 roles/netbox/tasks/main.yaml create mode 100644 roles/netbox/tasks/postgres.yaml create mode 100644 roles/netbox/templates/configuration.py.j2 create mode 100644 roles/netbox/templates/gunicorn.py.j2 (limited to 'roles') diff --git a/roles/netbox/Readme.md b/roles/netbox/Readme.md new file mode 100644 index 0000000..8c2cedc --- /dev/null +++ b/roles/netbox/Readme.md @@ -0,0 +1,53 @@ +# netbox + +as standard as possible according to the docs. + +A correct reverse proxy config is needed as well. +See docs for details. + +Example config: + +```yaml +--- +netbox_version: '3.7.2' +netbox_local_postgres: true +netbox_config: + CSRF_TRUSTED_ORIGINS: + - 'https://{{ ansible_facts.fqdn }}' + ALLOWED_HOSTS: + - '{{ ansible_facts.fqdn }}' + DATABASE: + NAME: netbox + USER: netbox + PASSWORD: '{{ postgres_netbox_db_key }}' + HOST: localhost + PORT: '' + CONN_MAX_AGE: 300 + REDIS: + tasks: + HOST: localhost + PORT: 6379 + PASSWORD: '' + DATABASE: 0 + SSL: false + caching: + HOST: localhost + PORT: 6379 + PASSWORD: '' + DATABASE: 1 + SSL: false + SECRET_KEY: '{{ sec_key.content | b64decode }}' + +gunicorn_config: + bind: '127.0.0.1:8001' + workers: 5 + threads: 3 + timeout: 120 + max_requests: 5000 + max_requests_jitter: 500 + +ldap_enable: false +# This has to be a Multiline String, because we need to define +# native Python-datatypes here and this is a hell to template. +ldap_config: '' +``` diff --git a/roles/netbox/defaults/main.yaml b/roles/netbox/defaults/main.yaml new file mode 100644 index 0000000..799de8b --- /dev/null +++ b/roles/netbox/defaults/main.yaml @@ -0,0 +1,42 @@ +--- +netbox_version: '3.7.2' +netbox_local_postgres: true +netbox_config: + CSRF_TRUSTED_ORIGINS: + - 'https://{{ ansible_facts.fqdn }}' + ALLOWED_HOSTS: + - '{{ ansible_facts.fqdn }}' + DATABASE: + NAME: netbox + USER: netbox + PASSWORD: '{{ postgres_netbox_db_key }}' + HOST: localhost + PORT: '' + CONN_MAX_AGE: 300 + REDIS: + tasks: + HOST: localhost + PORT: 6379 + PASSWORD: '' + DATABASE: 0 + SSL: false + caching: + HOST: localhost + PORT: 6379 + PASSWORD: '' + DATABASE: 1 + SSL: false + SECRET_KEY: '{{ sec_key.content | b64decode }}' + +gunicorn_config: + bind: '127.0.0.1:8001' + workers: 5 + threads: 3 + timeout: 120 + max_requests: 5000 + max_requests_jitter: 500 + +ldap_enable: false +# This has to be a Multiline String, because we need to define +# native Python-datatypes here and this is a hell to template. +ldap_config: '' diff --git a/roles/netbox/handlers/main.yaml b/roles/netbox/handlers/main.yaml new file mode 100644 index 0000000..a22359e --- /dev/null +++ b/roles/netbox/handlers/main.yaml @@ -0,0 +1,22 @@ +--- +- name: Handle systemd + systemd: + name: netbox + state: restarted + become: true + +- name: Daemon reload + systemd: + daemon_reload: true + become: true + +- name: Enable units + systemd: + name: '{{ item }}' + enabled: true + state: started + become: true + loop: + - netbox-rq.service + - netbox.service + - netbox-housekeeping.timer diff --git a/roles/netbox/tasks/main.yaml b/roles/netbox/tasks/main.yaml new file mode 100644 index 0000000..9238cc0 --- /dev/null +++ b/roles/netbox/tasks/main.yaml @@ -0,0 +1,146 @@ +--- +- name: Install packages + apt: + name: + - redis-server + - python3 + - python3-pip + - python3-venv + - python3-dev + - build-essential + - libxml2-dev + - libxslt1-dev + - libffi-dev + - libpq-dev + - libssl-dev + - zlib1g-dev + # LDAP + - libldap2-dev + - libsasl2-dev + - libssl-dev + become: true + +- name: Create User + user: + name: netbox + system: true + become: true + +- name: Create folder + file: + path: /opt/netbox_data + owner: netbox + state: directory + become: true + +- name: Generate SECRET_KEY + command: + cmd: 'bash -c "dd if=/dev/urandom bs=1 count=50 status=none | base64"' + creates: /opt/netbox_data/secret_key + become_user: netbox + become: true + register: gen_sec_key + +- name: Save secret Key + copy: + content: '{{ gen_sec_key.stdout }}' + dest: /opt/netbox_data/secret_key + owner: root + group: netbox + mode: '640' + become: true + when: gen_sec_key.changed + +- name: Read secret Key + slurp: + src: /opt/netbox_data/secret_key + become: true + register: sec_key + +- name: Install PostgreSQL + include_tasks: postgres.yaml + when: netbox_local_postgres + +- name: Download netbox + get_url: + url: 'https://github.com/netbox-community/netbox/archive/refs/tags/v{{ netbox_version }}.tar.gz' + dest: '/opt/netbox_data/netbox_{{ netbox_version }}.tar.gz' + become: true + become_user: netbox + register: archive_download + notify: + - Handle systemd + +- name: Unpack netbox + unarchive: + src: '/opt/netbox_data/netbox_{{ netbox_version }}.tar.gz' + remote_src: true + dest: '/opt/netbox_data/' + become: true + become_user: netbox + when: archive_download.changed + +- name: create link to right version + file: + state: link + path: /opt/netbox + src: '/opt/netbox_data/netbox-{{ netbox_version }}' + become: true + +- name: Create the configuration + template: + src: configuration.py.j2 + dest: /opt/netbox/netbox/netbox/configuration.py + owner: netbox + become: true + notify: + - Handle systemd + +- name: Add LDAP dependencies to requirements.txt + copy: + content: 'django-auth-ldap' + dest: /opt/netbox/local_requirements.txt + owner: netbox + become: true + +- name: Install LDAP Configuration + copy: + dest: /opt/netbox/netbox/netbox/ldap_config.py + content: '{{ ldap_config }}' + owner: netbox + become: true + when: ldap_enable + notify: + - Handle systemd + +- name: Install Gunicorn Configuration file + template: + src: gunicorn.py.j2 + dest: '/opt/netbox/gunicorn.py' + owner: netbox + become: true + notify: + - Handle systemd + +- name: Install Gunicorn Unit files + copy: + remote_src: true + src: '/opt/netbox/contrib/{{ item }}' + dest: '/etc/systemd/system/{{ item }}' + become: true + loop: + - netbox-housekeeping.service + - netbox-rq.service + - netbox.service + - netbox-housekeeping.timer + notify: + - Handle systemd + - Daemon reload + - Enable units + +- name: Run the upgrade script + command: + cmd: /opt/netbox/upgrade.sh + become: true + become_user: netbox + when: archive_download.changed diff --git a/roles/netbox/tasks/postgres.yaml b/roles/netbox/tasks/postgres.yaml new file mode 100644 index 0000000..405ed71 --- /dev/null +++ b/roles/netbox/tasks/postgres.yaml @@ -0,0 +1,59 @@ +--- +- name: Generate Database Password + command: + cmd: 'bash -c "dd if=/dev/urandom bs=1 count=50 status=none | base64"' + creates: /opt/netbox_data/db_key + become_user: netbox + become: true + register: gen_db_key + +- name: Save DB Key + copy: + content: '{{ gen_sec_key.stdout }}' + dest: /opt/netbox_data/db_key + owner: root + group: netbox + mode: '640' + become: true + when: gen_db_key.changed + +- name: Read DB Key + slurp: + src: /opt/netbox_data/db_key + become: true + register: db_key + +- name: Set DB Key + set_fact: + postgres_netbox_db_key: '{{ db_key.content | b64decode }}' + cache: false + +- name: install Packages + apt: + name: + - python3-psycopg2 + - postgresql + become: true + +- name: Create netbox DB + community.postgresql.postgresql_db: + name: netbox + become_user: postgres + become: true + +- name: Create netbox DB User + community.postgresql.postgresql_user: + db: netbox + name: netbox + password: '{{ postgres_netbox_db_key }}' + become_user: postgres + become: true + +- name: Change netbox DB Owner + community.postgresql.postgresql_owner: + db: netbox + new_owner: netbox + obj_type: database + obj_name: netbox + become_user: postgres + become: true diff --git a/roles/netbox/templates/configuration.py.j2 b/roles/netbox/templates/configuration.py.j2 new file mode 100644 index 0000000..0d58cd0 --- /dev/null +++ b/roles/netbox/templates/configuration.py.j2 @@ -0,0 +1,18 @@ +# vi: ft=python +# This file is created by Ansible. DO NOT CHANGE! + +{% macro procval(val) -%} +{% if val is string -%}"{{ val }}" +{%- elif val is sameas true or val is sameas false -%}{{ val | string }} +{%- elif val is mapping %}{ +{% for k, v in val.items() %}{{ prockv_map(k,v) }}, +{% endfor %} } +{% elif val is iterable %}[ {%+ for v in val %}{{ procval(v) }}{{ ", " if not loop.last else "" }} {% endfor %} ] +{%- else -%}{{ val }}{%- endif %} +{%- endmacro %} +{% macro prockv(key, val) %}{{ key }} = {{ procval(val) }}{%- endmacro %} +{% macro prockv_map(key, val) %}"{{ key }}" : {{ procval(val) }}{%- endmacro %} + +{% for key in netbox_config %} +{{ prockv(key, netbox_config[key]) }} +{% endfor %} diff --git a/roles/netbox/templates/gunicorn.py.j2 b/roles/netbox/templates/gunicorn.py.j2 new file mode 100644 index 0000000..4c86905 --- /dev/null +++ b/roles/netbox/templates/gunicorn.py.j2 @@ -0,0 +1,18 @@ +# vi: ft=python +# This file is created by Ansible. DO NOT CHANGE! + +{% macro procval(val) -%} +{% if val is string -%}"{{ val }}" +{%- elif val is sameas true or val is sameas false -%}{{ val | string }} +{%- elif val is mapping %}{ +{% for k, v in val.items() %}{{ prockv_map(k,v) }}, +{% endfor %} } +{% elif val is iterable %}[ {%+ for v in val %}{{ procval(v) }}{{ ", " if not loop.last else "" }} {% endfor %} ] +{%- else -%}{{ val }}{%- endif %} +{%- endmacro %} +{% macro prockv(key, val) %}{{ key }} = {{ procval(val) }}{%- endmacro %} +{% macro prockv_map(key, val) %}"{{ key }}" : {{ procval(val) }}{%- endmacro %} + +{% for key in gunicorn_config %} +{{ prockv(key, gunicorn_config[key]) }} +{% endfor %} -- cgit v1.2.3