diff --git a/openjdk/defaults/main.yml b/openjdk/defaults/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..7995277726b6ef39bd9753d6b1f8f07aab272386
--- /dev/null
+++ b/openjdk/defaults/main.yml
@@ -0,0 +1,3 @@
+---
+openjdk_download_url: "https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.5%2B11/OpenJDK21U-jdk_x64_linux_hotspot_21.0.5_11.tar.gz"
+openjdk_checksum: "sha256:3c654d98404c073b8a7e66bffb27f4ae3e7ede47d13284c132d40a83144bfd8c"
diff --git a/openjdk/tasks/main.yml b/openjdk/tasks/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f38a85e512beb63730e9b4193f34bdd30e021efc
--- /dev/null
+++ b/openjdk/tasks/main.yml
@@ -0,0 +1,34 @@
+---
+# tasks/main.yml
+- name: Download OpenJDK 21
+  get_url:
+    url: "{{ openjdk_download_url }}"
+    dest: "/tmp/openjdk.tar.gz"
+    mode: "0644"
+    checksum: "{{ openjdk_checksum }}"
+
+- name: Ensure OpenJDK directory exists
+  file:
+    path: "{{ openjdk_dir }}"
+    state: directory
+    mode: "0755"
+
+- name: Extract OpenJDK archive
+  unarchive:
+    src: "/tmp/openjdk.tar.gz"
+    dest: "{{ openjdk_dir }}"
+    remote_src: true
+    extra_opts:
+      - --strip-components=1 # This removes the top-level directory
+    creates: "{{ openjdk_dir }}/bin/java"
+
+- name: Create Java environment script
+  template:
+    src: jdk21.sh.j2
+    dest: /etc/profile.d/jdk21.sh
+    mode: "0644"
+
+- name: Set Java alternatives
+  alternatives:
+    name: java
+    path: "{{openjdk_dir}}/bin/java"
diff --git a/openjdk/templates/jdk21.sh.j2 b/openjdk/templates/jdk21.sh.j2
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/openjdk/vars/main.yml b/openjdk/vars/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9b3fa6b1bd1965de44f09fa00cc29e3f0bba308f
--- /dev/null
+++ b/openjdk/vars/main.yml
@@ -0,0 +1,2 @@
+---
+openjdk_dir: "/usr/local/openjdk-21"