diff --git a/Vagrantfile b/Vagrantfile
index 7f76a76..a978dce 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -23,3 +23,19 @@ Vagrant.configure("2") do |config|
     db.vm.network :private_network, ip: "192.168.60.6"
   end
 end
+
+Vagrant.configure("2") do |config|
+  config.vm.box = "generic/debian12"
+  config.ssh.insert_key = false
+  config.vm.synced_folder "." "/vagrant", disabled: true
+
+  config.vm.provider :virtualbox do |v|
+    v.memory = 512
+    v.linked_clone = true
+  end
+
+  config.vm.define "deb" do |app|
+    app.vm.hostname = "deb.test"
+    app.vm.network :private_network, ip: "192.168.60.7"
+  end
+end
diff --git a/hosts.yaml b/hosts.yaml
index 58a414c..4fd70b8 100644
--- a/hosts.yaml
+++ b/hosts.yaml
@@ -1,4 +1,4 @@
-multi:
+all:
   vars:
     ansible_host: "127.0.0.1"
     ansible_ssh_user: "vagrant"
@@ -9,7 +9,7 @@ multi:
     # hide all warnings regarding the discovered python interpreters on the remote side
     # https://docs.ansible.com/ansible-core/2.18/reference_appendices/interpreter_discovery.html
     ansible_python_interpreter: "auto_silent"
-
+multi:
   children:
     application_servers:
     database_servers:
@@ -26,3 +26,8 @@ database_servers:
       ansible_ssh_port: 2201
       ansible_become_user: "postgres"
 
+debian:
+  hosts:
+    deb:
+      ansible_host: 127.0.0.1
+      ansible_ssh_port: 2202
diff --git a/playbooks/playbook.yaml b/playbooks/playbook.yaml
new file mode 100644
index 0000000..b024e11
--- /dev/null
+++ b/playbooks/playbook.yaml
@@ -0,0 +1,183 @@
+---
+- name: Follow Tutorial
+  hosts: debian
+  become: true
+
+  vars_files:
+    - vars.yaml
+
+  pre_tasks:
+    - name: Update apt cache if needed
+      ansible.builtin.apt:
+        update_cache: true
+        cache_valid_time: 3600
+
+  handlers:
+    - name: restart apache
+      ansible.builtin.service:
+        name: apache2
+        state: restarted
+
+  tasks:
+    - name: Get software for apt repository management
+      ansible.builtin.apt:
+        state: present
+        name:
+          - python3-apt
+          - python3-pycurl
+
+    - name: "Install Apache, MySQL, PHP, and other dependencies"
+      ansible.builtin.apt:
+        state: present
+        name:
+          - acl
+          - git
+          - curl
+          - unzip
+          - sendmail
+          - apache2
+          - php8.2-common
+          - php8.2-cli
+          - php8.2-dev
+          - php8.2-gd
+          - php8.2-curl
+          - php8.2-opcache
+          - php8.2-xml
+          - php8.2-mbstring
+          - php8.2-pdo
+          - php8.2-mysql
+          - php8.2-apcu
+          - libpcre3-dev
+          - libapache2-mod-php8.2
+          - python3-mysqldb
+          - default-mysql-server
+
+    - name: Install the firewall
+      ansible.builtin.apt:
+        name: ufw
+        state: present
+
+    - name: Disable the firewall (since this is for local dev only).
+      ansible.builtin.service:
+        name: ufw
+        state: stopped
+
+    - name: "Start Apache, MySQL, and PHP."
+      ansible.builtin.service:
+        name: "{{ item }}"
+        state: started
+        enabled: true
+      loop:
+        - apache2
+        - mysql
+
+    - name: Enable Apache rewrite module (required for Drupal).
+      community.general.apache2_module:
+        name: rewrite
+        state: present
+      notify: restart apache
+
+    - name: Add Apache virtualhost for Drupal.
+      ansible.builtin.template:
+        src: "templates/drupal.test.conf.j2"
+        dest: "/etc/apache2/sites-available/{{ domain }}.test.conf"
+        owner: root
+        group: root
+        mode: "0664"
+      notify: restart apache
+
+    - name: Enable Drupal site.
+      ansible.builtin.command: >
+        a2ensite {{ domain }}.test
+        creates=/etc/apache2/sites-enabled/{{ domain }}.test.conf
+      notify: restart apache
+
+    - name: Disable the default site.
+      ansible.builtin.command: >
+        a2dissite 000-default
+        removes=/etc/apache2/sites-enabled/000-default.conf
+      notify: restart apache
+
+    - name: Adjust OpCache memory setting.
+      ansible.builtin.lineinfile:
+        dest: "/etc/php/8.2/apache2/conf.d/10-opcache.ini"
+        regexp: "^opcache/memory_consumption"
+        line: "opcache.memory_consumption = 96"
+        state: present
+      notify: restart apache
+
+    - name: Create a MySQL database for Drupal.
+      community.mysql.mysql_db:
+        db: "{{ domain }}"
+        state: present
+
+    - name: Create a MySQL user for Drupal.
+      community.mysql.mysql_user:
+        name: "{{ domain }}"
+        password: "1234"
+        priv: "{{ domain }}.*:ALL"
+        host: localhost
+        state: present
+
+    - name: Download Composer installer.
+      ansible.builtin.get_url:
+        url: https://getcomposer.org/installer
+        dest: /tmp/composer-installer.php
+        mode: "0755"
+    - name: Run Composer installer.
+      ansible.builtin.command: >
+        php composer-installer.php
+        chdir=/tmp
+        creates=/usr/local/bin/composer
+    - name: Mov Composer into globally-accessible location.
+      ansible.builtin.command: >
+        mv /tmp/composer.phar /usr/local/bin/composer
+        creates=/usr/local/bin/composer
+
+    - name: Ensure Drupal directory exists.
+      ansible.builtin.file:
+        path: "{{ drupal_core_path }}"
+        state: directory
+        owner: www-data
+        group: www-data
+    - name: Check if Drupal project already exists.
+      ansible.builtin.stat:
+        path: "{{ drupal_core_path }}/composer.json"
+      register: drupal_composer_json
+
+    - name: Create Drupal project.
+      community.general.composer:
+        command: create-project
+        arguments: drupal/recommended-project:^9 "{{ drupal_core_path }}"
+        working_dir: "{{ drupal_core_path }}"
+        no_dev: true
+      become_user: www-data
+      when: not drupal_composer_json.stat.exists
+
+    - name: Ensure cache dir is writable by www-data.
+      ansible.builtin.file:
+        dest: "/var/www/.cache"
+        state: directory
+        group: www-data
+        owner: www-data
+        mode: "0755"
+
+    - name: Add drush to the Drupal site with composer.
+      community.general.composer:
+        command: require
+        arguments: "drush/drush:^11"
+        working_dir: "{{ drupal_core_path }}"
+      become_user: www-data
+      when: not drupal_composer_json.stat.exists
+
+    - name: Install Drupal
+      ansible.builtin.command: >
+        vendor/bin/drush si -y --site-name="{{ drupal_site_name }}"
+        --account-name=admin
+        --account-pass=admin
+        --db-url=mysql:://{{ domain }}:1234@localhost/{{ domain }}
+        --root={{ drupal_core_path }}/web
+        chdir={{ drupal_core_path }}
+        creates={{ drupal_core_path }}/web/sites/default/settings.php
+      notify: restart apache
+      become_user: www-data
diff --git a/playbooks/templates/drupal.test.conf.j2 b/playbooks/templates/drupal.test.conf.j2
new file mode 100644
index 0000000..ab78902
--- /dev/null
+++ b/playbooks/templates/drupal.test.conf.j2
@@ -0,0 +1,10 @@
+<VirtualHost *:80>
+  ServerAdmin webmaster@localhost
+  ServerName {{ domain }}.test
+  ServerAlias www.{{ domain }}.test
+  DocumentRoot {{ drupal_core_path }}/web
+  <Directory "{{ drupal_core_path }}/web">
+    Options FollowSymlinks Indexes
+    AllowOverride All
+  </Directory>
+</VirtualHost>
diff --git a/playbooks/vars.yaml b/playbooks/vars.yaml
new file mode 100644
index 0000000..b658fd3
--- /dev/null
+++ b/playbooks/vars.yaml
@@ -0,0 +1,4 @@
+---
+drupal_core_path: "/var/www/drupal"
+domain: "drupal"
+drupal_site_name: "Drupal Test"