Packer templates and conditional statements

I would like to use conditional statements in the wrapper template in the "Providers" stage.

  "provisioners": [
    {
      "execute_command": "echo 'vagrant'|sudo -S sh '{{.Path}}'",
      "override": {
        "virtualbox-iso": {
          "scripts": [
            "scripts/base.sh",
            "scripts/puppet.sh",
          ]
        }
      },
      "type": "shell",
    }
  ]

      

For example, if the user specifies a "puppet" parameter in the "bundler" command line in some way, then "scripts / puppet.sh" will be executed differently if omitted.

How can i do this?

+3


source to share


2 answers


I don't think this is possible with the bundle scaffold because the wrapper uses JSON for configuration, which as far as I know does not support flow control mechanisms like the conditional statement. But you need to be able to archive similar behavior with user variables and the shell provider.

Idea

The easiest way is to set a custom variable from the build command, and pass those variables from the packager to a shell script provider that determines the value of the custom variable and invokes the appropriate script security mechanism like puppet, salt, ...

Denial of responsibility:

I haven't tested this approach, but it should give you a hint of what I mean and maybe you can find an even better solution .; -)

Approach to problem solving

1. Define a variable that indicates the collateral to use:

There are several ways to define a custom variable,

  • by calling the package build command with the -var flag (see end of answer)
  • define custom variables in box-template file

    Packer box template file: template.json

        "variables": [
            "using_provision_system": "puppet"
        ]
        "provisioners": [
             {...}
    
          

  • define a variable definition file and provide the path to it in the build command with -var-file

    Variable file: variables.json  Great alternative if you want to define variables in a separate file.

        {
           "using_provision_system": "puppet"
        }
    
          

2. Calling a shell script that invokes the build scripts:



Now modify the execute_command so that the "master" script with the specified variable is called as an argument.

"provisioners": [
    {
      "execute_command": "echo 'vagrant'|sudo -S sh '{{.Path}}' '{{user `using_provision_system`}}'",
      "override": {
        "virtualbox-iso": {
          "scripts": [
            call_provisioner_script.sh
          ]
        }
      },
      "type": "shell",
    }
  ]

      

Please note, we only need to specify one script. This "master" script takes the passed variable as an argument and compares the value with some predefined creator names in a toggle state. (Short: he chooses which scripting scripts will run.)

main script condition: call_provisioner_script.sh

case $1 in
    puppet*) sh puppet_provisioner.sh
    *) sh shell_provisioner.sh

      

Be careful!
Since this script will run inside your window, you may need to load scripts in the box before this command is executed.

3. The last step is to create your box :)

Build command of calling packers:

#define variable in build command (first option from above)
$ packer build -var 'using_provision_system=puppet' template.json

#define variables in variable file and set path in build command
$ packer build -var-file=variables.json template.json

      

Instead of using custom variables, there should be a way to set environment variables in your field and use that variable type to indicate the provisioning facility.

+7


source


An alternative way is to define 2 different builders of the same type but with different names. Then you can exclude the initialization step from a specific assembly using the field only

:



{
  "source": "foo.txt",
  "destination": "/opt/foo.txt",
  "type": "file",
  "only": ["docker-local"]
}

      

+4


source







All Articles