Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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.3.0
version: 11.5.0
readme: README.md
authors:
- https://github.com/novateams
Expand Down
2 changes: 1 addition & 1 deletion nova/core/roles/caddy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Refer to the [defaults/main.yml](https://github.com/novateams/nova.core/blob/mai

## Dependencies

- Depends on Docker and Docker Compose being installed on the host. Docker can be installed using the [nova.core.docker](https://github.com/novateams/nova.core/tree/main/nova/core/roles/caddy) role.
- Depends on Docker and Docker Compose being installed on the host. Docker can be installed using the [nova.core.docker](https://github.com/novateams/nova.core/tree/main/nova/core/roles/docker) role.

## Example

Expand Down
90 changes: 74 additions & 16 deletions nova/core/roles/configure_networking/tasks/proxmox/interfaces.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,53 @@
become: false
delegate_to: localhost
block:
- name: Templating following network configuration files...
- name: Getting OS type...
ansible.builtin.uri:
url: "{{ proxmox_api_url }}/nodes/{{ cfg_net_proxmox_node }}/qemu/{{ cfg_net_proxmox_vmid }}/agent/file-read?file=/etc/os-release"
headers:
Authorization: PVEAPIToken={{ proxmox_defaults.api_user }}!{{ proxmox_defaults.api_token_id }}={{ proxmox_defaults.api_token_secret }}
method: GET
validate_certs: "{{ proxmox_defaults.validate_certs }}"
register: network_config_command

- name: Setting OS type variable
ansible.builtin.set_fact:
configure_networking_os: >-
{% if 'ID=debian' in network_config_command.json.data['content'] | trim %}
Debian
{% elif 'ID=alpine' in network_config_command.json.data['content'] | trim %}
Alpine
{% else %}
Unknown
{% endif %}

- name: Templating interfaces...
ansible.builtin.template:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
src: interfaces.j2
dest: /tmp/{{ project_fullname | default('') }}_{{ inventory_hostname }}_interfaces
lstrip_blocks: true
mode: "0644"
loop_control:
label: "{{ item.dest }}"
loop:
- src: interfaces.j2
dest: /tmp/{{ project_fullname | default('') }}_{{ inventory_hostname }}_interfaces

- src: resolv.conf
dest: /tmp/{{ project_fullname | default('') }}_{{ inventory_hostname }}_resolv.conf
- name: Templating resolv.conf...
ansible.builtin.template:
src: resolv.conf
dest: /tmp/{{ project_fullname | default('') }}_{{ inventory_hostname }}_resolv.conf
lstrip_blocks: true
mode: "0644"

# For locking MAC addresses to interface names
- src: mactab
dest: /tmp/{{ project_fullname | default('') }}_{{ inventory_hostname }}_mactab
- name: Templating udev persistent net rules...
ansible.builtin.template:
src: 70-persistent-net.rules
dest: /tmp/{{ project_fullname | default('') }}_{{ inventory_hostname }}_70-persistent-net.rules
mode: "0644"
lstrip_blocks: true

- name: Templating mactab persistent net rules...
ansible.builtin.template:
src: mactab
dest: /tmp/{{ project_fullname | default('') }}_{{ inventory_hostname }}_mactab
mode: "0644"
lstrip_blocks: true

- name: Getting network configuration file contents...
ansible.builtin.slurp:
Expand All @@ -29,13 +58,15 @@
loop:
- /tmp/{{ project_fullname | default('') }}_{{ inventory_hostname }}_interfaces
- /tmp/{{ project_fullname | default('') }}_{{ inventory_hostname }}_resolv.conf
- /tmp/{{ project_fullname | default('') }}_{{ inventory_hostname }}_70-persistent-net.rules
- /tmp/{{ project_fullname | default('') }}_{{ inventory_hostname }}_mactab

# Since the Proxmox API can be quite unstable especially under load, we implement a rescue loop here
# to retry the network configuration up to 3 times before failing the task completely.
- name: Including network configuration tasks...
block:
- name: Writing following configuration to {{ custom_vm_name | default(vm_name) }}...
- name: Writing following Debian configuration to {{ custom_vm_name | default(vm_name) }}...
when: configure_networking_os is search('Debian')
ansible.builtin.uri:
url: "{{ proxmox_api_url }}/nodes/{{ cfg_net_proxmox_node }}/qemu/{{ cfg_net_proxmox_vmid }}/agent/file-write"
headers:
Expand All @@ -53,12 +84,39 @@
file: /etc/network/interfaces

- content: "{{ network_files.results[1].content | b64decode }}"
file: /etc/resolv.conf
file: /tmp/resolv.conf

- content: "{{ network_files.results[2].content | b64decode }}"
file: /etc/udev/rules.d/70-persistent-net.rules

- content: update-initramfs -u && cp /tmp/resolv.conf /etc/resolv.conf && reboot
file: /tmp/rebuild_initramfs.sh

- name: Writing following Alpine configuration to {{ custom_vm_name | default(vm_name) }}...
when: configure_networking_os is search('Alpine')
ansible.builtin.uri:
url: "{{ proxmox_api_url }}/nodes/{{ cfg_net_proxmox_node }}/qemu/{{ cfg_net_proxmox_vmid }}/agent/file-write"
headers:
Authorization: PVEAPIToken={{ proxmox_defaults.api_user }}!{{ proxmox_defaults.api_token_id }}={{ proxmox_defaults.api_token_secret }}
method: POST
body:
content: "{{ item.content }}"
file: "{{ item.file }}"
body_format: json
validate_certs: "{{ proxmox_defaults.validate_certs }}"
loop_control:
label: "{{ item.file }}"
loop:
- content: "{{ network_files.results[0].content | b64decode }}"
file: /etc/network/interfaces

- content: "{{ network_files.results[1].content | b64decode }}"
file: /tmp/resolv.conf

- content: "{{ network_files.results[3].content | b64decode }}"
file: /etc/mactab

- content: mkinitfs && reboot
- content: mkinitfs && cp /tmp/resolv.conf /etc/resolv.conf && reboot
file: /tmp/rebuild_initramfs.sh

- name: Rebuilding initramfs on {{ custom_vm_name | default(vm_name) }}...
Expand Down
9 changes: 9 additions & 0 deletions nova/core/roles/configure_networking/templates/netplan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,27 @@ network:
{% if (ip_address.mode == "ipv4_static") and (ip_address.gateway is defined) and (ip_address.gateway != none) %}
- to: default
via: "{{ ip_address.gateway }}"
{% if ip_address.on_link is defined and ip_address.on_link %}
on-link: true
{% endif %}
{% endif %}
{% endfor %}
{% for ip_address in interface.addresses %}
{% if (ip_address.mode == "ipv6_static") and (ip_address.gateway is defined) and (ip_address.gateway != none) %}
- to: default
via: "{{ ip_address.gateway }}"
{% if ip_address.on_link is defined and ip_address.on_link %}
on-link: true
{% endif %}
{% endif %}
{% endfor %}
{% if extra_routes[interface_names[interface_loop]] is defined %}
{% for route in extra_routes[interface_names[interface_loop]] %}
- to: {{ route.to }}
via: "{{ route.via }}"
{% if route.on_link is defined and route.on_link %}
on-link: true
{% endif %}
{% endfor %}
{% endif %}
{% if extra_ipv4 is defined or extra_ipv6 is defined %}
Expand Down
102 changes: 102 additions & 0 deletions nova/core/roles/coredns/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# coredns

This role installs and configures CoreDNS on Debian-based systems and allows generating zonefiles and configuring forwarders for CoreDNS

## Requirements

none

## Role Variables

Refer to the [defaults/main.yml](https://github.com/novateams/nova.core/blob/main/nova/core/roles/coredns/defaults/main.yml) file for a list and description of the variables used in this role.

## Dependencies

- Depends on Docker and Docker Compose being installed on the host. Docker can be installed using the [nova.core.docker](https://github.com/novateams/nova.core/tree/main/nova/core/roles/docker) role.

## Example

```yml
# Installing CoreDNS without any custom zonefiles or forwarders
# By default it'll use DoT (DNS over TLS) to forward all requests to Cloudflare or Google if Cloudflare is not reachable.
- name: Including CoreDNS role...
ansible.builtin.include_role:
name: nova.core.coredns
```

```yml
# Installing CoreDNS and generating custom zonefiles based on the provided coredns_records variable.
# 2 zonefiles will be generated, one for example.com and one for example.org with the provided records.
- name: Including CoreDNS role...
ansible.builtin.include_role:
name: nova.core.coredns
vars:
coredns_records:
- domain: example.com
records:
- type: A
name: www
value: 10.0.0.1
- type: AAAA
name: www
value: 2001:db8::1
- type: CNAME
name: mail
value: mail.example.com
- domain: example.org
records:
- type: A
name: www
value: 10.0.0.2
```

```yml
# Installing CoreDNS and generating custom zonefiles based on the provided coredns_records variable.
# 2 zonefiles will be generated, one for example.com and one for example.org with the provided records.
# Additionally setting custom nameservers for example.com zone when nameservers is not defined, CoreDNS will itself act as the nameserver for the zone.
- name: Including CoreDNS role...
ansible.builtin.include_role:
name: nova.core.coredns
vars:
coredns_records:
- domain: example.com
# OPTIONAL
nameservers:
- name: ns1
address: 10.10.10.1
- name: ns1
address: 2001:db8::1
- name: ns2
address: 10.10.10.2
records:
- type: A
name: www
value: 10.0.0.1
- type: AAAA
name: www
value: 2001:db8::1
- type: CNAME
name: mail
value: mail.example.com
- domain: example.org
records:
- type: A
name: www
value: 10.0.0.2
```

```yml
# Installing CoreDNS without any zonefiles but with custom forwarders defined in the coredns_forwarders variable.
# CoreDNS will now forward requests for example.com and example.org to the specified DNS servers.
- name: Including CoreDNS role...
ansible.builtin.include_role:
name: nova.core.coredns
vars:
coredns_forwarders:
- domains:
- example.com
- example.org
addresses:
- 10.10.10.1
- 2001:db8::1
```
26 changes: 26 additions & 0 deletions nova/core/roles/coredns/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
coredns_version: coredns/coredns:1.14.6
coredns_config_folder: /srv/coredns
coredns_docker_network: local-network # This is the default for nova.core.docker role

# List of DNS server that will go to resolve.conf file, in order of preference.
# By default, the first entry is the IP address of CoreDNS itself and the rest are public DNS servers.
# This is to avoid race conditions when setting up CoreDNS for the first time and disabling systemd-resolved service causing DNS resolution to fail.
coredns_upstream_dns_servers:
- "{{ connection_address }}"
- 1.1.1.1
- 8.8.8.8

# The default CoreDNS configuration file template to use. Default comes with this role.
# This can be overridden by providing a different path for the template file.
coredns_corefile: corefile

# The list of DNS records to be created in CoreDNS.
# Refer to this roles README for the format of the records.
# By leaving this empty, no records will be created,
# this is useful if you want to generate the zonefiles outside of this role and just want to use this role to setup CoreDNS.
coredns_records: []

# The list of DNS forwarders to be used in CoreDNS. These will forward matching domains to the specified DNS servers.
# Refer to this roles README for the format of the forwarders.
coredns_forwarders: []
Loading