diff --git a/docker/ironic/ironic-pxe/Dockerfile.j2 b/docker/ironic/ironic-pxe/Dockerfile.j2
index 3ab5ac293a..c319973e09 100644
--- a/docker/ironic/ironic-pxe/Dockerfile.j2
+++ b/docker/ironic/ironic-pxe/Dockerfile.j2
@@ -14,6 +14,15 @@ LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" build-date="{{ build
         'syslinux-tftpboot',
         'tftp-server'
     ] %}
+
+    {% if base_arch == 'aarch64' %}
+        ENV ironic_arch=aarch64
+        {% set ironic_pxe_packages = ironic_pxe_packages + [
+            'grub2-efi',
+            'grub2-efi-aa64-modules'
+        ] %}
+    {% endif %}
+
 {{ macros.install_packages(ironic_pxe_packages | customizable("packages")) }}
 RUN sed -i -r 's,^(Listen 80),#\1,' /etc/httpd/conf/httpd.conf \
     && sed -i -r 's,^(Listen 443),#\1,' /etc/httpd/conf.d/ssl.conf
@@ -31,6 +40,11 @@ RUN sed -i -r 's,^(Listen 80),#\1,' /etc/httpd/conf/httpd.conf \
         {% set ironic_pxe_packages = ironic_pxe_packages + [
             'syslinux'
         ] %}
+    {% elif base_arch == 'aarch64' %}
+        ENV ironic_arch=aarch64
+        {% set ironic_pxe_packages = ironic_pxe_packages + [
+            'grub-efi-arm64'
+        ] %}
     {% endif %}
 
 {{ macros.install_packages(ironic_pxe_packages | customizable("packages")) }}
diff --git a/docker/ironic/ironic-pxe/extend_start.sh b/docker/ironic/ironic-pxe/extend_start.sh
index 6957ec777c..f7297988c6 100644
--- a/docker/ironic/ironic-pxe/extend_start.sh
+++ b/docker/ironic/ironic-pxe/extend_start.sh
@@ -14,6 +14,18 @@ if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then
     exit 0
 fi
 
+if [[ "${ironic_arch}" =~ aarch64 ]]; then
+    modules="boot chain configfile efinet ext2 fat gettext help hfsplus loadenv \
+    lsefi normal part_gpt part_msdos read search search_fs_file search_fs_uuid \
+    search_label terminal terminfo tftp linux"
+
+    if [[ "${KOLLA_BASE_DISTRO}" =~ debian|ubuntu ]]; then
+        grub-mkimage -v -o /tftpboot/grubaa64.efi -O arm64-efi -p "grub" $modules
+    elif [[ "${KOLLA_BASE_DISTRO}" =~ centos|oraclelinux|rhel ]]; then
+        grub2-mkimage -v -o /tftpboot/grubaa64.efi -O arm64-efi -p "EFI/centos" $modules
+    fi
+fi
+
 # NOTE(pbourke): httpd will not clean up after itself in some cases which
 # results in the container not being able to restart. (bug #1489676, 1557036)
 if [[ "${KOLLA_BASE_DISTRO}" =~ debian|ubuntu ]]; then