diff --git a/playbooks/setup.yaml b/playbooks/setup.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..8ff63d9a2641a1f95e8f9c54866a6ea56d47d078
--- /dev/null
+++ b/playbooks/setup.yaml
@@ -0,0 +1,23 @@
+- hosts: localhost
+  vars:
+    dconf_config_path: ""
+    vscode_config_path: ""
+    vscode_extensions_path: ""
+    swap_sizes: ""
+
+  tasks:
+    - name: Include DConf Tasks
+      include_tasks: "{{ item }}"
+      loop:
+        - ../tasks/setup/dconf.yaml
+    
+    - name: Include Visual Studio Code Tasks
+      include_tasks: "{{ item }}"
+      loop:
+        - ../tasks/setup/vscode_settings.yaml
+        - ../tasks/setup/vscode_extensions.yaml
+    
+    - name: Include Swap Tasks
+      include_tasks: "{{ item }}"
+      loop:
+        - ../tasks/setup/swap.yaml
diff --git a/setup.sh b/setup.sh
new file mode 100644
index 0000000000000000000000000000000000000000..5597e063555da1923a082c730c3a66dcfbd21461
--- /dev/null
+++ b/setup.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+set -e
+INSTALLER_DIR=$(dirname "${BASH_SOURCE[0]}")
+HELPER_SCRIPTS_DIR="$INSTALLER_DIR/helper_scripts"
+
+SWAP_DEFAULT_UNIT="G"
+
+main() {
+    read -e -p "DConf config path (empty to skip): " dconf_config_path
+    read -e -p "Visual Studio Code User Settings (empty to skip): " vscode_config_path
+    read -e -p "Visual Studio Code Extensions File (empty to skip): " vscode_extensions_path
+    read -e -p "Comma separated swap sizes in Gigabytes (empty to skip): " swap_sizes
+    swap_sizes="${swap_sizes//','/"$SWAP_DEFAULT_UNIT "}"
+
+    additional_ansible_args=()
+
+    if [[ -n "$swap_sizes" ]]; then
+        additional_ansible_args+=('--ask-become-pass')
+        swap_sizes+="$SWAP_DEFAULT_UNIT"
+    fi
+
+    $HELPER_SCRIPTS_DIR/install_ansible.sh
+    ansible-playbook "${INSTALLER_DIR}/playbooks/setup.yaml" \
+        --extra-vars "dconf_config_path='$dconf_config' vscode_config_path='$vscode_config_path' vscode_extensions_path='$vscode_extensions_path' swap_sizes='$swap_sizes'" \
+        --inventory "${INSTALLER_DIR}/ansible_inventory.ini" \
+        $(IFS=' ' echo "${additional_ansible_args[*]}")
+}
+
+main
diff --git a/setup_functions.sh b/setup_functions.sh
deleted file mode 100644
index 114e7522f3fb8877be48e0488043186a35e51b37..0000000000000000000000000000000000000000
--- a/setup_functions.sh
+++ /dev/null
@@ -1,50 +0,0 @@
-source installer_vars.sh
-
-gsettings_set_cmd="gsettings set"
-control_center_cmd="gnome-terminal -- bash -c \"gnome-control-center $tab && exit\""
-mkdir_cmd="mkdir -p"
-
-gsettings_set_option() {
-    scheme=$1
-    key=$2
-    value=$3
-
-    $gsettings_set_cmd $scheme $key $value
-}
-
-control_center_set_option() {
-    tab=$1
-
-    gnome-terminal -- bash -c "gnome-control-center $tab && exit"
-}
-
-setup_dark_mode() { # todo, settings -> appereance must be opened to apply
-    gsettings_set_option org.gnome.desktop.interface color-scheme 'prefer-dark'
-
-    control_center_set_option 'ubuntu' #appereance tab
-}
-
-setup_idle_delay() { # todo, settings -> power must be opened to apply
-    gsettings_set_option org.gnome.desktop.session idle-delay 0
-
-    control_center_set_option 'power'
-}
-
-setup_paths() {
-    $mkdir_cmd $projects_path
-    $mkdir_cmd $portable_programs_path
-    $mkdir_cmd $tmp_path
-}
-
-setup_swap() {
-    swap_path="/swap"
-    swap_file="$swap_path/swapfile0"
-
-    sudo $mkdir_cmd $swap_path
-    read -p "swap size (e.g. 50G): " swap_size
-    sudo fallocate -l $swap_size $swap_file
-    sudo chmod 600 $swap_file
-    sudo mkswap $swap_file
-    echo "$swap_file none swap sw 0 0" | sudo tee -a /etc/fstab
-    sudo swapon $swap_file
-}
diff --git a/tasks/apt_packages.yaml b/tasks/apt_packages.yaml
index 6aa6b68e9ebd7f0ec47f560cb32fd316e7838f93..4db7a678ae72e8cd4e0a15dc1c166fdf00bdd455 100644
--- a/tasks/apt_packages.yaml
+++ b/tasks/apt_packages.yaml
@@ -150,7 +150,5 @@
   when: "'wireguard' in apt_packages"
 
 - name: Install DConf Editor (APT)
-  include_tasks: apt_templates/install_apt_package.yaml
-  vars:
-    app: dconf-editor
+  include_tasks: apt_templates/packages/dconf.yaml
   when: "'dconf-editor' in apt_packages"
diff --git a/tasks/apt_templates/packages/dconf.yaml b/tasks/apt_templates/packages/dconf.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..dbf7523948fafb3ebb376c6c7f078aaa72cbdc5f
--- /dev/null
+++ b/tasks/apt_templates/packages/dconf.yaml
@@ -0,0 +1,4 @@
+- name: Install DConf Editor (APT)
+  include_tasks: ../install_apt_package.yaml
+  vars:
+    app: dconf-editor
diff --git a/tasks/general_templates/make_dir.yaml b/tasks/general_templates/make_dir.yaml
index ec1719ddaa43c1890b6620472b07fdd7d069ffac..6084868bc4ca4f4327e7cf8b378f2d3899ea282f 100644
--- a/tasks/general_templates/make_dir.yaml
+++ b/tasks/general_templates/make_dir.yaml
@@ -3,4 +3,4 @@
     path: "{{ path }}"
     state: directory
     mode: '0755'
-  become: false
+  become: "{{ become | default(false) }}"
diff --git a/tasks/general_templates/print_warning.yaml b/tasks/general_templates/print_warning.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..6d6975993a23b664aeda8c9e3b6e3a5f6902f1eb
--- /dev/null
+++ b/tasks/general_templates/print_warning.yaml
@@ -0,0 +1,4 @@
+- name: Print Warning
+  shell:
+    cmd: echo "\033[1;33m[WARNING] {{ warning }}\033[0m" > /dev/tty
+  changed_when: false
diff --git a/tasks/mainline/upgrade_mainline_kernel.yaml b/tasks/mainline/upgrade_mainline_kernel.yaml
index 94f58109b24f4043a07451dc7f4b1e353df3bdba..e984dcfdfc5d83787bb15997a03c00c9fe1b32b5 100644
--- a/tasks/mainline/upgrade_mainline_kernel.yaml
+++ b/tasks/mainline/upgrade_mainline_kernel.yaml
@@ -14,9 +14,7 @@
       changed_when: mainline_result.rc != 1
 
     - name: Print Upgrade Restriction
-      shell:
-        cmd: echo "\033[1;33m[WARNING] {{ warning }}\033[0m" > /dev/tty
-      changed_when: false
+      include_tasks: ../general_templates/print_warning.yaml
       loop_control:
         loop_var: warning
       loop:
diff --git a/tasks/setup/dconf.yaml b/tasks/setup/dconf.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b920944641a17f972e08b8e97ccb64922cd91ace
--- /dev/null
+++ b/tasks/setup/dconf.yaml
@@ -0,0 +1,9 @@
+- name: Import DConf config
+  when: dconf_config_path
+  block:
+    - name: Install DConf Editor (APT)
+      include_tasks: ../apt_templates/packages/dconf.yaml
+
+    - name: Import DConf config
+      shell:
+        cmd: "dconf load / < {{ dconf_config_path | realpath }}"
diff --git a/tasks/setup/swap.yaml b/tasks/setup/swap.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..78424ddc2d1905771068c18cd7465878638cdea3
--- /dev/null
+++ b/tasks/setup/swap.yaml
@@ -0,0 +1,97 @@
+- name: Create swaps
+  when: swap_sizes
+  vars:
+    swap_dir: "/swap"
+    swapfile_prefix: "swapfile"
+    swapfiles: {}
+  block:
+    - name: Ensure swap directory
+      include_tasks: ../general_templates/make_dir.yaml
+      vars:
+        path: "{{ swap_dir }}"
+        become: true
+
+    - name: Extract swap sizes
+      set_fact:
+        swapsizes: "{{ swap_sizes.split() }}"
+
+    - name: Get existing swapfiles
+      find:
+        paths: "{{ swap_dir }}"
+        patterns: "{{ swapfile_prefix }}*"
+        file_type: file
+      register: existing_swapfiles
+
+    - name: Extract the highest existing swapfile number
+      set_fact:
+        highest_number: >-
+          {{
+            existing_swapfiles.files | map(attribute='path')
+            | map('basename')
+            | map('regex_replace', '^' ~ swapfile_prefix ~ '(\d+)', '\g<1>')
+            | select('!=', None)
+            | map('int')
+            | max | default(-1)
+          }}
+
+    - name: Generate swapfile filenames
+      set_fact:
+        swapfile_number_suffix: "{{ '%04d' | format((highest_number | int) + 1 + swapfile_index) }}"
+        swapfiles: "{{ swapfiles | combine({swapfile_prefix + '%04d' | format((highest_number | int) + 1 + swapfile_index): swapsizes[swapfile_index]}) }}"
+      loop_control:
+        loop_var: swapfile_index
+      with_items: "{{ range(swapsizes | length) }}"
+
+    - name: Create swapfiles
+      include_tasks: swap/create_swapfile.yaml
+      vars:
+        # swapfile_prefix: "{{ swapfile_prefix }}"
+        swapfile_filename: "{{ swapfile_infos.key }}"
+        # swap_dir: "{{ swap_dir }}"
+        swapfile_size: "{{ swapfile_infos.value }}"
+      # debug:
+      #   msg: "{{ swapfile_infos.key }}: {{  swapfile_infos.value }}"
+      loop_control:
+        loop_var: swapfile_infos
+      with_items: "{{ swapfiles | dict2items }}"
+
+    # - name: Create swapfiles
+    #   loop_control:
+    #     loop_var: swapfile_index
+    #   with_items: "{{ range(swapsizes | length) }}"
+    #   block:
+    #     - name: Evaluate swapfile filename
+    #       set_fact:
+    #         swapfile_filename: "swapfile{{ '%04d' | format(highest_number + item) }}"
+    #         swapfile_path: "{{ swap_dir }}/{{ swapfile_filename }}"
+
+      #   - name: "Allocate file size for swapfile {{ swapfile_filename }}"
+      #     shell:
+      #       cmd: "fallocate -l {{ swap_sizes[item] }} {{ swapfile_path }}"
+      #     become: true
+
+      #   - name: "Setting permissions for swapfile {{ swapfile_filename }}"
+      #     file:
+      #       path: "{{ swapfile_path }}"
+      #       owner: root
+      #       group: root
+      #       mode: '0600'
+      #     become: true
+
+      #   - name: "Make swapfile from {{ swapfile_filename }}"
+      #     shell:
+      #       cmd: "mkswap {{ swapfile_filename }}"
+      #     become: true
+
+      #   - name: "Add swapfile {{ swapfile_filename }} to /etc/fstab"
+      #     blockinfile:
+      #       path: /etc/fstab
+      #       block: |
+      #         {{ swapfile_path }} none swap sw 0 0
+      #       state: present
+      #     become: true
+
+      #   - name: "Enable swapfile {{ swapfile_filename }}"
+      #     shell:
+      #       cmd: "swapon {{ swapfile_path }}"
+      #     become: true
diff --git a/tasks/setup/swap/create_swapfile.yaml b/tasks/setup/swap/create_swapfile.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..2b6e30b9ac757cdfbb98fe279ff6aec20f12a350
--- /dev/null
+++ b/tasks/setup/swap/create_swapfile.yaml
@@ -0,0 +1,33 @@
+- name: Evaluate swapfile filename
+  set_fact:
+    swapfile_path: "{{ swap_dir }}/{{ swapfile_filename }}"
+
+- name: "Allocate {{ swapfile_size }} for swapfile {{ swapfile_filename }}"
+  shell:
+    cmd: "fallocate -l {{ swapfile_size }} {{ swapfile_path }}"
+  become: true
+
+- name: "Setting permissions for swapfile {{ swapfile_filename }}"
+  file:
+    path: "{{ swapfile_path }}"
+    owner: root
+    group: root
+    mode: '0600'
+  become: true
+
+- name: "Make swapfile from {{ swapfile_filename }}"
+  shell:
+    cmd: "mkswap {{ swapfile_path }}"
+  become: true
+
+- name: "Add swapfile {{ swapfile_filename }} to /etc/fstab"
+  lineinfile:
+    path: /etc/fstab
+    line: "{{ swapfile_path }} none swap sw 0 0"
+    state: present
+  become: true
+
+- name: "Enable swapfile {{ swapfile_filename }}"
+  shell:
+    cmd: "swapon {{ swapfile_path }}"
+  become: true
diff --git a/tasks/setup/vscode_extensions.yaml b/tasks/setup/vscode_extensions.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b2d5d1cf98b1849cc5db31dc3697e1abe362421c
--- /dev/null
+++ b/tasks/setup/vscode_extensions.yaml
@@ -0,0 +1,18 @@
+- name: Install Visual Studio Code Extensions
+  when: vscode_extensions_path
+  block:
+    - name: Read Visual Studio Code Extensions from File
+      slurp:
+        src: "{{ vscode_extensions_path | realpath }}"
+      register: vscode_extensions_file_content
+
+    - name: Decode Visual Studio Code Extensions File Content
+      set_fact:
+        vscode_extensions: "{{ vscode_extensions_file_content['content'] | b64decode | split('\n') }}"
+
+    - name: Install Visual Studio Code Extensions
+      shell:
+        cmd: "code --install-extension {{ vscode_extension }}"
+      loop_control:
+        loop_var: vscode_extension
+      with_items: "{{ vscode_extensions }}"
diff --git a/tasks/setup/vscode_settings.yaml b/tasks/setup/vscode_settings.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e271016dd66d0ba4fe119fd4e703c84343c916c1
--- /dev/null
+++ b/tasks/setup/vscode_settings.yaml
@@ -0,0 +1,26 @@
+- name: Import Visual Studio Code User Settings
+  when: vscode_config_path
+  vars:
+    vscode_user_settings_path: "{{ ansible_env.HOME }}/.config/Code/User"
+    vscode_user_settings_file: "{{ vscode_user_settings_path }}/settings.json"
+  block:
+    - name: Ensure Visual Studio Code Config Directory
+      include_tasks: ../general_templates/make_dir.yaml
+      vars:
+        path: "{{ vscode_user_settings_path }}"
+
+    - name: Remove current Visual Studio Code User Settings
+      file:
+        path: "{{ vscode_user_settings_file }}"
+        state: absent
+
+    - name: Link Visual Studio Code User Settings
+      shell:
+        cmd: "ln -s {{ vscode_config_path | realpath }} {{ vscode_user_settings_file }}"
+
+    - name: Print Visual Studio Code User Settings Warnings
+      include_tasks: ../general_templates/print_warning.yaml
+      loop_control:
+        loop_var: warning
+      loop:
+        - The Visual Studio Code User Settings were dynamically linked. Please don't remove the source.