21

I am struggling to pass input parameter to packer provisioning script. I have tried various options but no joy.

Objective is my provision.sh should accept input parameter which I send during packer build.

packer build -var role=abc test.json

I am able to get the user variable in json file however I am unable to pass it provision script. I have to make a decision based on the input parameter.

I tried something like

"provisioners": 
{
  "type": "shell",
  "scripts": [
  "provision.sh {{user `role`}}"
 ]
}

But packer validation itself is failed with no such file/directory error message.

It would be real help if someone can help me on this.

Thanks in advance.

Thayz
  • 631
  • 1
  • 6
  • 9

2 Answers2

35

You should use the environment_vars option, see the docs Shell Provisioner - environment_vars.

Example:

"provisioners": [
  {
    "type": "shell"
    "environment_vars": [
      "HOSTNAME={{user `vm_name`}}",
      "FOO=bar"
    ],
    "scripts": [
      "provision.sh"
    ],
  }
 ]
Rickard von Essen
  • 4,110
  • 2
  • 23
  • 27
  • Thanks Richard for the response. I think I understand environment variables. Now I do have have couple of environment variables declared. My question is how to make use of them in provision.sh script? In general shell script we use to use $1, $2 to receive input parameters. When I print $1 & $2, there is no value set. – Thayz Dec 01 '17 at 22:31
  • 1
    $1, $2 etc are _arguments_. _Environment variables_ can be used with their name in your script, i.e. `$HOSTNAME` and `$FOO`. I recommend that you start reading some introduction to (ba)sh scripting, for example http://tldp.org/LDP/abs/html/ – Rickard von Essen Dec 02 '17 at 04:38
  • I see what do you mean. Thanks. – Thayz Dec 02 '17 at 09:58
  • I would be wary of this solution if you have wrapped packer such that you run multiple instances simultaneously, in which case the json cfg for each run (in my case creating multiple differentiated snowflakes) HOSTTYPE will vary between runs. – volvox Jul 11 '18 at 11:49
  • @volvox sorry I don't understand your comment? There are no mention of `HOSTTYPE` in either the question, my answer, nor any of the comments (except for yours) – Rickard von Essen Jul 11 '18 at 14:05
  • Sorry yes let me clarify. My point was that you are setting environment vars. In order to reduce costs of AMI copies between regions, but also to reduce time waiting for copies of AMIs to be produced by packer, I wrap packer and nohup the processes in parallel. If each packer proc tries to write a shell env var, then the same var will be overwritten, which is undesirable. T J Biddle's answer would thus be better in this situation. – volvox Jul 12 '18 at 07:09
  • Sorry that doesn't makes any sense. There are no pros/cons with my vs T J Biddle's answer, it's just two different solutions which achieves the same thing. – Rickard von Essen Jul 12 '18 at 07:17
19

If your script is already configured to use arguments; you simply need to run it as inline rather than in the scripts array.

In order to do this, the script must exist on the system already - you can accomplish this by copying it to the system with the file provisioner.

  "provisioners": [
    {
      "type":        "file",
      "source":      "scripts/provision.sh",
      "destination": "/tmp/provision.sh"
    },
    {
      "type": "shell",
      "inline": [
        "chmod u+x /tmp/provision.sh",
        "/tmp/provision.sh {{user `vm_name`}}"]
    }
  ]
TJ Biddle
  • 6,024
  • 6
  • 40
  • 47