I'm having trouble understanding how the user option for the ansible provisioner works, and I'm wondering if this is expected or not. See the following extract of my template:
"builders": [
{
"type": "amazon-ebs",
...
"ssh_username": "ubuntu",
}
],
"provisioners": [
{
"type": "ansible",
"playbook_file": "./deploy.yml",
"user": "web",
"ansible_env_vars": [ "ANSIBLE_HOST_KEY_CHECKING=False", "ANSIBLE_SSH_ARGS='-o ForwardAgent=yes -o ControlMaster=auto -o ControlPersist=60s'" ]
}
]
My source AMI is customised and the deploy.yml playbook acts on a directory owned by the "web" user. However, when my ssh_username is set to "ubuntu" I get a permission error because "ubuntu" doesn't have access to said directory:
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: OSError: [Errno 13] Permission denied: '/srv/www/site1/releases'
However, if I set my ssh_username to "web", it works fine. I'm wondering what setting the user in the provisioner block does if it doesn't actually login as that user. I've also tried adding "-u web" in extra_arguments but that didn't work either.
Ideally, I would like to build using "ubuntu" and then provision 2 ansible playbooks, one as "ubuntu" and the other as "web", but this doesn't seem to be possible if the "web" user has to perform actions that "ubuntu" is not permissioned for.
From the docs
user(string) - Theansible_userto use. Defaults to the user running packer.
See the Ansible docs - ansible_user
You probably want to read up on Ansible - become
Thanks for the reply, Rickard. I'm not sure I understand though.
I am setting user in the ansible provisioner block, which as it says in the docs, sets the ansible_user to use. However, it doesn't work as I would expect, since if I run the playbook separately with ansible_user set to 'web', or -u web, then I have no permission problems. However, if I run the playbook as part of a packer run, with user set to 'web', then I get a permission error above, unless I also set the ssh_username on the build block to 'web'.
Is this expected? If so, I'm not sure what the purpose of setting the user parameter is if it gets overidden/depends on the ssh_username parameter in the build block?
TL;DR: you'll need to use ansible's become_user to run your plays as the web user if you want to use the ubuntu user to connect to the node from packer.
The ansible provisioner works by creating an SSH server on the packer host that Ansible can connect to as the provisioner's user. Packer is connected to the node (in the case of an SSH communicator) as the commmunicator's ssh_username:
ansible --- (user) ---> packer/ansible-provisioner --- (ssh_username) ---> node
The ansible provisioner has to marshal SSH requests to the node using the interface that packer exposes to communicate with the node. In your case, the way to get the ansible plays to run as the web user is to use become_user: web on your plays.
Thank you for the explanation, @bhcleek. It makes a lot more sense now. I'll switch to using become_user and hopefully that should do the trick.
Most helpful comment
Thanks for the reply, Rickard. I'm not sure I understand though.
I am setting
userin the ansible provisioner block, which as it says in the docs, sets theansible_userto use. However, it doesn't work as I would expect, since if I run the playbook separately withansible_userset to 'web', or-u web, then I have no permission problems. However, if I run the playbook as part of a packer run, withuserset to 'web', then I get a permission error above, unless I also set thessh_usernameon the build block to 'web'.Is this expected? If so, I'm not sure what the purpose of setting the
userparameter is if it gets overidden/depends on thessh_usernameparameter in the build block?