diff --git a/README.md b/README.md
index 7a344376647dac7500bf39e03602a379103ae291..7aa8b738ce73fd02f318babfe58c7bf23cb21bf1 100644
--- a/README.md
+++ b/README.md
@@ -1,50 +1,50 @@
-ansible-certbot
-=========
+# hdacloud.certs
 
-Deploy certbot and enable auto-renew.
+Role to obtain certificates from Let's Encrypt using either [certbot][certbot] or [lego-acme][lego-acme].
+Refer to the variables below to obtain certificates.
 
-Role Variables
---------------
+## Role Variables
 
-```yaml
----
-# certbot settings
-certbot_dns_challenge: false                                                          # default use webserver, true to obtain certificate using dns challenge
-certbot_lego_version: "4.11.0"                                                        # lego version - Let's Encrypt client
-certbot_dns_provider: "designate"                                                     # list of available providers https://go-acme.github.io/lego/dns/
-dns_provider_auth_env_variables:                                                      # variables required to authenticate dns provider
-  OS_AUTH_URL: "https://openstack.example.org"
-  OS_REGION_NAME: "RegionOne"
-  OS_AUTH_TYP: "v3applicationcredential"                                              # default is to use application credential rather than password
-  OS_APPLICATION_CREDENTIAL_ID: "{{ vault_os_application_credential_id }}"
-  OS_APPLICATION_CREDENTIAL_SECRET: "{{ vault_os_application_credential_secret }}"
-
-certbot_fqdn:
-  - example.de
-certbot_admin_email: "admin@example.de"
-# certbot_webroot: "/var/www/example"                                                 # if undefined use --standalone
-
-# LEGO Settings
-lego_extra_flags: []
-
-# renewal settings
-certbot_renewal_hook_file_name: "example"
-certbot_renewal_hook: |
-  #!/bin/sh
-
-  cp {{ certbot_live_dir }}/fullchain.pem {{ certbot_application_dir }}
-  cp {{ certbot_live_dir }}/privkey.pem {{ certbot_application_dir }}
-
-  systemctl restart {{ certbot_application }}.service
-```
+The role variables are split up into three categories. A general one and two specialized sets of variables
+depending on whether or not you are using `dns_challenge` or not.
+
+### General Settings
+
+| Variable | Description | Type | Default |
+|---|---|---|---|
+| `cert_fqdns` | List of FQDNs the certificate should be valid for | `List<string>` | `[]` |
+| `admin_email` | Email for expiry notifications | `string` | `''` |
+| `dns_challenge` | Whether to use a dns challenge for obtaining certificates. Refer to 'DNS challenge settings' if true, otherwise to section 'WebServer Settings' | `boolean` | `false` |
+| `renewal_hook_file_name` | Filename of the renewal script file | `string` | `''` |
+| `renewal_hook` | Contents of the renewal script. this should be used to restart services after a new certificate has been obtained. | `string` | `''` |
+
+
+### DNS Challenge: `true`
+
+These settings need to be provided when a DNS challenge is used.
 
-Example Playbook
-----------------
+| Variable | Description | Type | Default |
+|---|---|---|---|
+| `lego_version` | The version of the [lego-acme][lego-acme] client binary to be used. | `string` | `4.11.0` |
+| `lego_extra_flags` | Additional arguments / flags to be passed to the `lego` command. | `List<string>` | `[]` |
+| `lego_dns_provider` | The DNS provider to be used for the DNS challenge. A full list of the supported providers can be found [here][lego-dns-providers]. | `string` | `designate` |
+| `dns_provider_auth_env_variables` | Dictionary of environment variables used by the selected DNS provider. | `Dictionary<string, string>` | `{}` |
+
+
+### DNS Challenge: `false`
+
+These settings optionally need to be provided when no DNS challenge is used.
+
+| Variable | Description | Type | Default |
+|---|---|---|---|
+| `certbot_webroot` | If you are already running a web server on your instance provide a path that is served on port `80` here, to allow the HTTP challenge to be completed when obtaining the certificate. | `string` | `undefined` |
+
+## Example Playbook
 
 ```yaml
 # requirements.yaml
 roles:
-  - name: hdacloud.certbot
+  - name: hdacloud.certs
     src: git+https://code.fbi.h-da.de/hdacloud/ansible_certbot
     version: main
 ```
@@ -59,15 +59,18 @@ roles:
 
 In some cases you might need the certificates split up into the cert itself and a separate fullchain certificate
 chain. For this case you need to add the `--no-bundle` option to the `lego_extra_flags` array. Then add the
-following to the `certbot_renewal_hook` script (replacing variables accordingly):
+following to the `renewal_hook` script (replacing variables accordingly):
 
 ```sh
-rm "/etc/letsencrypt/live/fullchain.pem"
-cat "/etc/letsencrypt/live/certificates/{{ certbot_fqdn_first }}.crt" >> "/etc/letsencrypt/live/fullchain.pem" &&
-cat "/etc/letsencrypt/live/certificates/{{ certbot_fqdn_first }}.issuer.crt" >> "/etc/letsencrypt/live/fullchain.pem"
+rm -f /var/lib/lego/fullchain.pem
+cat /var/lib/lego/certificates/<cert_fqdns_first>.crt >> <wherever>/fullchain.pem &&
+cat /var/lib/lego/certificates/<cert_fqdns_first>.issuer.crt >> <wherever>/fullchain.pem
 ```
 
-License
--------
+# License
 
 See [LICENSE](LICENSE)
+
+[lego-acme]: https://go-acme.github.io/lego/ 'LEGO ACME'
+[certbot]: https://certbot.eff.org/ 'EFF Certbot'
+[lego-dns-providers]: https://go-acme.github.io/lego/dns/#dns-providers 'LEGO: DNS Providers'
diff --git a/defaults/main.yml b/defaults/main.yml
index eea0c5c98de5b73360c6324944a4b551e2566abf..ab9861e95758a5a2695a0e9701050c364d600b4f 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -14,30 +14,15 @@ certbot_timer_name:
   Fedora: "certbot-renew.timer"
 
 # certbot settings
-certbot_dns_challenge: false                                                          # default use webserver, true to obtain certificate using dns challenge
-certbot_lego_version: "4.11.0"                                                        # lego version - Let's Encrypt client
-certbot_dns_provider: "designate"                                                     # list of available providers https://go-acme.github.io/lego/dns/
-dns_provider_auth_env_variables:                                                      # variables required to authenticate dns provider
-  OS_AUTH_URL: "https://openstack.example.org"
-  OS_REGION_NAME: "RegionOne"
-  OS_AUTH_TYP: "v3applicationcredential"                                              # default is to use application credential rather than password
-  OS_APPLICATION_CREDENTIAL_ID: "{{ vault_os_application_credential_id }}"
-  OS_APPLICATION_CREDENTIAL_SECRET: "{{ vault_os_application_credential_secret }}"
+dns_challenge: false                                                                  # default use webserver, true to obtain certificate using dns challenge
+lego_version: "4.11.0"                                                                # lego version - Let's Encrypt client
+lego_dns_provider: "designate"                                                        # list of available providers https://go-acme.github.io/lego/dns/
+dns_provider_auth_env_variables: {}                                                    # variables required to authenticate dns provider
 
-certbot_fqdn:
+cert_fqdns:
   - example.de
-certbot_admin_email: "admin@example.de"
-# certbot_webroot: "/var/www/example"                                                 # if undefined use --standalone
+admin_email: "admin@example.de"
+
 
 # LEGO Settings
 lego_extra_flags: []
-
-# renewal settings
-certbot_renewal_hook_file_name: "example"
-certbot_renewal_hook: |
-  #!/bin/sh
-
-  cp {{ certbot_live_dir }}/fullchain.pem {{ certbot_application_dir }}
-  cp {{ certbot_live_dir }}/privkey.pem {{ certbot_application_dir }}
-
-  systemctl restart {{ certbot_application }}.service
diff --git a/tasks/dns-challenge.yml b/tasks/dns-challenge.yml
index 8916ec2e04cd16dc2b21f127d376f67847b66c15..9ea5d7d8eb3071027501d57d2719800aa945a959 100644
--- a/tasks/dns-challenge.yml
+++ b/tasks/dns-challenge.yml
@@ -1,68 +1,51 @@
 - name: Fetch Binary
   ansible.builtin.get_url:
-    url: "https://github.com/go-acme/lego/releases/download/v{{ certbot_lego_version }}/lego_v{{ certbot_lego_version }}_linux_amd64.tar.gz"
-    dest: "/tmp/lego_v{{ certbot_lego_version }}_linux_amd64.tar.gz"
+    url: "https://github.com/go-acme/lego/releases/download/v{{ lego_version }}/lego_v{{ lego_version }}_linux_amd64.tar.gz"
+    dest: "/tmp/lego_v{{ lego_version }}_linux_amd64.tar.gz"
     mode: "0644"
 
 - name: Unpack Archive
   ansible.builtin.unarchive:
-    src: "/tmp/lego_v{{ certbot_lego_version }}_linux_amd64.tar.gz"
+    src: "/tmp/lego_v{{ lego_version }}_linux_amd64.tar.gz"
     dest: "/tmp"
     remote_src: true
 
 - name: Copy Binary
   ansible.builtin.copy:
     src: /tmp/lego
-    dest: /usr/bin/lego
+    dest: /usr/local/bin/lego
     owner: root
     group: root
     mode: '0755'
     remote_src: true
   become: true
 
-- name: Check Whether Cert Exists
-  ansible.builtin.stat:
-    path: "{{ certbot_live_dir }}/fullchain.pem"
-  register: lecert
+- name: Create lego directories
   become: true
-
-- name: Ensure Deploy Hook Dir Exists
   ansible.builtin.file:
-    path: "{{ item }}"
     state: directory
+    path: "{{ lego_path }}/renewal-hooks" # all intermediate subdirectories will be created
     mode: "0755"
     owner: root
     group: root
-  loop:
-    - /etc/letsencrypt/renewal-hooks
-    - /etc/letsencrypt/renewal-hooks/deploy
+
+- name: Check Whether Cert Exists
+  ansible.builtin.stat:
+    path: "{{ lego_path }}/certificates/{{ cert_fqdns_first }}.crt"
+  register: lego_cert
   become: true
 
 - name: Request Cert If Necessary - DNS Challenge
-  when: not lecert.stat.exists
+  when: not lego_cert.stat.exists
   become: true
-  block:
-    - name: Request Cert
-      ansible.builtin.command: >-
-        lego -a --dns {{ certbot_dns_provider }}
-        --email {{ certbot_admin_email }} -d {{ lego_dflag }}
-        --path {{ certbot_live_dir }}
-        run --no-bundle
-      environment: "{{ dns_provider_auth_env_variables }}"
-      register: lego
-      changed_when: lego.rc == 0
-
-    - name: Mirror Letsencrypt Structure
-      ansible.builtin.copy:
-        src: "{{ item.src }}"
-        dest: "{{ item.dest }}"
-        owner: root
-        group: root
-        mode: '0600'
-        remote_src: true
-      loop:
-        - { src: "{{ certbot_live_dir }}/certificates/{{ certbot_fqdn_first }}.crt", dest: "{{ certbot_live_dir }}/cert.pem" }
-        - { src: "{{ certbot_live_dir }}/certificates/{{ certbot_fqdn_first }}.key", dest: "{{ certbot_live_dir }}/privkey.pem" }
+  ansible.builtin.command: >-
+    lego -a --dns {{ lego_dns_provider }}
+    --email {{ admin_email }} -d {{ lego_dflag }}
+    --path {{ lego_path }}
+    run {% for f in lego_extra_flags %}{{ f }} {% endfor %}
+  environment: "{{ dns_provider_auth_env_variables }}"
+  register: lego
+  changed_when: lego.rc == 0
 
 - name: Render Systemd Files
   become: true
@@ -76,18 +59,18 @@
     - name: Render Systemd Service File
       ansible.builtin.template:
         src: templates/dns-challenge.service.j2
-        dest: /lib/systemd/system/dns-challenge.service
+        dest: /etc/systemd/system/dns-challenge.service
         mode: "0644"
 
     - name: Render Systemd Timer File
       ansible.builtin.template:
         src: templates/dns-challenge.timer.j2
-        dest: /lib/systemd/system/dns-challenge.timer
+        dest: /etc/systemd/system/dns-challenge.timer
         mode: "0644"
 
 - name: Setup renewal hook
   ansible.builtin.include_tasks: "renewal-hook.yml"
-  when: certbot_renewal_hook is defined
+  when: renewal_hook is defined
 
 - name: Enable LEGO Renew Timer
   ansible.builtin.systemd:
diff --git a/tasks/main.yml b/tasks/main.yml
index a97d708121d71398f8e54f12ca9ae0962ee188e1..cb686c25063f58d063c56d28d28a8ef52cb5db85 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -1,8 +1,8 @@
 ---
 - name: Obtain Cert Using Web Server
   ansible.builtin.include_tasks: "webserver.yml"
-  when: not certbot_dns_challenge
+  when: not dns_challenge
 
 - name: Obtain Cert DNS Challenge
   ansible.builtin.include_tasks: "dns-challenge.yml"
-  when: certbot_dns_challenge
+  when: dns_challenge
diff --git a/tasks/renewal-hook.yml b/tasks/renewal-hook.yml
index a24a31c7a80e31b7ec008a6f7b7e7c1a5c558c3e..5eb30f89cecad84e3a80270ce8cda2c0dc6dee82 100644
--- a/tasks/renewal-hook.yml
+++ b/tasks/renewal-hook.yml
@@ -1,7 +1,7 @@
 ---
 - name: Setup Renewal Hook
   ansible.builtin.copy:
-    dest: "/etc/letsencrypt/renewal-hooks/deploy/{{ certbot_renewal_hook_file_name }}"
-    content: "{{ certbot_renewal_hook }}"
+    dest: "{{ dns_challenge | ternary(lego_path + '/renewal-hooks/', '/etc/letsencrypt/renewal-hooks/deploy/') }}{{ renewal_hook_file_name }}"
+    content: "{{ renewal_hook }}"
     mode: "0755"
   become: true
diff --git a/tasks/webserver.yml b/tasks/webserver.yml
index 06f4e649f3a990c95b379bb6af3a0c5fbc71a23d..f2e96f89ead8980de72f13c2dd97e61c4f061ff3 100644
--- a/tasks/webserver.yml
+++ b/tasks/webserver.yml
@@ -28,20 +28,17 @@
 
 - name: Ensure Deploy Hook Dir Exists
   ansible.builtin.file:
-    path: "{{ item }}"
+    path: /etc/letsencrypt/renewal-hooks/deploy
     state: directory
     mode: "0755"
     owner: root
     group: root
-  loop:
-    - /etc/letsencrypt/renewal-hooks
-    - /etc/letsencrypt/renewal-hooks/deploy
   become: true
 
 - name: Request Cert If Necessary - Standalone
   ansible.builtin.command: >-
     certbot certonly --standalone --noninteractive --agree-tos
-    --email {{ certbot_admin_email }} -d {{ certbot_dflag }}
+    --email {{ admin_email }} -d {{ certbot_dflag }}
   when: not lecert.stat.exists and not certbot_webroot is defined
   register: cbstandalone
   changed_when: cbstandalone.rc == 0
@@ -59,7 +56,7 @@
 - name: Request Cert If Necessary - Webroot
   ansible.builtin.command: >-
     certbot certonly --webroot --webroot-path {{ certbot_webroot }} --noninteractive --agree-tos
-    --email {{ certbot_admin_email }} -d {{ certbot_dflag }}
+    --email {{ admin_email }} -d {{ certbot_dflag }}
   when: not lecert.stat.exists and certbot_webroot is defined
   register: cbwebroot
   changed_when: cbwebroot.rc == 0
@@ -67,7 +64,7 @@
 
 - name: Setup Certbot renewal hook
   ansible.builtin.include_tasks: "renewal-hook.yml"
-  when: certbot_renewal_hook is defined
+  when: renewal_hook is defined
 
 - name: Enable Letsencrypt Renew Timer Based On Distribution
   become: true
diff --git a/templates/dns-challenge.service.j2 b/templates/dns-challenge.service.j2
index 695172dbb39851e1faa54b3980912e1b2fd2a7ce..433f085812c2a3ba9e73ad74218f05235a316dbe 100644
--- a/templates/dns-challenge.service.j2
+++ b/templates/dns-challenge.service.j2
@@ -5,7 +5,5 @@ Description=LEGO DNS challenge
 
 [Service]
 Type=oneshot
-ExecStart=/usr/bin/lego -a --dns {{ certbot_dns_provider }} --email {{ certbot_admin_email }} -d {{ lego_dflag }} --path {{ certbot_live_dir }} renew {% for f in lego_extra_flags %}{{ f }} {% endfor %} {{ '--renew-hook /etc/letsencrypt/renewal-hooks/deploy/' + certbot_renewal_hook_file_name if certbot_renewal_hook is defined else ''}}
-ExecStartPost=cp {{ certbot_live_dir }}/certificates/{{ certbot_fqdn_first }}.crt {{ certbot_live_dir }}/cert.pem
-ExecStartPost=cp {{ certbot_live_dir }}/certificates/{{ certbot_fqdn_first }}.key {{ certbot_live_dir }}/privkey.pem
+ExecStart=/usr/local/bin/lego -a --dns {{ lego_dns_provider }} --email {{ admin_email }} -d {{ lego_dflag }} --path {{ lego_path }} renew {% for f in lego_extra_flags %}{{ f }} {% endfor %} {{ '--renew-hook ' + lego_path + '/renewal-hooks/' + renewal_hook_file_name if renewal_hook is defined else ''}}
 EnvironmentFile=/etc/default/dns-challenge.env
diff --git a/vars/main.yml b/vars/main.yml
index e55bd962c4da69fa300b421949e5cbbc31ccc611..2c1154e6a275cee553bc16cec29225e684703c20 100644
--- a/vars/main.yml
+++ b/vars/main.yml
@@ -1,11 +1,16 @@
 ---
-certbot_fqdn_first: >-
+cert_fqdns_first: >-
   {{
-    certbot_fqdn
+    cert_fqdns
     | first
     | replace("*.", "")
     | trim(".")
   }}
-certbot_live_dir: "/etc/letsencrypt/live/{{ certbot_fqdn_first }}"
-certbot_dflag: "{{ certbot_fqdn | map('trim', '.') | join(',') }}"
-lego_dflag: "{{ certbot_fqdn | map('trim', '.') | join(' -d ') }}"
+
+# Certbot
+certbot_live_dir: "/etc/letsencrypt/live/{{ cert_fqdns_first }}"
+certbot_dflag: "{{ cert_fqdns | map('trim', '.') | join(',') }}"
+
+# LEGO (when DNS challenge)
+lego_path: /var/lib/lego
+lego_dflag: "{{ cert_fqdns | map('trim', '.') | join(' -d ') }}"