diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 0000000..e23cd71
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,23 @@
+name: Ansible
+on:
+  push:
+    branches: [ main ]
+  pull_request:
+    branches: [ main ]
+  workflow_dispatch:
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+
+      - name: Install ansible
+        run: |
+          sudo apt install software-properties-common
+          sudo add-apt-repository --yes --update ppa:ansible/ansible
+          sudo apt install ansible
+      
+      # Check syntax for all ansible playbooks
+      - name: Validate all playbooks
+        run: ansible-playbook ansible/*.yml --syntax-check
\ No newline at end of file
diff --git a/ansible/0-checks.yml b/ansible/0-checks.yml
index b93ac89..bb6f178 100644
--- a/ansible/0-checks.yml
+++ b/ansible/0-checks.yml
@@ -2,16 +2,11 @@
 - name: Configure SSH
   hosts: all
   tasks:
-    - name: Add hosts to known_hosts
-      shell: "ssh-keyscan -H {{ hostvars[item].ansible_host }} >> ~/.ssh/known_hosts"
-      delegate_to: localhost
-      run_once: yes
-      loop: "{{ groups['proxy'] + groups['gateway'] }}"
     - name: Check SSH connection
-      command: hostname
+      ansible.builtin.command: hostname
     - name: Update and upgrade apt packages
-      become: yes
-      apt:
-        upgrade: yes
-        update_cache: yes
+      become: true
+      ansible.builtin.apt:
+        upgrade: true
+        update_cache: true
         cache_valid_time: 86400
\ No newline at end of file
diff --git a/ansible/1-duckdns.yml b/ansible/1-duckdns.yml
index e17817f..84c43cd 100644
--- a/ansible/1-duckdns.yml
+++ b/ansible/1-duckdns.yml
@@ -3,10 +3,10 @@
   hosts: gateway
   tasks:
     - name: Install docker
-      become: yes
+      become: true
       shell: "apt install docker.io -y"
     - name: Create a duckdns container
-      become: yes
+      become: true
       community.docker.docker_container:
         name: duckdns
         image: lscr.io/linuxserver/duckdns:latest
diff --git a/ansible/2-unattended-upgrades.yml b/ansible/2-unattended-upgrades.yml
index b284fd8..90f83cb 100644
--- a/ansible/2-unattended-upgrades.yml
+++ b/ansible/2-unattended-upgrades.yml
@@ -1,32 +1,32 @@
 ---
 - name: Configure unattended-upgrades
   hosts: all
-  become: yes
+  become: true
   tasks:
     - name: Install unattended-upgrades
-      apt:
+      ansible.builtin.apt:
         pkg: "unattended-upgrades"
         state: "present"
 
     # ref. https://wiki.debian.org/UnattendedUpgrades
     - name: Create apt file that would be made by interactive dpkg-reconfigure
-      file:
+      ansible.builtin.file:
         path: "/etc/apt/apt.conf.d/20auto-upgrades"
         owner: "root"
         group: "root"
         mode: "0644"
         state: "touch"
     - name: "Populate 20auto-upgrades apt file"
-      lineinfile:
+      ansible.builtin.lineinfile:
         dest: "/etc/apt/apt.conf.d/20auto-upgrades"
-        line: '{{item}}'
+        line: '{{ item }}'
       with_items:
         - 'APT::Periodic::Update-Package-Lists "1";'
         - 'APT::Periodic::Unattended-Upgrade "1";'
 
     # ref. https://help.ubuntu.com/community/Lubuntu/Documentation/RemoveOldKernels#Shell
     - name: Enable remove unused deps in /etc/apt/apt.conf.d/50unattended-upgrades
-      lineinfile:
+      ansible.builtin.lineinfile:
         dest: "/etc/apt/apt.conf.d/50unattended-upgrades"
         line: 'Unattended-Upgrade::Remove-Unused-Dependencies "true";'
         insertafter: '^//Unattended-Upgrade::Remove-Unused-Dependencies'
\ No newline at end of file
diff --git a/ansible/3-wireguard.yml b/ansible/3-wireguard.yml
index 1a5fd5d..bb20894 100644
--- a/ansible/3-wireguard.yml
+++ b/ansible/3-wireguard.yml
@@ -1,10 +1,9 @@
 ---
-- name: Configure SSH
-  hosts: all
-  gather_facts: no
+- hosts: all
+  gather_facts: false
   tasks:
     - name: Install Wireguard
-      become: yes
+      become: true
       ansible.builtin.package:
         name: wireguard-tools
         state: present
@@ -14,7 +13,7 @@
       delay: 10
 
 - hosts: proxy
-  become: yes
+  become: true
   tasks:
     - name: Generate Wireguard keys on proxy
       shell: "wg genkey | tee privatekey_proxy | wg pubkey > publickey_proxy"
@@ -30,7 +29,7 @@
       register: private_key_proxy
 
 - hosts: gateway
-  become: yes
+  become: true
   tasks:
     - name: Get internet-facing interface from gateway
       shell: "ip route get 8.8.8.8 | awk '/dev/ { print $5 }'"
@@ -65,11 +64,11 @@
       register: private_key_gateway
 
 - hosts: proxy
-  become: yes
+  become: true
   tasks:
     - name: Remove any older connection
       shell: "wg-quick down wg0 && sleep 5"
-      ignore_errors: yes
+      ignore_errors: true
     - name: Generate proxy wg0.conf file
       template:
         src: "../templates/wireguard/wg0_proxy.conf.template"
@@ -83,11 +82,11 @@
       shell: "systemctl enable wg-quick@wg0"
 
 - hosts: gateway
-  become: yes
+  become: true
   tasks:
     - name: Remove any older connection
       shell: "wg-quick down wg0 && sleep 5"
-      ignore_errors: yes
+      ignore_errors: true
     - name: Generate gateway wg0.conf file
       template:
         src: "../templates/wireguard/wg0_gateway.conf.template"
diff --git a/ansible/4-reverse-proxy.yml b/ansible/4-reverse-proxy.yml
index a093a80..912258e 100644
--- a/ansible/4-reverse-proxy.yml
+++ b/ansible/4-reverse-proxy.yml
@@ -2,7 +2,7 @@
 - hosts: proxy
   tasks:
     - name: Install nginx
-      become: yes
+      become: true
       apt:
         pkg: "nginx"
         state: "present"
@@ -11,12 +11,12 @@
       register: nodes
       delegate_to: localhost
     - name: Setup nginx config
-      become: yes
+      become: true
       template:
         src: "../templates/nginx-backend.template"
         dest: "/etc/nginx/sites-available/default"
     - name: Restart nginx
-      become: yes
+      become: true
       ansible.builtin.shell: systemctl restart nginx
 
 - hosts: gateway
@@ -28,7 +28,7 @@
         src: "../templates/caddyfile.template"
         dest: "~/caddy/Caddyfile"
     - name: Create a caddy container
-      become: yes
+      become: true
       community.docker.docker_container:
         name: caddy
         image: docker.io/caddy:alpine