hashicorp / packer

Packer is a tool for creating identical machine images for multiple platforms from a single source configuration.
http://www.packer.io
Other
14.98k stars 3.33k forks source link

Allow Shell provisioner to redirect its output into a logfile #11907

Open mtausig opened 1 year ago

mtausig commented 1 year ago

I am using a shell provisioner which writes a lot of output to stdout. Most of the times, this output just spams my build log and I do not need, but occasionally I want to have a look at it for debugging purposes.

What I would like, is to have an extra option for the shell-provisioner to specify a local file (on the build host) where all output from my script gets redirected to.

nywilken commented 1 year ago

Hi @mtausig thanks for reaching out. I totally understand where you are coming from. The option you are looking for here is not something that we will build into the provisioner but I could see the option of allowing Packer to write its output to some file without having to manually redirect the output. At this time this can only be done when running in debug log mode.

Packer has support for redirecting a full debug log to some file on the build host by setting the PACKER_LOG=1 and PACKER_LOG_PATH environment variables. For example PACKER_LOG=1 PACKER_LOG_PATH=build.log packer build .

By settingPACKER_LOG=1 it will enable debug log mode, which can then be written to the file defined in the PACKER_LOG_PATH environment variable. Since this is debug logging there will be more noise but you can filter down to each of the provisioners as they are named within the log.

If you have multiple shell provisioners that you need to distigush in the logs without looking at the scripts or inline commands they are running you can give each provisioner a unique name which you can then use to jump to a specific provisioner in the log.

  provisioner "shell-local" {
    name = "set-sentive-values"
    inline = ["echo ${source.name} and ${source.type}, the sensitive var: ${var.sensitive}, ${local.bip}, ${var.number}"]
  }
sgleske-ias commented 8 months ago

Here's an example that would make this useful: You can execute goss infrastructure tests remotely and capture JUnit formatted results for report collection in Jenkins.

ssh -nl someuser somehost sudo goss --format junit -f /tmp/goss.yaml validate > local-results.xml

And later collect local-results.xml after the packer baking completes. In the above case, stdout is a particular format (XML) and so simply outputting it to a mixed debug log is no good because it would be invalid output for the desired result.

The above command is trivial using just SSH but ideally it would be nice to have the provisioner behave like

{
    "type": "shell",
    "inline": [
        "sudo goss --format junit -f /tmp/goss.yaml validate"
    ],
    "local_output": "local-results.xml"
}