File Provisioner in Packer

Reading Time: 3 minutes


Packer is an open-source tool. It allows us to create machine images. It can be used for multiple platforms from a single source template. A common use case is creating images that can be used later in cloud infrastructure. We will use File Provisioner in this blog.

Basically, It can work with JSON as well as HCL language which is developed by Harshicorp. In this blog, we will use JSON files to create a machine image and transfer the files from local to the image which we will create.

File Provisioner

The File Provisioner uploads files to machines images. The File packer provisioner is used to upload files. Here, If you want to move that file to a specific location or set the permission etc then you can use shell provisioner.

Warning: If you want to upload then you can only upload the file to the location that the provisioning user has access to the location. Now you can simply use the shell provisioner to move the file where you want to move. The file provisioner can upload both single files and complete directories.


  "type": "file",
  "source": "index.html",
  "destination": "/tmp/index.html"


  • Type is use to define the provisioner type basically which is File type.
  • Source is use to define which file we want to upload.
  • Destination is use to define the end location of file. As we discuss above that file can be upload to the folder where provisioning user has access then we can use shell provisioner to move required location.

Now, We will try to create an AMI and upload a file. We will create an AWS instance with the same machine image.

Step to use File Provisioner:


First We need to set the environment variable with the below command:

export ACCESS_KEY=<access key>
export SECRET_KEY=<secret key>


Create a file with this <file_name.json> name and this file will look like this:

        "access_key": "{{env `ACCESS_KEY`}}",
        "secret_key": "{{env `SECRET_KEY`}}"
    "builders": [
            "type": "amazon-ebs",
            "access_key": "{{user `access_key`}}",
            "secret_key": "{{user `secret_key`}}",
            "region": "us-east-1",
            "ami_name": "blog-ami-nginx",
            "source_ami": "ami-04505e74c0741db8d",
            "instance_type": "t2.micro",
            "ssh_username": "ubuntu"

    "provisioners": [
            "type": "shell",
            "script": ""
            "type": "file",
            "source": "index.html",
            "destination": "/tmp/"
            "type": "shell",
            "inline": ["sudo cp /tmp/index.html /var/www/html/"]


<h1>Hey, Welcome to this page</h1>

sleep 30
sudo apt-get update
sudo apt-get upgrade -y 
sudo apt-get install -y nginx
sudo systemctl start nginx

In the above configuration, We will replace a default Nginx page with our own create an HTML page.


Now, run the below command to build a machine image with the above configuration:

packer build <file_name.json>


When we create an instance with these machine images. We will see, all the packages are installed and the Nginx default page has been replaced with the page we want and try to access the nginx default page with the public IP of the instance. We will see our HTML page as below


This is a very easy way to configure the machine image according to requirements and create the instance. In this blog, I have also used Shell Provisioner and I also wrote a blog on it. You can check out that blog also here.

Written by 

Mohd Muzakkir Saifi is a Software Consultant at Knoldus Software. He loves to take deep dives into cloud technologies & different tools. His hobbies are playing gymnastics and traveling.