diff --git a/openstack-gpu/README.md b/openstack-gpu/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..d9287a3ae8ba8e4456edcf1ef7607a9366c5f8c7
--- /dev/null
+++ b/openstack-gpu/README.md
@@ -0,0 +1 @@
+This contains packer hcl files for creating images. For documentation on packer, see [here](https://www.packer.io/docs); for information about the openstack-specific builder, see [here](https://www.packer.io/plugins/builders/openstack)
diff --git a/openstack-gpu/nodeimage.pkr.hcl b/openstack-gpu/nodeimage.pkr.hcl
new file mode 100644
index 0000000000000000000000000000000000000000..79bc5cccc2056e16a5f5a2f9a04167d1829b4d56
--- /dev/null
+++ b/openstack-gpu/nodeimage.pkr.hcl
@@ -0,0 +1,28 @@
+locals {
+    local_image_name = "${var.image_name}${var.image_date_suffix ? formatdate("YYYYMMDDHHmm", timestamp()): ""}"
+}
+
+source "openstack" "image" {
+  image_name        = local.local_image_name
+  source_image_name = var.source_image
+  flavor            = var.flavor
+
+  floating_ip_network = var.floating_ip_network
+  networks = var.networks
+  security_groups = var.security_groups
+
+  ssh_username = var.ssh_username
+}
+
+# regular instance
+build {
+  sources = ["source.openstack.image"]
+
+  provisioner "ansible" {
+    playbook_file = "./ansible/node-gpu.yml"
+    roles_path = "./ansible/roles"
+    extra_arguments = [
+      "--extra-vars", "root_ssh_key='${var.root_ssh_key}'"
+    ]
+  }
+}
diff --git a/openstack-gpu/variables.pkr.hcl b/openstack-gpu/variables.pkr.hcl
new file mode 100644
index 0000000000000000000000000000000000000000..322fb9d56469aee86ae656d3bd82b9b2a081be68
--- /dev/null
+++ b/openstack-gpu/variables.pkr.hcl
@@ -0,0 +1,48 @@
+variable "root_ssh_key" {
+  type = string
+  description = "The root key to use for ssh"
+}
+
+variable "image_name" {
+  type        = string
+  default     = "cluster-image-gpu"
+  description = "Name of the image in openstack"
+}
+
+variable "image_date_suffix" {
+  type        = bool
+  default     = false
+  description = "Append a date to the image name (in YYYYMMDDHHMMSS format)"
+}
+
+variable "source_image" {
+  type        = string
+  description = "The name of the source image to use"
+}
+
+variable "flavor" {
+  type        = string
+  description = "The name of the flavor to use"
+}
+
+variable "ssh_username" {
+  type = string
+  default = "centos"
+  description = "The default username to use for SSH"
+}
+
+variable "floating_ip_network" {
+  type = string
+  description = "floating ip network to use with (temporary) ip assignmnet to a vm"
+}
+
+variable "networks" {
+  type = list(string)
+  description = "List of network UUIDs to assign to the network"
+}
+
+variable "security_groups" {
+  type = list(string)
+  default = []
+  description = "A list of security groups to add - you should make sure ssh access is open to the machine"
+}