301 lines
9.6 KiB
YAML
301 lines
9.6 KiB
YAML
---
|
|
- name: Set up technitium LXC
|
|
hosts: technitium
|
|
become: yes
|
|
vars:
|
|
dotnet_dir: /opt/dotnet
|
|
dotnet_version: "10.0"
|
|
dotnet_runtime_prefix: "Microsoft.AspNetCore.App 10.0."
|
|
dotnet_url: "https://dot.net/v1/dotnet-install.sh"
|
|
dns_config: /etc/dns
|
|
dns_log: /var/log/technitium/dns
|
|
dns_url: "https://download.technitium.com/dns/DnsServerPortable.tar.gz"
|
|
service_user: dns-server
|
|
|
|
tasks:
|
|
- name: default_packages
|
|
ansible.builtin.include_tasks: ../../templates/default_packages.yml
|
|
|
|
- name: create_user
|
|
ansible.builtin.include_tasks: ../../templates/create_user.yml
|
|
vars:
|
|
username: nick
|
|
github_user: Chewbaccalakis
|
|
|
|
# Determine dns_dir: use /etc/dns if an existing install is detected, otherwise /opt/technitium/dns
|
|
- name: Check for existing install at /etc/dns/config
|
|
ansible.builtin.stat:
|
|
path: /etc/dns/config
|
|
register: etc_dns_config
|
|
|
|
- name: Set dns_dir for existing install
|
|
ansible.builtin.set_fact:
|
|
dns_dir: /etc/dns
|
|
dns_tar: /etc/dns/DnsServerPortable.tar.gz
|
|
when: etc_dns_config.stat.exists and etc_dns_config.stat.isdir
|
|
|
|
- name: Set dns_dir for fresh install
|
|
ansible.builtin.set_fact:
|
|
dns_dir: /opt/technitium/dns
|
|
dns_tar: /opt/technitium/dns/DnsServerPortable.tar.gz
|
|
when: not (etc_dns_config.stat.exists and etc_dns_config.stat.isdir)
|
|
|
|
- name: Create required directories
|
|
ansible.builtin.file:
|
|
path: "{{ item }}"
|
|
state: directory
|
|
mode: '0755'
|
|
loop:
|
|
- "{{ dns_dir }}"
|
|
- "{{ dns_config }}"
|
|
|
|
# .NET Runtime
|
|
- name: Check installed .NET runtimes
|
|
ansible.builtin.command: dotnet --list-runtimes
|
|
register: dotnet_runtimes
|
|
changed_when: false
|
|
failed_when: false
|
|
|
|
- name: Install ASP.NET Core Runtime
|
|
when: dotnet_runtime_prefix not in (dotnet_runtimes.stdout | default(''))
|
|
block:
|
|
- name: Download dotnet-install.sh
|
|
ansible.builtin.get_url:
|
|
url: "{{ dotnet_url }}"
|
|
dest: /tmp/dotnet-install.sh
|
|
mode: '0755'
|
|
|
|
- name: Run dotnet-install.sh
|
|
ansible.builtin.command: >
|
|
bash /tmp/dotnet-install.sh
|
|
-c {{ dotnet_version }}
|
|
--runtime aspnetcore
|
|
--no-path
|
|
--install-dir {{ dotnet_dir }}
|
|
|
|
- name: Create /usr/bin/dotnet symlink
|
|
ansible.builtin.file:
|
|
src: "{{ dotnet_dir }}/dotnet"
|
|
dest: /usr/bin/dotnet
|
|
state: link
|
|
|
|
# DNS Server
|
|
- name: Download Technitium DNS Server archive
|
|
ansible.builtin.get_url:
|
|
url: "{{ dns_url }}"
|
|
dest: "{{ dns_tar }}"
|
|
mode: '0644'
|
|
|
|
- name: Extract Technitium DNS Server
|
|
ansible.builtin.unarchive:
|
|
src: "{{ dns_tar }}"
|
|
dest: "{{ dns_dir }}"
|
|
remote_src: yes
|
|
|
|
# ICU
|
|
- name: Test ICU availability for .NET
|
|
ansible.builtin.command: "dotnet {{ dns_dir }}/DnsServerApp.dll --icu-test"
|
|
register: icu_test
|
|
changed_when: false
|
|
failed_when: false
|
|
|
|
- name: Install ICU library
|
|
when: icu_test.rc != 0
|
|
block:
|
|
- name: Find available ICU package
|
|
ansible.builtin.shell: |
|
|
for pkg in libicu74 libicu72 libicu70; do
|
|
if apt-cache show $pkg >/dev/null 2>&1; then
|
|
echo $pkg
|
|
exit 0
|
|
fi
|
|
done
|
|
echo "libicu-dev"
|
|
register: icu_package
|
|
changed_when: false
|
|
|
|
- name: Install ICU package
|
|
ansible.builtin.apt:
|
|
name: "{{ icu_package.stdout }}"
|
|
state: present
|
|
update_cache: yes
|
|
|
|
- name: Verify ICU works after install
|
|
ansible.builtin.command: "dotnet {{ dns_dir }}/DnsServerApp.dll --icu-test"
|
|
|
|
# Systemd service
|
|
- name: Check if dns.service is already installed
|
|
ansible.builtin.stat:
|
|
path: /etc/systemd/system/dns.service
|
|
register: dns_service_file
|
|
|
|
- name: Restart existing dns service (update path)
|
|
ansible.builtin.systemd:
|
|
name: dns.service
|
|
state: restarted
|
|
when: dns_service_file.stat.exists
|
|
|
|
- name: First-time service setup
|
|
#when: not dns_service_file.stat.exists #temp change
|
|
block:
|
|
- name: Create DNS log directory
|
|
ansible.builtin.file:
|
|
path: "{{ dns_log }}"
|
|
state: directory
|
|
mode: '0755'
|
|
|
|
- name: Create dns-server service user
|
|
ansible.builtin.user:
|
|
name: "{{ service_user }}"
|
|
system: yes
|
|
create_home: no
|
|
shell: /usr/sbin/nologin
|
|
|
|
- name: Set ownership on DNS directories
|
|
ansible.builtin.file:
|
|
path: "{{ item }}"
|
|
owner: "{{ service_user }}"
|
|
group: "{{ service_user }}"
|
|
recurse: yes
|
|
loop:
|
|
- "{{ dns_dir }}"
|
|
- "{{ dns_config }}"
|
|
- "{{ dns_log }}"
|
|
|
|
- name: Copy systemd service file
|
|
ansible.builtin.copy:
|
|
src: "{{ dns_dir }}/systemd.service"
|
|
dest: /etc/systemd/system/dns.service
|
|
remote_src: yes
|
|
|
|
- name: Enable dns.service
|
|
ansible.builtin.systemd:
|
|
name: dns.service
|
|
enabled: yes
|
|
daemon_reload: yes
|
|
|
|
- name: Stop and disable systemd-resolved
|
|
ansible.builtin.systemd:
|
|
name: systemd-resolved
|
|
state: stopped
|
|
enabled: no
|
|
failed_when: false
|
|
|
|
- name: Start dns.service
|
|
ansible.builtin.systemd:
|
|
name: dns.service
|
|
state: started
|
|
|
|
- name: Check if NetworkManager.conf exists
|
|
ansible.builtin.stat:
|
|
path: /etc/NetworkManager/NetworkManager.conf
|
|
register: nm_conf
|
|
|
|
- name: Configure NetworkManager to not manage DNS
|
|
community.general.ini_file:
|
|
path: /etc/NetworkManager/NetworkManager.conf
|
|
section: main
|
|
option: dns
|
|
value: none
|
|
no_extra_spaces: yes
|
|
when: nm_conf.stat.exists
|
|
|
|
- name: Back up existing resolv.conf
|
|
ansible.builtin.copy:
|
|
src: /etc/resolv.conf
|
|
dest: "{{ dns_dir }}/resolv.conf.bak"
|
|
remote_src: yes
|
|
force: no
|
|
|
|
- name: Configure resolv.conf to use local DNS
|
|
ansible.builtin.copy:
|
|
dest: /etc/resolv.conf
|
|
content: |
|
|
# Generated by Technitium DNS Server Installer
|
|
|
|
nameserver 127.0.0.1
|
|
|
|
# Admin user setup
|
|
- name: Prompt for Technitium admin password
|
|
ansible.builtin.pause:
|
|
prompt: "Set Technitium admin password"
|
|
echo: no
|
|
register: technitium_pass_raw
|
|
|
|
- name: Prompt to confirm Technitium admin password
|
|
ansible.builtin.pause:
|
|
prompt: "Confirm Technitium admin password"
|
|
echo: no
|
|
register: technitium_pass_confirm
|
|
|
|
- name: Fail if passwords do not match
|
|
ansible.builtin.fail:
|
|
msg: "Passwords do not match!"
|
|
when: technitium_pass_raw.user_input != technitium_pass_confirm.user_input
|
|
|
|
- name: Wait for Technitium web console to be available
|
|
ansible.builtin.wait_for:
|
|
host: localhost
|
|
port: 5380
|
|
timeout: 60
|
|
|
|
- name: Login with default admin credentials
|
|
ansible.builtin.uri:
|
|
url: "http://localhost:5380/api/user/login"
|
|
method: GET
|
|
body_format: form-urlencoded
|
|
body:
|
|
user: admin
|
|
pass: admin
|
|
includeInfo: "true"
|
|
register: technitium_login
|
|
no_log: true
|
|
failed_when: technitium_login.json.status != 'ok'
|
|
|
|
- name: Change admin password
|
|
ansible.builtin.uri:
|
|
url: "http://localhost:5380/api/user/changePassword"
|
|
method: GET
|
|
body_format: form-urlencoded
|
|
body:
|
|
token: "{{ technitium_login.json.token }}"
|
|
pass: admin
|
|
newPass: "{{ technitium_pass_raw.user_input }}"
|
|
no_log: false # temp change
|
|
failed_when: technitium_change_pass.json.status != 'ok'
|
|
register: technitium_change_pass
|
|
|
|
- name: Create Terraform API token
|
|
ansible.builtin.uri:
|
|
url: "http://localhost:5380/api/user/createToken"
|
|
method: GET
|
|
body_format: form-urlencoded
|
|
body:
|
|
token: "{{ technitium_login.json.token }}"
|
|
tokenName: terraform
|
|
register: technitium_terraform_token
|
|
no_log: true
|
|
failed_when: technitium_terraform_token.json.status != 'ok'
|
|
|
|
- name: Read secrets.tmpl to get Infisical connection details
|
|
ansible.builtin.slurp:
|
|
src: "{{ playbook_dir }}/../../../secrets.tmpl"
|
|
delegate_to: localhost
|
|
become: false
|
|
register: secrets_tmpl_raw
|
|
|
|
- name: Parse Infisical project ID, env, and path from secrets.tmpl
|
|
ansible.builtin.set_fact:
|
|
infisical_params: >-
|
|
{{ (secrets_tmpl_raw.content | b64decode).split('\n')[0] | regex_findall('"([^"]+)"') }}
|
|
|
|
- name: Store Terraform API token in Infisical
|
|
ansible.builtin.command: >
|
|
infisical secrets set TECHNITIUM_API_TOKEN="{{ technitium_terraform_token.json.token }}"
|
|
--projectId="{{ infisical_params[0] }}"
|
|
--env="{{ infisical_params[1] }}"
|
|
--path="{{ infisical_params[2] }}"
|
|
delegate_to: localhost
|
|
become: false
|
|
no_log: false # temp change
|