From 90e608888192819378d751d2d7dc3a769a2ef504 Mon Sep 17 00:00:00 2001 From: "James E. Blair" Date: Wed, 31 Oct 2018 16:13:33 -0700 Subject: [PATCH] Configure adns1.opendev.org server via ansible Change-Id: Ib4d3cd7501a276bff62e3bc0998d93c41f3ab185 --- .zuul.yaml | 22 ++++++ inventory/groups.yaml | 6 +- playbooks/base.yaml | 5 ++ playbooks/group_vars/dns.yaml | 15 ++++ playbooks/roles/master-nameserver/README.rst | 77 +++++++++++++++++++ .../master-nameserver/handlers/main.yaml | 2 + .../roles/master-nameserver/tasks/main.yaml | 68 ++++++++++++++++ .../master-nameserver/templates/bind.key.j2 | 4 + .../master-nameserver/templates/named.conf.j2 | 49 ++++++++++++ playbooks/zuul/run-base.yaml | 1 + playbooks/zuul/run-production-playbook.yaml | 1 - .../zuul/templates/group_vars/adns.yaml.j2 | 12 +++ testinfra/test_adns.py | 21 +++++ 13 files changed, 280 insertions(+), 3 deletions(-) create mode 100644 playbooks/group_vars/dns.yaml create mode 100644 playbooks/roles/master-nameserver/README.rst create mode 100644 playbooks/roles/master-nameserver/handlers/main.yaml create mode 100644 playbooks/roles/master-nameserver/tasks/main.yaml create mode 100644 playbooks/roles/master-nameserver/templates/bind.key.j2 create mode 100644 playbooks/roles/master-nameserver/templates/named.conf.j2 create mode 100644 playbooks/zuul/templates/group_vars/adns.yaml.j2 create mode 100644 testinfra/test_adns.py diff --git a/.zuul.yaml b/.zuul.yaml index bc2d797188..f5310c422b 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -195,6 +195,26 @@ - playbooks/templates/clouds/ - testinfra/test_nodepool.py +- job: + name: system-config-run-dns + parent: system-config-run + description: | + Run the playbook for dns. + nodeset: + nodes: + - name: bridge.openstack.org + label: ubuntu-bionic + - name: adns1.opendev.org + label: ubuntu-bionic + files: + - .zuul.yaml + - playbooks/group_vars/adns.yaml + - playbooks/group_vars/dns.yaml + - playbooks/host_vars/adns1.opendev.org.yaml + - playbooks/zuul/templates/group_vars/adns.yaml.j2 + - playbooks/roles/master-nameserver/ + - testinfra/test_adns.py + - job: name: infra-prod-playbook description: | @@ -237,6 +257,7 @@ - puppet-beaker-rspec-puppet-4-infra-system-config - puppet-beaker-rspec-puppet-4-centos-7-infra-system-config - system-config-run-base + - system-config-run-dns - system-config-run-eavesdrop - system-config-run-nodepool gate: @@ -248,5 +269,6 @@ - puppet-beaker-rspec-puppet-4-infra-system-config - puppet-beaker-rspec-puppet-4-centos-7-infra-system-config - system-config-run-base + - system-config-run-dns - system-config-run-eavesdrop - system-config-run-nodepool diff --git a/inventory/groups.yaml b/inventory/groups.yaml index 5bbdf4804c..6f68b636ab 100644 --- a/inventory/groups.yaml +++ b/inventory/groups.yaml @@ -27,6 +27,9 @@ groups: - wiki-dev01.openstack.org - wiki-upgrade-test.openstack.org - wiki.openstack.org + dns: + - adns*.opendev.org + - ns*.opendev.org eavesdrop: eavesdrop[0-9]*.openstack.org elasticsearch: elasticsearch[0-9]*.openstack.org ethercalc: ethercalc* @@ -99,8 +102,7 @@ groups: nodepool-launcher: - nl[0-9]*.openstack.org ns: - - ns1.openstack.org - - ns2.openstack.org + - ns[0-9]*.* paste: - paste01.openstack.org pbx: diff --git a/playbooks/base.yaml b/playbooks/base.yaml index 57a1abaa88..10f416de21 100644 --- a/playbooks/base.yaml +++ b/playbooks/base.yaml @@ -41,3 +41,8 @@ roles: - puppet-install - disable-puppet-agent + +- hosts: "adns1.opendev.org:!disabled" + name: "Base: configure adns1.opendev.org" + roles: + - master-nameserver diff --git a/playbooks/group_vars/dns.yaml b/playbooks/group_vars/dns.yaml new file mode 100644 index 0000000000..8d8cccbe48 --- /dev/null +++ b/playbooks/group_vars/dns.yaml @@ -0,0 +1,15 @@ +dns_repos: + - name: zone-opendev.org + url: https://git.openstack.org/openstack-infra/zone-opendev.org + - name: zone-zuul-ci.org + url: https://git.openstack.org/openstack-infra/zone-zuul-ci.org +dns_zones: + - name: opendev.org + source: zone-opendev.org/zones/opendev.org/ + - name: zuul-ci.org + source: zone-zuul-ci.org/zones/zuul-ci.org/ + - name: zuulci.org + source: zone-zuul-ci.org/zones/zuulci.org/ +dns_notify: + - 104.239.140.165 + - 162.253.55.16 diff --git a/playbooks/roles/master-nameserver/README.rst b/playbooks/roles/master-nameserver/README.rst new file mode 100644 index 0000000000..4003243af3 --- /dev/null +++ b/playbooks/roles/master-nameserver/README.rst @@ -0,0 +1,77 @@ +Configure a hidden master nameserver + +This role installs and configures bind9 to be a hidden master +nameserver. + +**Role Variables** + +.. zuul:rolevar:: tsig_key + :type: dict + + The TSIG key used to control named. + + .. zuul:rolevar:: algorithm + + The algorithm used by the key. + + .. zuul:rolevar:: secret + + The secret portion of the key. + +.. zuul:rolevar:: dnssec_keys + :type: dict + + This is a dictionary of DNSSEC keys. Each entry is a dnssec key, + where the dictionary key is the dnssec key id and the value is the + a dictionary with the following contents: + + .. zuul:rolevar:: zone + + The name of the zone for this key. + + .. zuul:rolevar:: public + + The public portion of this key. + + .. zuul:rolevar:: private + + The private portion of this key. + +.. zuul:rolevar:: dns_repos + :type: list + + A list of zone file repos to check out on the server. Each item in + the list is a dictionary with the following keys: + + .. zuul:rolevar:: name + + The name of the repo. + + .. zuul:rolevar:: url + + The URL of the git repository. + +.. zuul:rolevar:: dns_zones + :type: list + + A list of zones that should be served by named. Each item in the + list is a dictionary with the following keys: + + .. zuul:rolevar:: name + + The name of the zone. + + .. zuul:rolevar:: source + + The repo name and path of the directory containing the zone + file. For example if a repo was provided to + :zuul:rolevar:`master-nameserver.dns_repos.name` with the name + ``example.com``, and within that repo, the ``zone.db`` file was + located at ``zones/example_com/zone.db``, then the value here + should be ``example.com/zones/example_com``. + +.. zuul:rolevar:: dns_notify + :type: list + + A list of IP addresses of nameservers which named should notify on + updates. diff --git a/playbooks/roles/master-nameserver/handlers/main.yaml b/playbooks/roles/master-nameserver/handlers/main.yaml new file mode 100644 index 0000000000..55a13392e7 --- /dev/null +++ b/playbooks/roles/master-nameserver/handlers/main.yaml @@ -0,0 +1,2 @@ +- name: Reload named + command: "rndc reload" diff --git a/playbooks/roles/master-nameserver/tasks/main.yaml b/playbooks/roles/master-nameserver/tasks/main.yaml new file mode 100644 index 0000000000..b6f4fa93b4 --- /dev/null +++ b/playbooks/roles/master-nameserver/tasks/main.yaml @@ -0,0 +1,68 @@ +- name: Install packages + package: + name: + - bind9 + - git + - rsync + state: present +- name: Ensure base zone directory exists + file: + path: /var/lib/bind/zones + state: directory +- name: Clone zone repos + git: + repo: "{{ item.url }}" + dest: "/opt/source/{{ item.name }}" + loop: "{{ dns_repos }}" +- name: Synchronize zone repos to zone directories + delegate_to: "{{ inventory_hostname }}" + synchronize: + src: "/opt/source/{{ item.source }}" + dest: "/var/lib/bind/zones/{{ item.name }}" + loop: "{{ dns_zones }}" + notify: Reload named +- name: Install tsig key + no_log: true + template: + src: templates/bind.key.j2 + dest: "/etc/bind/tsig.key" + owner: root + group: bind + mode: 0440 + vars: + key: "{{ tsig_key }}" + name: tsig +- name: Ensure base dnssec key directory exists + file: + path: /etc/bind/keys + state: directory +# The key directories must exist for every zone, regardless of whether +# there are any keys in them. +- name: Ensure zone dnssec key directories exist + loop: "{{ dns_zones }}" + file: + path: "/etc/bind/keys/{{ item.name }}" + state: directory +- name: Install dnssec public keys + loop: "{{ dnssec_keys | dict2items }}" + copy: + dest: "/etc/bind/keys/{{ item.value.zone }}/{{ item.value.zone }}.+008+{{ item.key }}.key" + content: "{{ item.value.public }}" +- name: Install dnssec private keys + no_log: true + loop: "{{ dnssec_keys | dict2items }}" + copy: + dest: "/etc/bind/keys/{{ item.value.zone }}/{{ item.value.zone }}.+008+{{ item.key }}.private" + content: "{{ item.value.private }}" +- name: Install bind config + template: + src: templates/named.conf.j2 + dest: /etc/bind/named.conf + owner: root + group: bind + mode: 0444 + notify: Reload named +- name: Enable named + service: + name: bind9 + enabled: true diff --git a/playbooks/roles/master-nameserver/templates/bind.key.j2 b/playbooks/roles/master-nameserver/templates/bind.key.j2 new file mode 100644 index 0000000000..5f46db2657 --- /dev/null +++ b/playbooks/roles/master-nameserver/templates/bind.key.j2 @@ -0,0 +1,4 @@ +key "{{ name }}" { + algorithm {{ key.algorithm }}; + secret "{{ key.secret }}"; +}; diff --git a/playbooks/roles/master-nameserver/templates/named.conf.j2 b/playbooks/roles/master-nameserver/templates/named.conf.j2 new file mode 100644 index 0000000000..66ebea2ac7 --- /dev/null +++ b/playbooks/roles/master-nameserver/templates/named.conf.j2 @@ -0,0 +1,49 @@ +include "/etc/bind/rndc.key"; +include "/etc/bind/tsig.key"; + +controls { + inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { "rndc-key"; }; +}; + +options { + directory "/var/cache/bind"; + + recursion yes; + allow-query { any; }; + dnssec-enable yes; + dnssec-validation yes; + + empty-zones-enable yes; + + notify yes; +{% if 'address' in ansible_facts.default_ipv6 + and 'scope' in ansible_facts.default_ipv6 + and ansible_facts.default_ipv6.scope == 'global' %} + listen-on-v6 { {{ ansible_facts.default_ipv6.address }}; }; +{% endif %} + + allow-recursion { localnets; localhost; }; + + allow-transfer { key tsig; }; + also-notify { + {% for host in dns_notify %} + {{ host }}; + {% endfor %} + }; + +{% if 'address' in ansible_facts.default_ipv4 %} + listen-on { {{ ansible_facts.default_ipv4.address }}; }; +{% endif %} +}; + +include "/etc/bind/zones.rfc1918"; + +{% for zone in dns_zones %} +zone {{ zone.name }} { + type master; + file "/var/lib/bind/zones/{{ zone.name }}/zone.db"; + key-directory "/etc/bind/keys/{{ zone.name }}"; + auto-dnssec maintain; + inline-signing yes; +}; +{% endfor %} diff --git a/playbooks/zuul/run-base.yaml b/playbooks/zuul/run-base.yaml index eb8c51bc8e..ecb48e058e 100644 --- a/playbooks/zuul/run-base.yaml +++ b/playbooks/zuul/run-base.yaml @@ -58,6 +58,7 @@ dest: "/etc/ansible/hosts/{{ item }}" loop: - group_vars/all.yaml + - group_vars/adns.yaml - group_vars/nodepool.yaml - host_vars/bridge.openstack.org.yaml - name: Display group membership diff --git a/playbooks/zuul/run-production-playbook.yaml b/playbooks/zuul/run-production-playbook.yaml index ac1004461d..d641b4f990 100644 --- a/playbooks/zuul/run-production-playbook.yaml +++ b/playbooks/zuul/run-production-playbook.yaml @@ -9,4 +9,3 @@ tasks: - name: Run specified playbook on bridge.o.o command: ansible-playbook -f {{ ansible_forks }} /opt/system-config/playbooks/{{ playbook_name }} - diff --git a/playbooks/zuul/templates/group_vars/adns.yaml.j2 b/playbooks/zuul/templates/group_vars/adns.yaml.j2 new file mode 100644 index 0000000000..ec16d77a03 --- /dev/null +++ b/playbooks/zuul/templates/group_vars/adns.yaml.j2 @@ -0,0 +1,12 @@ +tsig_key: + algorithm: hmac-md5 + secret: 9zO/4WnUinnLHISPgDI5Aw== +dnssec_keys: + 54873: + zone: zuul-ci.org + public: public_key + private: private_key + 04765: + zone: zuul-ci.org + public: public_key + private: private_key diff --git a/testinfra/test_adns.py b/testinfra/test_adns.py new file mode 100644 index 0000000000..a5418a7d84 --- /dev/null +++ b/testinfra/test_adns.py @@ -0,0 +1,21 @@ +# Copyright 2018 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +testinfra_hosts = ['adns1.opendev.org'] + + +def test_bind(host): + named = host.service('bind9') + assert named.is_running