Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
fd04226
Fixed a race condition in `accounts` where Windows AD group membershi…
AllRWeak Jul 15, 2026
a39ee3e
Set default GCP instance disk to SSD
AllRWeak Jul 16, 2026
4a07870
Added a feature to define source IP ranges for GCP firewalls
AllRWeak Jul 16, 2026
ec4f29b
Linted and refactored `win_configure_rdp` role
AllRWeak Jul 16, 2026
37354ec
Enabling compression by default on `caddy`
AllRWeak Jul 16, 2026
9b536e9
Refactored how MacOS users get created in `accounts` role to be more …
AllRWeak Jul 16, 2026
cc79a34
Removed unmaintained ParrotOS support from `configure_package_mirrors…
AllRWeak Jul 16, 2026
53bf759
Refactored `configure_package_mirrors` role to use deb822 format
AllRWeak Jul 16, 2026
48730cf
Set `gitlab` version to 19.2.0
AllRWeak Jul 16, 2026
86f10ae
Added a flag to toggle the disable of administrators_authorized_keys …
AllRWeak Jul 20, 2026
c461208
Redesigned `accounts` role so all admin_accounts SSH keys are added t…
AllRWeak Jul 20, 2026
4b4bad2
Set `outline` version to 1.9.2
AllRWeak Jul 23, 2026
2db709d
Added a feature to update Debian OS firmware with `updates` role
AllRWeak Jul 24, 2026
0897ba8
Set `nexus` version to 3.94.1
AllRWeak Jul 26, 2026
18bca90
Added a feature to upgrade OPNsense major version with the `updates` …
AllRWeak Jul 26, 2026
34df4cd
Added nmcli network configuration method support for AWS EC2 hosts
AllRWeak Jul 28, 2026
78938ca
Removing cloud-init from Linux OSs in cloud env after initial config …
AllRWeak Jul 28, 2026
04001c9
In `updates` role for FreeBSD setting the current Python version afte…
AllRWeak Jul 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion nova/core/galaxy.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace: nova
name: core
version: 11.1.0
version: 11.3.0
readme: README.md
authors:
- https://github.com/novateams
Expand Down
41 changes: 0 additions & 41 deletions nova/core/roles/accounts/tasks/create_domain_groups.yml

This file was deleted.

59 changes: 48 additions & 11 deletions nova/core/roles/accounts/tasks/macos_create.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,43 @@
---
- name: MISSING OR INCORRECT VARIABLE(S)
ansible.builtin.fail:
msg: |
The **ansible_deployer_password** variable is required and **connection_no_password** variable must be false.
MacOS requires a password as secure token to create and edit user accounts.
when: ansible_deployer_password | default(false) is ansible.builtin.falsy
or connection_no_password | default(false) is ansible.builtin.truthy

# This required so this role can clean up the default cloud users if they are not in the local_accounts_with_password list
- name: Adding source creation flag for default cloud account...
when: lookup('vars', infra_env ~ '_template_username') | default('') not in [admin_account, '']
block:
- name: Checking if {{ lookup('vars', infra_env ~ '_template_username') | default('') }} user exists...
ansible.builtin.raw: |
if dscl . -list /Users | grep -q "^{{ lookup('vars', infra_env ~ '_template_username') | default('') }}$"; then
echo "User exists"
else
echo "User does not exist"
fi
changed_when: false
register: template_user

- name: Adding account creation source flag for {{ lookup('vars', infra_env ~ '_template_username') | default('') }}...
ansible.builtin.raw: |
echo "This account was created with {{ ansible_role_name
}} role" > /Users/{{ lookup('vars', infra_env ~ '_template_username') | default('') }}/.created
chown {{ lookup('vars', infra_env ~ '_template_username') | default('')
}}:staff /Users/{{ lookup('vars', infra_env ~ '_template_username') | default('') }}/.created
changed_when: true
when: template_user.stdout.find('User exists') != -1

- name: Configuring following users...
ansible.builtin.raw: |
if dscl . -list /Users | grep -q "^{{ item.username }}$"; then

echo Setting existing {{ item.username }} user password
sysadminctl -resetPasswordFor {{ item.username }} -newPassword {{
item.password }} -adminUser {{ ansible_user }} "{{ '' if ansible_password is not defined else '-adminPassword ' ~ ansible_password }}"

sysadminctl -resetPasswordFor {{ item.username }} -newPassword '{{ item.password }}' -adminUser {{ ansible_user }} -adminPassword '{{ ansible_password }}'
else

echo Creating new {{ item.username }} account
sysadminctl -addUser {{ item.username }} -password {{ item.password }} -admin -shell /bin/zsh

echo "Creating new {{ item.username }} account"
sysadminctl -addUser {{ item.username }} -password {{ item.password }} -admin -shell /bin/zsh
sysadminctl -adminUser {{ ansible_user }} -adminPassword {{ ansible_password }} -secureTokenOn {{ item.username }} -password {{ item.password }}
fi
changed_when: true
loop: "{{ admin_accounts_with_password }}"
Expand Down Expand Up @@ -48,8 +74,7 @@
- name: Adding ssh keys for...
ansible.builtin.raw: |
line="$( echo {{ item.ssh_key }} )"
if [ "{{ admin_account }}" = "{{ item.username }}" ];
then
if [ "{{ admin_account }}" = "{{ item.username }}" ]; then
echo "Adding ssh key to root user"
file=/var/root/.ssh/authorized_keys
mkdir -p /var/root/.ssh/
Expand All @@ -66,3 +91,15 @@
loop_control:
label: "{{ item.username }}"
when: item.ssh_key is defined

- name: Configuring SSHD in cloud environments...
when: accounts_configure_ssh_maxauthtries
block:
# This to avoid errors when someone has more that 6 SSH keys in their agent
- name: Setting SSHD MaxAuthTries to {{ accounts_ssh_maxauthtries }}...
ansible.builtin.raw: sed -i "" "s/.*MaxAuthTries.*/MaxAuthTries {{ accounts_ssh_maxauthtries }}/g" /etc/ssh/sshd_config
changed_when: true

- name: Restarting SSHD... # noqa: no-handler
ansible.builtin.raw: launchctl kickstart -k system/com.openssh.sshd
changed_when: true
26 changes: 18 additions & 8 deletions nova/core/roles/accounts/tasks/macos_remove.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
---
# Ignoring symbolic links and only listing user accounts that have a .created file in their home directory, which indicates they were created by this role.
- name: Listing user accounts created with {{ ansible_role_name }}...
ansible.builtin.raw: |
for profile in /Users/*/; do
if [[ -f $profile/.created ]]; then
echo $(basename $profile)
fi
for profile in /Users/*; do
if [[ -f "$profile/.created" && ! -L "$profile" ]]; then
basename "$profile"
fi
done
register: home_profiles
changed_when: false
Expand All @@ -21,8 +22,10 @@
block:
- name: Removing following accounts...
ansible.builtin.raw: |
dscl . -delete /Users/{{ item }}
rm -rf /Users/{{ item }}
pkill -9 -u {{ item }}
sysadminctl -deleteUser {{ item }}
# rm -rf /Users/{{ item }}
# dscl . -delete /Users/{{ item }}
loop: "{{ user_profiles_to_remove }}"
changed_when: true

Expand All @@ -37,10 +40,17 @@
# because the connection is lost before the reboot command completes.
# To avoid this, we can ignore unreachable hosts after issuing the reboot command.
ignore_unreachable: true
when: not darwin_with_python

- name: Rebooting
ansible.builtin.reboot:
when: darwin_with_python

- name: Removing following accounts...
ansible.builtin.raw: |
dscl . -delete /Users/{{ item }}
rm -rf /Users/{{ item }}
pkill -9 -u {{ item }}
sysadminctl -deleteUser {{ item }}
# rm -rf /Users/{{ item }}
# dscl . -delete /Users/{{ item }}
loop: "{{ user_profiles_to_remove }}"
changed_when: true
68 changes: 51 additions & 17 deletions nova/core/roles/accounts/tasks/windows_create.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,16 @@
- name: Creating OUs for {{ ad_domain_name | default('') }}...
ansible.windows.win_shell: "{{ lookup('ansible.builtin.template', 'Create-OUs.ps1') }}"

- name: Configuring Domain groups...
ansible.builtin.include_tasks: create_domain_groups.yml
# Creating all domain groups without members first, since some members may not exist yet
- name: Creating following Domain groups...
microsoft.ad.group:
name: "{{ item.name }}"
scope: "{{ item.scope | default('domainlocal') }}"
path: "{{ item.ou | default(omit) }}"
description: "{{ item.description | default(omit) }}"
loop: "{{ domain_groups }}"
loop_control:
label: "{{ item.name | default('') }}"

- name: Creating following domain accounts...
microsoft.ad.user:
Expand Down Expand Up @@ -87,6 +95,38 @@
win_domain_user.results | selectattr('changed', 'equalto', true) | map(attribute='item.username')
| list | intersect([ansible_deployer_username]) | length > 0

# Configuring all domains groups with members now that all domain accounts have been created with replace strategy
- name: Configuring following domain groups and replacing members...
microsoft.ad.group:
name: "{{ item.name }}"
scope: "{{ item.scope | default('domainlocal') }}"
path: "{{ item.ou | default(omit) }}"
description: "{{ item.description | default(omit) }}"
members:
set: "{{ item.members }}"
loop: "{{ domain_groups }}"
loop_control:
label: "{{ item.members | default(['no_members']) | join(', ') }} to {{ item.name | default('') }}"
when:
- item.members is defined
- accounts_domain_groups_members_strategy == 'replace'

# Configuring all domains groups with members now that all domain accounts have been created with add strategy
- name: Configuring following domain groups and adding members...
microsoft.ad.group:
name: "{{ item.name }}"
scope: "{{ item.scope | default('domainlocal') }}"
path: "{{ item.ou | default(omit) }}"
description: "{{ item.description | default(omit) }}"
members:
add: "{{ item.members }}"
loop: "{{ domain_groups }}"
loop_control:
label: "{{ item.members | default(['no_members']) | join(', ') }} to {{ item.name | default('') }}"
when:
- item.members is defined
- accounts_domain_groups_members_strategy == 'add'

# To make sure that we are setting the password for the correct account on non-primary domain controller
- name: Setting correct password for {{ ansible_deployer_username }}...
ansible.builtin.set_fact:
Expand Down Expand Up @@ -149,22 +189,16 @@
- item.ssh_key is defined
- not item.ssh_key_exclusive | default(accounts_exclusive_ssh_key)

- name: Creating administrators_authorized_keys file...
ansible.windows.win_file:
path: C:\ProgramData\ssh\administrators_authorized_keys
state: touch

- name: Adding administrators_authorized_keys public keys for admins...
community.windows.win_lineinfile:
path: C:\ProgramData\ssh\administrators_authorized_keys
line: "{{ item.ssh_key }}"
# Adding keys to administrators_authorized_keys in case it's used.
# Careful with this feature since it allows any ssh key under administrators_authorized_keys to be used to login as any user in the Administrators group.
# This feature needs the following lines to be enabled in sshd_config:
# Match Group administrators
# AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
- name: Adding admin_accounts ssh public keys to administrators_authorized_keys file...
ansible.windows.win_copy:
content: "{{ admin_accounts_with_password | selectattr('ssh_key', 'defined') | map(attribute='ssh_key') | list | unique | join('\n')}}"
dest: C:\ProgramData\ssh\administrators_authorized_keys
create: true
loop: "{{ admin_accounts_with_password }}"
loop_control:
label: "{{ item.username }}"
when:
- item.username == ansible_deployer_username # Because C:\ProgramData\ssh\administrators_authorized_keys supports only one key
- item.ssh_key is defined

- name: Configuring SSHD in cloud environments...
when: accounts_configure_ssh_maxauthtries
Expand Down
1 change: 1 addition & 0 deletions nova/core/roles/caddy/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ caddy_certificates_folder: /srv/certs/
caddy_auto_https: "disable_certs" # https://caddyserver.com/docs/caddyfile/options#auto-https
caddy_ocsp_stapling: false
caddy_use_tls: true # Set to false to disable TLS for all servers or add it as a variable per server
caddy_enable_compression: true # Set to false to disable compression for all servers or add it as a variable per server
3 changes: 3 additions & 0 deletions nova/core/roles/caddy/templates/Caddyfile_jinja
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
}
}

{% if caddy_enable_compression %}
encode
{% endif %}
request_body {
max_size {{ server.caddy_server_request_body_size | default("10MB") }}
}
Expand Down
89 changes: 89 additions & 0 deletions nova/core/roles/configure_networking/tasks/aws/nmcli.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
- name: Purging existing networking packages...
ansible.builtin.package:
name:
- netplan.io
- cloud-init
state: absent
purge: true
become: true

- name: Cleaning up old network configuration files...
ansible.builtin.shell: |
rm -rf /etc/systemd/network/*
rm -rf /etc/netplan/*
changed_when: true
become: true

- name: Installing NetworkManager package...
ansible.builtin.package:
name: network-manager
state: present
update_cache: true
become: true

- name: Templating nmcli configuration files...
ansible.builtin.template:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: "0644"
lstrip_blocks: true
loop_control:
label: "{{ item.src }}"
loop:
- src: 70-persistent-net.rules
dest: /tmp/{{ project_fullname | default('') }}_{{ inventory_hostname }}_70-persistent-net.rules
- src: nmcli.sh
dest: /tmp/{{ project_fullname | default('') }}_{{ inventory_hostname }}_nmcli.sh
become: false
delegate_to: localhost

- name: Uploading nmcli configuration files...
ansible.builtin.copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: "{{ item.mode }}"
loop_control:
label: "{{ item.src }}"
loop:
- src: /tmp/{{ project_fullname | default('') }}_{{ inventory_hostname }}_70-persistent-net.rules
dest: /etc/udev/rules.d/70-persistent-net.rules
mode: "0644"
- src: /tmp/{{ project_fullname | default('') }}_{{ inventory_hostname }}_nmcli.sh
dest: /tmp/nmcli.sh
mode: "0755"
become: true

- name: Running nmcli configuration script...
ansible.builtin.command: /tmp/nmcli.sh
changed_when: true
become: true
async: 3600
poll: 0

- name: Waiting until SSH is down for {{ custom_vm_name | default(vm_name) }} over {{ connection_address }}...
ansible.builtin.wait_for:
host: "{{ connection_address }}"
port: 22
state: stopped
timeout: 300
become: false
delegate_to: localhost

- name: Waiting until SSH is up for {{ custom_vm_name | default(vm_name) }} over {{ connection_address }}...
ansible.builtin.wait_for:
host: "{{ connection_address }}"
port: 22
state: started
timeout: 300
become: false
delegate_to: localhost
# - name: Removing temporary files...
# ansible.builtin.file:
# path: /var/tmp/nmcli.sh
# state: absent
# - name: Rebooting {{ custom_vm_name | default(vm_name) }} VM...
# ansible.builtin.include_role:
# name: nova.core.powerstate
# vars:
# restart: true
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
---
# This step is not actually very useful for debugging
- name: Templating network configuration script...
ansible.builtin.template:
src: Configure-Network.ps1
Expand Down
4 changes: 3 additions & 1 deletion nova/core/roles/configure_networking/templates/nmcli.sh
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,6 @@ fi
{% endif %}
{% endfor %}

nmcli networking off && nmcli networking on
{% if infra_env == "aws" %}
reboot
{% endif %}
Loading