diff --git a/app-template/README.md b/app-template/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..e5188c074d645b9c1a36810f3382a74d59157ee6
--- /dev/null
+++ b/app-template/README.md
@@ -0,0 +1 @@
+This a packer hcl template for creating a image. 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/app-template/nodeimage.pkr.hcl b/app-template/nodeimage.pkr.hcl
new file mode 100644
index 0000000000000000000000000000000000000000..465acc8b91e0212f51c8b8cfb88a31e655717a21
--- /dev/null
+++ b/app-template/nodeimage.pkr.hcl
@@ -0,0 +1,47 @@
+packer {
+  required_plugins {
+    openstack = {
+      version = "~> 1"
+      source  = "github.com/hashicorp/openstack"
+    }
+    ansible = {
+      version = "~> 1"
+      source  = "github.com/hashicorp/ansible"
+    }
+  }
+}
+
+source "openstack" "example" {
+  skip_create_image         = var.skip_create_image
+  image_name                = local.local_image_name
+  source_image              = var.source_image
+  image_members             = var.image_membership
+  image_auto_accept_members = var.auto_accept_members
+  image_tags                = var.image_tags
+  image_disk_format         = var.image_format
+  volume_size               = var.volume_size
+  flavor                    = var.flavor
+  instance_name             = var.build_instance_name
+  use_blockstorage_volume   = true
+  floating_ip_network       = var.floating_ip_network
+  networks                  = var.networks
+  security_groups           = var.security_groups
+  ssh_username              = var.ssh_username
+}
+
+build {
+  sources = ["source.openstack.example"]
+
+  provisioner "shell" {
+    inline = [
+      "echo Hello",
+      "echo from `hostname`"
+    ]
+  }
+
+  # For more provision, check at https://developer.hashicorp.com/packer/docs/provisioners
+  # Example of ansible provisioner:
+  provisioner "ansible" {
+    playbook_file = "./ansible/playbook.yml"
+  }
+}
diff --git a/app-template/variables.pkr.hcl b/app-template/variables.pkr.hcl
new file mode 100644
index 0000000000000000000000000000000000000000..597771bec06df86239d52408f534f36372a35287
--- /dev/null
+++ b/app-template/variables.pkr.hcl
@@ -0,0 +1,102 @@
+variable "root_ssh_key" {
+  type        = string
+  default     = ""
+  description = "The root key to use for ssh"
+}
+
+variable "image_name" {
+  type        = string
+  default     = "cluster-image"
+  description = "Name of the image in openstack"
+}
+
+variable "image_format" {
+  type        = string
+  default     = "qcow2"
+  description = "The format of the resulting image"
+}
+
+variable "image_tags" {
+  type        = list(string)
+  default     = []
+  description = "List of tags to be associated to the resulting image"
+}
+
+variable "image_membership" {
+  type        = list(string)
+  default     = []
+  description = "Projects/tenants to share the image in openstack with"
+}
+
+variable "auto_accept_members" {
+  type        = bool
+  default     = false
+  description = "A boolean value for auto accepting image in the projects/tenants defined in image_membership."
+}
+
+variable "skip_create_image" {
+  type        = bool
+  default     = false
+  description = "A boolean value for skipping image creation at the end of the build"
+}
+
+variable "source_image" {
+  type        = string
+  default     = ""
+  description = "The name of the source image to use"
+}
+
+variable "flavor" {
+  type        = string
+  default     = ""
+  description = "The name of the flavor to use"
+}
+
+variable "floating_ip_network" {
+  type        = string
+  default     = "uab-campus"
+  description = "floating ip network to use with (temporary) ip assignmnet to a vm"
+}
+
+variable "networks" {
+  type        = list(string)
+  default     = []
+  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"
+}
+
+variable "build_instance_name" {
+  type        = string
+  default     = "ood"
+  description = "A name of build instance used for image build"
+}
+
+variable "ssh_username" {
+  type        = string
+  default     = "centos"
+  description = "The default username to use for SSH"
+}
+
+variable "volume_size" {
+  type        = number
+  default     = 20
+  description = "The default volume size for building iamge"
+}
+
+variable "ANSIBLE_DEBUG" {
+  type        = string
+  default     = "false"
+  description = "to turn on debugging"
+}
+
+variable "ANSIBLE_VERBOSITY" {
+  type        = string
+  default     = "0"
+  description = "to increase verbosity - 0|1|2|3|4"
+}
+