From 8aa823949d362d37a5d834c0a9a65079ab0803cd Mon Sep 17 00:00:00 2001
From: ale <ale@incal.net>
Date: Tue, 19 May 2020 14:54:50 +0100
Subject: [PATCH] Manage resolv.conf

---
 docs/configuration.md               | 15 +++++++++++++++
 roles/base/defaults/main.yml        |  8 ++++++++
 roles/base/tasks/main.yml           |  7 +++++++
 roles/base/templates/resolv.conf.j2 | 15 +++++++++++++++
 4 files changed, 45 insertions(+)
 create mode 100644 roles/base/templates/resolv.conf.j2

diff --git a/docs/configuration.md b/docs/configuration.md
index 32bd4a3e..24e396eb 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -89,6 +89,21 @@ the public-facing DNS zones, if unset it defaults to `ip`
 `groups` (optional) is a list of groups that this host should be a
 member of.
 
+`resolver_mode` (optional) controls the desired state of the host's
+*resolv.conf* file. The supported values are:
+
+* *ignore* - do nothing and leave resolv.conf alone
+* *localhost* - use localhost as a resolver, presumably some other
+  role will have installed a DNS cache there
+* *internal:NET* - use the frontend hosts as resolvers, over the
+  specified overlay network named NET
+* *external* - use Google Public DNS.
+
+Note that due to ordering issues it is advised to set the *resolver_mode*
+attribute on hosts only after the first setup is complete, to avoid
+breaking DNS resolution while Ansible is running.
+
+
 ## Example
 
 An example of a valid inventory file (for a hypotetic Vagrant
diff --git a/roles/base/defaults/main.yml b/roles/base/defaults/main.yml
index 839f0328..7946955e 100644
--- a/roles/base/defaults/main.yml
+++ b/roles/base/defaults/main.yml
@@ -21,3 +21,11 @@ emergency_ssh_key: ""
 # The Debian distribution that we are using as the basis.
 float_debian_dist: "buster"
 
+# How to configure resolv.conf, one of the following options:
+# 'ignore' - do nothing and leave resolv.conf alone
+# 'localhost' - use localhost as the name server (presumably a cache)
+# 'internal:NET' - use the frontend hosts as resolvers, over the
+#   specified overlay network NET
+# 'external' - use Google Public DNS.
+resolver_mode: "ignore"
+
diff --git a/roles/base/tasks/main.yml b/roles/base/tasks/main.yml
index 0ab03eed..9b5d48cf 100644
--- a/roles/base/tasks/main.yml
+++ b/roles/base/tasks/main.yml
@@ -86,3 +86,10 @@
 
 - import_tasks: ipmi.yml
   when: ipmi_device.stat.exists == true
+
+- name: Configure resolv.conf
+  template:
+    src: "resolv.conf.j2"
+    dest: "/etc/resolv.conf"
+  when: "resolver_mode != 'ignore'"
+
diff --git a/roles/base/templates/resolv.conf.j2 b/roles/base/templates/resolv.conf.j2
new file mode 100644
index 00000000..e15b6caf
--- /dev/null
+++ b/roles/base/templates/resolv.conf.j2
@@ -0,0 +1,15 @@
+{% if resolver_mode == 'localhost' %}
+nameserver 127.0.0.1
+options edns0
+{% elif resolver_mode.startswith('internal:') %}
+{% set dns_overlay_net = resolver_mode[9:] %}
+{% for h in groups['frontend'] | sort %}
+nameserver {{ hostvars[h]['ip_' + dns_overlay_net] }}
+{% endfor %}
+options edns0 rotate
+{% else %}
+nameserver 8.8.8.8
+nameserver 8.8.4.4
+options edns0
+{% endfor %}
+
-- 
GitLab