Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Packer can't execute shell provisioner as sudo

I have a shell provisioner in packer connected to a box with user vagrant

{
  "environment_vars": [
    "HOME_DIR=/home/vagrant"
  ],
  "expect_disconnect": true,
  "scripts": [
    "scripts/foo.sh"
  ],
  "type": "shell"
}

where the content of the script is:

whoami
sudo su
whoami

and the output strangely remains:

==> virtualbox-ovf: Provisioning with shell script: scripts/configureProxies.sh
    virtualbox-ovf: vagrant
    virtualbox-ovf: vagrant

why cant I switch to the root user? How can I execute statements as root? Note, I do not want to quote all statements like sudo "statement |foo" but rather globally switch user like demonstrated with sudo su

like image 621
Georg Heiler Avatar asked Jan 31 '18 07:01

Georg Heiler


People also ask

Does Packer run as root?

So Packer is running as root but the ansible user is not root, and needs access to environment variables? You can use the option ansible_env_vars to inject specific environment variables into the ansible environment.

What is Provisioner in Packer?

Packer Provisioners are the components of Packer that install and configure software into a running machine prior to turning that machine into an image. An example of a provisioner is the shell provisioner, which runs shell scripts within the machines.

What is Shell provisioning?

The shell Packer provisioner provisions machines built by Packer using shell scripts. Shell provisioning is the easiest way to get software installed and configured on a machine. Building Windows images? You probably want to use the PowerShell or Windows Shell provisioners.


3 Answers

There is another solution with simpler usage of 2 provisioner together.

Packer's shell provisioner can run the bash with sudo privileges. First you need copy your script file from local machine to remote with file provisioner, then run it with shell provisioner.

packer.json

{
    "vars": [...],
    "builders": [
        {
            # ...
            "ssh_username": "<some_user_other_than_root_with_passwordless_sudo>",
        }
    ],
    "provisioners": [
        {
            "type": "file",
            "source": "scripts/foo.sh",
            "destination": "~/shell.tmp.sh"
        },
        {
            "type": "shell",
            "inline": ["sudo bash ~/shell.tmp.sh"]
        }
    ]
}

foo.sh

# ...
whoami
sudo su root
whoami
# ...

output

<some_user_other_than_root_with_passwordless_sudo>
root

After provisioner complete its task, you can delete the file with shell provisioner.

packer.json updated

        {
            "type": "shell",
            "inline": ["sudo bash ~/shell.tmp.sh", "rm ~/shell.tmp.sh"]
        }
like image 157
ufukty Avatar answered Oct 05 '22 06:10

ufukty


You should override the execute_command. Example:

  "provisioners": [
    {
      "execute_command": "echo 'vagrant' | {{.Vars}} sudo -S -E sh -eux '{{.Path}}'",
      "scripts": [
        "scripts/foo.sh"
      ],
      "type": "shell"
    }
  ],
like image 21
Rickard von Essen Avatar answered Oct 05 '22 08:10

Rickard von Essen


one possible answer seems to be: https://unix.stackexchange.com/questions/70859/why-doesnt-sudo-su-in-a-shell-script-run-the-rest-of-the-script-as-root

sudo su <<HERE
ls /root
whoami
HERE

maybe there is a better answer?

like image 30
Georg Heiler Avatar answered Oct 05 '22 07:10

Georg Heiler