diff --git a/README.rst b/README.rst
index 57d46644822eafd37f69bd645605f3a4b467e66e..fcb31aceb8ee7036dab95d4a6769da35c0737c32 100644
--- a/README.rst
+++ b/README.rst
@@ -5,14 +5,13 @@ NSD
     :target: https://travis-ci.org/adarnimrod/nsd
 
 Provision an NSD authorative DNS server. By default the role has minimal
-configuration. You can add your own by overriding the default
-:code:`nsd_config` dictionary with your own for configuration under the
-:code:`server` block in :code:`nsd.conf`. For other blocks that can declared
-multiple times (like the :code:`zone` block) add your own templates in the
-:code:`templates/nsd/conf.d` directory either inside the role or next to your
-playbook. Likewise, zone templates can be added by placing them in
-:code:`templates/nsd/zones` (again either inside the role or relative to your
-playbook).
+configuration. Overriding :code:`nsd_server_block` with a text block will
+configure the :code:`server` clause of NSD, same for
+:code:`nsd_remote_control_block` and the :code:`remote-control` block. Multiple
+patterns, zones and keys are provided by overriding :code:`nsd_patterns`,
+:code:`nsd_zones` and :code:`nsd_keys` respectively. Zone file templates can be
+added by placing them in :code:`templates/nsd/zones` either inside the role or
+relative to your playbook.
 
 Requirements
 ------------
diff --git a/defaults/main.yml b/defaults/main.yml
index 69ca08bcca695a7867e5d10f89760007d8569d18..9b04799a896d1a8240dbb37ab287fdb82f1bce8b 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -2,7 +2,13 @@
 # defaults file for nsd
 
 nsd_mail_alias: root # Where to send mail for the NSD user.
-nsd_config: # key/value configuration under the server block, for more
-            # information consult the nsd.conf man page.
-    'rrl-ratelimit': 200
-    'rrl-whitelist-ratelimit': 2000
+nsd_server_block: |
+    rrl-ratelimit: 200
+    rrl-whitelist-ratelimit: 2000
+
+nsd_remote_control_block: |
+    control-enable: no
+
+nsd_patterns: []
+nsd_keys: []
+nsd_zones: []
diff --git a/tasks/main.yml b/tasks/main.yml
index e01ddecc3bdde982d6f41df89ec0250846afeb5f..4ab4e317aa8b9dba9cef28896613ab7a1eb6d9de 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -6,7 +6,11 @@
     that:
         - ansible_os_family in nsd_user
         - ansible_os_family in aliases_file
-        - nsd_config is iterable
+        - nsd_server_block is defined
+        - nsd_remote_control_block is defined
+        - nsd_patterns is iterable
+        - nsd_keys is iterable
+        - nsd_zones is iterable
 
 - name: APT install NSD
   when: ansible_pkg_mgr == 'apt'
@@ -16,60 +20,31 @@
       update_cache: yes
       cache_valid_time: 3600
 
-- name: Create conf.d directory
+- name: Create zones directory
   file:
-      path: '{{ nsd_conf_d }}'
+      path: '{{ nsd_zones_dir }}'
       state: directory
       owner: root
       group: 0
       mode: 0o755
 
-- name: Use the conf.d directory
-  lineinfile:
-      dest: '{{ nsd_conf }}'
-      line: 'include: "{{ nsd_conf_d }}/*.conf"'
-      insertafter: EOF
-      state: present
-  notify:
-      - Restart NSD
-
-- name: Add server block
-  lineinfile:
-      dest: '{{ nsd_conf }}'
-      line: 'server:'
-      insertbefore: BOF
-      state: present
-
 - name: Configure
-  with_dict: '{{ nsd_config }}'
-  lineinfile:
-      dest: '{{ nsd_conf }}'
-      line: '{{ item.key }}: {{ item.value }}'
-      regexp: '{{ item.key }}:'
-      insertafter: 'server:'
-  notify:
-      - Restart NSD
-
-- name: Copy configuration templates
-  with_fileglob:
-      - '{{ role_path }}/templates/nsd/conf.d/*'
-      - '{{ playbook_dir }}/templates/nsd/conf.d/*'
   template:
-      src: '{{ item }}'
-      dest: '{{ nsd_conf_d }}/'
+      src: nsd.conf.j2
+      dest: '{{ nsd_conf }}'
       owner: root
       group: 0
-      mode: 0o644
+      mode: 0o0644
   notify:
       - Restart NSD
 
-- name: Copy zones
+- name: Copy zone templates
   with_fileglob:
       - '{{ role_path }}/templates/nsd/zones/*'
       - '{{ playbook_dir }}/templates/nsd/zones/*'
   template:
       src: '{{ item }}'
-      dest: '{{ nsd_zones }}/'
+      dest: '{{ nsd_zones_dir }}/'
       owner: root
       group: 0
       mode: 0o644
diff --git a/templates/nsd.conf.j2 b/templates/nsd.conf.j2
new file mode 100644
index 0000000000000000000000000000000000000000..c2487168c623b30d1b073e88515e2a798c434148
--- /dev/null
+++ b/templates/nsd.conf.j2
@@ -0,0 +1,23 @@
+server:
+{{ nsd_server_block }}
+
+remote-control:
+{{ nsd_remote_control_block }}
+
+{% for pattern in nsd_patterns %}
+pattern:
+{{ pattern }}
+
+{% endfor %}
+
+{% for key in nsd_keys %}
+key:
+{{ key }}
+
+{% endfor %}
+
+{% for zone in nsd_zones %}
+zone:
+{{ zone }}
+
+{% endfor %}
diff --git a/tests/playbook.yml b/tests/playbook.yml
index 84aceb6b80edfe27654b12441c1ea41e76a43eb9..1c4d4601246431a4795c47b2f95de91d30ead6c8 100644
--- a/tests/playbook.yml
+++ b/tests/playbook.yml
@@ -11,18 +11,12 @@
   strategy: free
   roles:
     - role: nsd
+      nsd_zones:
+          - |
+              name: "testzone"
+              zonefile: "testzone"
   post_tasks:
-      - name: Copy test zone
-        with_items:
-            - src: templates/nsd_conf_d/testzone.conf
-              dest: '{{ nsd_conf_d }}/testzone.conf'
-            - src: templates/nsd_zones/testzone
-              dest: '{{ nsd_zones }}/testzone'
-        template:
-            src: '{{ item.src }}'
-            dest: '{{ item.dest }}'
-            owner: root
-            group: 0
-            mode: 0o0644
-        notify:
-            - Restart NSD
+      - name: APT install test utilities
+        apt:
+            name: [net-tools, dnsutils]
+            state: present
diff --git a/tests/templates/nsd_zones/testzone b/tests/templates/nsd/zones/testzone
similarity index 100%
rename from tests/templates/nsd_zones/testzone
rename to tests/templates/nsd/zones/testzone
diff --git a/tests/templates/nsd_conf_d/testzone.conf b/tests/templates/nsd_conf_d/testzone.conf
deleted file mode 100644
index aa87ffe2743c72ba9cc86f7ed83615701c36fb7f..0000000000000000000000000000000000000000
--- a/tests/templates/nsd_conf_d/testzone.conf
+++ /dev/null
@@ -1,3 +0,0 @@
-zone:
-    name: "testzone"
-    zonefile: "testzone"
diff --git a/vars/main.yml b/vars/main.yml
index 872791f150f09634e9692538b519df54e3d5c057..1242f8d99de32936c33b3f62167a26a0d9e81a24 100644
--- a/vars/main.yml
+++ b/vars/main.yml
@@ -2,8 +2,7 @@
 # vars file for nsd
 
 nsd_conf: '{{ "/var/nsd/etc/nsd.conf" if ansible_os_family == "OpenBSD" else "/etc/nsd/nsd.conf" }}'
-nsd_conf_d: '{{ nsd_conf }}.d'
-nsd_zones: '{{ "/var/nsd/zones" if ansible_os_family == "OpenBSD" else "/etc/nsd" }}'
+nsd_zones_dir: '{{ "/var/nsd/zones" if ansible_os_family == "OpenBSD" else "/etc/nsd" }}'
 
 aliases_file:
     OpenBSD: /etc/mail/aliases