diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3cf100bd5151bd8e8a5b639494cc3f3f222034ad
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,5 @@
+---
+ansible_lint:
+  image: 'registry.code.fbi.h-da.de/hdacloud/images/netci'
+  script:
+    - ansible-lint
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..2dd29e24f274d5c2bf9ef5e97cb3141ffae82937
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2023 hdacloud
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
index ce4f7e0bf44d1997acd601d7dd2189034a5d7be3..26cca3d50641d6edba380d65605ca91a9457418c 100644
--- a/README.md
+++ b/README.md
@@ -16,3 +16,8 @@ Including an example of how to use your role (for instance, with variables passe
     - hosts: servers
       roles:
          - { role: username.rolename, x: 42 }
+
+License
+-------
+
+See [LICENSE](LICENSE)
diff --git a/defaults/main.yml b/defaults/main.yml
index a4a7ee1b403d35b0b2691b4830480a7801137143..0daf2e52cdb1617acb59f0d7bd6062fc84aa1243 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -1,2 +1,17 @@
 ---
-# defaults file for ansible-certbot
+# certbot settings
+certbot_fqdn:
+  - example.de
+certbot_admin_email: "admin@example.de"
+# certbot_webroot: "/var/www/example"                          # if undefined use --standalone
+
+# application settings
+# certbot_application: "example"                               # if defined copy certs to application dir and setup deploy hooks
+certbot_application_dir: "/etc/{{ certbot_application }}"
+certbot_application_deploy_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/files/.gitkeep b/files/.gitkeep
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/handlers/main.yml b/handlers/main.yml
deleted file mode 100644
index 914cb07e05fb549c37ccd4b7a0a8f174bbc74959..0000000000000000000000000000000000000000
--- a/handlers/main.yml
+++ /dev/null
@@ -1,2 +0,0 @@
----
-# handlers file for ansible-certbot
diff --git a/meta/main.yml b/meta/main.yml
index c572acc9f8b466bea50f2799b0ca1956418b862c..4388dbbaa6a7fc5a96a0ebb60e2c812699282b85 100644
--- a/meta/main.yml
+++ b/meta/main.yml
@@ -1,52 +1,13 @@
 galaxy_info:
-  author: your name
-  description: your role description
-  company: your company (optional)
-
-  # If the issue tracker for your role is not on github, uncomment the
-  # next line and provide a value
-  # issue_tracker_url: http://example.com/issue/tracker
-
-  # Choose a valid license ID from https://spdx.org - some suggested licenses:
-  # - BSD-3-Clause (default)
-  # - MIT
-  # - GPL-2.0-or-later
-  # - GPL-3.0-only
-  # - Apache-2.0
-  # - CC-BY-4.0
-  license: license (GPL-2.0-or-later, MIT, etc)
-
-  min_ansible_version: 2.1
-
-  # If this a Container Enabled role, provide the minimum Ansible Container version.
-  # min_ansible_container_version:
-
-  #
-  # Provide a list of supported platforms, and for each platform a list of versions.
-  # If you don't wish to enumerate all versions for a particular platform, use 'all'.
-  # To view available platforms and versions (or releases), visit:
-  # https://galaxy.ansible.com/api/v1/platforms/
-  #
-  # platforms:
-  # - name: Fedora
-  #   versions:
-  #   - all
-  #   - 25
-  # - name: SomePlatform
-  #   versions:
-  #   - all
-  #   - 1.0
-  #   - 7
-  #   - 99.99
-
-  galaxy_tags: []
-    # List tags for your role here, one per line. A tag is a keyword that describes
-    # and categorizes the role. Users find roles by searching for tags. Be sure to
-    # remove the '[]' above, if you add tags to this list.
-    #
-    # NOTE: A tag is limited to a single word comprised of alphanumeric characters.
-    #       Maximum 20 tags per role.
+  author: hdacloud
+  description: Ansible role to deploy certbot and enable auto-renew
+  license: MIT
+  min_ansible_version: "2.12"
+  platforms:
+    - name: Ubuntu
+    - name: EL # CentOS
+    - name: Debian
+    - name: Fedora
+    - name: Ubuntu
 
 dependencies: []
-  # List your role dependencies here, one per line. Be sure to remove the '[]' above,
-  # if you add dependencies to this list.
diff --git a/tasks/CentOS-packages.yml b/tasks/CentOS-packages.yml
new file mode 100644
index 0000000000000000000000000000000000000000..4915865bff78928e93c539c4911dd3565e7d8f54
--- /dev/null
+++ b/tasks/CentOS-packages.yml
@@ -0,0 +1,10 @@
+---
+- name: Install Certbot
+  ansible.builtin.package:
+    name: # sadly doesn't as a list
+      - "{{ item }}"
+    state: present
+  loop:
+    - epel-release
+    - certbot
+  become: true
diff --git a/tasks/CentOS-timer.yml b/tasks/CentOS-timer.yml
new file mode 100644
index 0000000000000000000000000000000000000000..78b2674c34b706766557eb7528b9510457556136
--- /dev/null
+++ b/tasks/CentOS-timer.yml
@@ -0,0 +1,7 @@
+---
+- name: Enable Letsencrypt Renew Timer
+  ansible.builtin.systemd:
+    name: certbot-renew.timer
+    state: started
+    enabled: true
+  become: true
diff --git a/tasks/Debian-packages.yml b/tasks/Debian-packages.yml
new file mode 100644
index 0000000000000000000000000000000000000000..42ad8f174eba9e90aba720960a8da0b8f6db0434
--- /dev/null
+++ b/tasks/Debian-packages.yml
@@ -0,0 +1,7 @@
+---
+- name: Install Certbot
+  ansible.builtin.apt:
+    name: certbot
+    state: present
+    update_cache: true
+  become: true
diff --git a/tasks/Debian-timer.yml b/tasks/Debian-timer.yml
new file mode 100644
index 0000000000000000000000000000000000000000..519207159281893a5774a0892983a368dbedb600
--- /dev/null
+++ b/tasks/Debian-timer.yml
@@ -0,0 +1,7 @@
+---
+- name: Enable Letsencrypt Renew Timer
+  ansible.builtin.systemd:
+    name: certbot.timer
+    state: started
+    enabled: true
+  become: true
diff --git a/tasks/Fedora-packages.yml b/tasks/Fedora-packages.yml
new file mode 100644
index 0000000000000000000000000000000000000000..5c319309c8e50fa596ada8363c324d5d9a5ae117
--- /dev/null
+++ b/tasks/Fedora-packages.yml
@@ -0,0 +1,6 @@
+---
+- name: Install Certbot
+  ansible.builtin.package:
+    name: certbot
+    state: present
+  become: true
diff --git a/tasks/Fedora-timer.yml b/tasks/Fedora-timer.yml
new file mode 100644
index 0000000000000000000000000000000000000000..78b2674c34b706766557eb7528b9510457556136
--- /dev/null
+++ b/tasks/Fedora-timer.yml
@@ -0,0 +1,7 @@
+---
+- name: Enable Letsencrypt Renew Timer
+  ansible.builtin.systemd:
+    name: certbot-renew.timer
+    state: started
+    enabled: true
+  become: true
diff --git a/tasks/Ubuntu-packages.yml b/tasks/Ubuntu-packages.yml
new file mode 100644
index 0000000000000000000000000000000000000000..42ad8f174eba9e90aba720960a8da0b8f6db0434
--- /dev/null
+++ b/tasks/Ubuntu-packages.yml
@@ -0,0 +1,7 @@
+---
+- name: Install Certbot
+  ansible.builtin.apt:
+    name: certbot
+    state: present
+    update_cache: true
+  become: true
diff --git a/tasks/Ubuntu-timer.yml b/tasks/Ubuntu-timer.yml
new file mode 100644
index 0000000000000000000000000000000000000000..519207159281893a5774a0892983a368dbedb600
--- /dev/null
+++ b/tasks/Ubuntu-timer.yml
@@ -0,0 +1,7 @@
+---
+- name: Enable Letsencrypt Renew Timer
+  ansible.builtin.systemd:
+    name: certbot.timer
+    state: started
+    enabled: true
+  become: true
diff --git a/tasks/application.yml b/tasks/application.yml
new file mode 100644
index 0000000000000000000000000000000000000000..b9bf4b4841d33071aba2d4ae942bca6c5cdf8036
--- /dev/null
+++ b/tasks/application.yml
@@ -0,0 +1,34 @@
+---
+- name: Ensure Application Certificate Directory exists
+  ansible.builtin.file:
+    path: "{{ certbot_application_dir }}"
+    state: directory
+    owner: root
+    group: root
+    mode: "0755"
+  become: true
+
+- name: Check Whether Application Cert Exists
+  ansible.builtin.stat:
+    path: "{{ certbot_application_dir }}/fullchain.pem"
+  register: leoacert
+  become: true
+
+- name: Setup Application Deploy Hook
+  ansible.builtin.copy:
+    dest: "/etc/letsencrypt/renewal-hooks/deploy/{{ certbot_application }}"
+    content: "{{ certbot_application_deploy_hook }}"
+    mode: "0755"
+  become: true
+
+- name: Copy Application Cert If Necessary
+  ansible.builtin.copy:
+    src: "{{ item }}"
+    dest: "{{ certbot_application_dir }}"
+    remote_src: true
+    mode: "0644"
+  loop:
+    - "{{ certbot_live_dir }}/fullchain.pem"
+    - "{{ certbot_live_dir }}/privkey.pem"
+  when: not leoacert.stat.exists
+  become: true
diff --git a/tasks/main.yml b/tasks/main.yml
index 3813d8da3d261a9c33128cfed3b5cf6f0ea28401..3cc640a31d76361ef1fc41cb1c2a1ab1233b7ef6 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -1,2 +1,58 @@
 ---
-# tasks file for ansible-certbot
+# TODO:
+#   - dns challenge
+
+- name: Install Packages Based On Distribution
+  ansible.builtin.include_tasks: "{{ ansible_facts.distribution }}-packages.yml"
+
+- name: Check Whether Cert Exists
+  ansible.builtin.stat:
+    path: "{{ certbot_live_dir }}/cert.pem"
+  register: lecert
+  become: true
+
+- name: Ensure Deploy Hook Dir Exists
+  ansible.builtin.file:
+    path: "{{ item }}"
+    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 }}
+  when: not lecert.stat.exists and not certbot_webroot is defined
+  register: cbstandalone
+  changed_when: cbstandalone.rc == 0
+  become: true
+
+- name: Ensure Webroot Path Exists
+  ansible.builtin.file:
+    path: "{{ certbot_webroot }}"
+    state: directory
+    mode: "0755"
+    owner: root
+    group: root
+  when: not lecert.stat.exists and certbot_webroot is defined
+
+- 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 }}
+  when: not lecert.stat.exists and certbot_webroot is defined
+  register: cbwebroot
+  changed_when: cbwebroot.rc == 0
+  become: true
+
+- name: Setup Certbot With Application
+  ansible.builtin.include_tasks: "application.yml"
+  when: certbot_application is defined
+
+- name: Enable Letsencrypt Renew Timer Based On Distribution
+  ansible.builtin.include_tasks: "{{ ansible_facts.distribution }}-timer.yml"
diff --git a/templates/.gitkeep b/templates/.gitkeep
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/tests/inventory b/tests/inventory
deleted file mode 100644
index 878877b0776c44f55fc4e458f70840f31da5bb01..0000000000000000000000000000000000000000
--- a/tests/inventory
+++ /dev/null
@@ -1,2 +0,0 @@
-localhost
-
diff --git a/tests/test.yml b/tests/test.yml
deleted file mode 100644
index 792d81aa7f58329bdacf710d8b83d0c74b10f51a..0000000000000000000000000000000000000000
--- a/tests/test.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-- hosts: localhost
-  remote_user: root
-  roles:
-    - ansible-certbot
diff --git a/vars/main.yml b/vars/main.yml
index 8feed124f0c1cf2418fd622b50b173ada5c46a57..d12eca560203f5505c97f30a0a9bf820ad5f1208 100644
--- a/vars/main.yml
+++ b/vars/main.yml
@@ -1,2 +1,9 @@
 ---
-# vars file for ansible-certbot
+certbot_live_dir: >-
+  /etc/letsencrypt/live/{{
+    certbot_fqdn
+    | first
+    | replace("*.", "")
+    | trim(".")
+  }}
+certbot_dflag: "{{ certbot_fqdn | map('trim', '.') | join(',') }}"