为Ansible指定sudo密码

我如何指定一个sudo密码Ansible在非交互的方式?

我是这样运行Ansible剧本的:

$ ansible-playbook playbook.yml -i inventory.ini \
--user=username --ask-sudo-pass

但我想这样运行它:

$ ansible-playbook playbook.yml -i inventory.ini \
--user=username` **--sudo-pass=12345**

有办法吗?我希望尽可能地自动化我的项目部署。

395231 次浏览

查看代码(runner/__init__.py),我认为你可能可以在你的库存文件中设置它:

[whatever]
some-host ansible_sudo_pass='foobar'

ansible.cfg配置文件中似乎也有一些规定,但现在还没有实现(constants.py)。

我不认为ansible会让你在标志中指定密码,因为你希望这样做。 可能在配置的某个地方可以设置这个,但这将使使用ansible总体上不太安全,不建议使用

您可以做的一件事是在目标计算机上创建一个用户,并向其授予所有命令或受限制的命令列表的无密码sudo特权。

如果你运行sudo visudo并输入如下一行,那么用户'privilegedUser'在运行类似sudo service xxxx start的代码时应该不需要输入密码:

%privilegedUser ALL= NOPASSWD: /usr/bin/service

您可以为一个组或所有服务器设置密码:

[all:vars]
ansible_sudo_pass=default_sudo_password_for_all_hosts


[group1:vars]
ansible_sudo_pass=default_sudo_password_for_group1

的文档 强烈不建议设置sudo密码为明文:

提醒一下,密码永远不应该以纯文本的形式存储。有关Ansible Vault加密密码和其他秘密的信息,请参见加密内容与Ansible Vault

相反,在运行ansible-playbook时,应该在命令行上使用--ask-become-pass

之前版本的Ansible使用--ask-sudo-passsudo来代替become

可能做到这一点的最好方法——假设你不能使用NOPASSWD解决方案由scottod——是将Mircea Vutcovici的解决方案与Ansible vault Archived结合使用。

例如,你可能有这样的剧本:

- hosts: all


vars_files:
- secret


tasks:
- name: Do something as sudo
service: name=nginx state=restarted
sudo: yes

这里我们包含了一个名为secret的文件,它将包含我们的sudo密码。

我们将使用ansible-vault来创建这个文件的加密版本:

ansible-vault create secret

这将要求您输入密码,然后打开默认编辑器来编辑该文件。你可以把你的ansible_sudo_pass放在这里。

例如:secret:

ansible_sudo_pass: mysudopassword

保存并退出,现在你有一个加密的secret文件,Ansible是能够解密当你运行你的剧本。注意:您可以使用ansible-vault edit secret编辑文件(并输入创建文件时使用的密码)

谜题的最后一部分是为Ansible提供一个--vault-password-file,它将使用它来解密你的secret文件。

创建一个名为vault.txt的文件,并在其中放入创建secret文件时使用的密码。密码应该是存储在文件中的单行字符串。

来自Ansible Docs:

.. 确保文件上的权限是这样的,没有其他人可以访问您的密钥,并且没有将您的密钥添加到源代码控制中

最后:您现在可以使用以下内容运行您的剧本

ansible-playbook playbook.yml -u someuser -i hosts --sudo --vault-password-file=vault.txt

上面假设的目录布局如下:

.
|_ playbook.yml
|_ secret
|_ hosts
|_ vault.txt

你可以在这里阅读更多关于Ansible Vault: 存档https://docs.ansible.com/playbooks_vault.html <一口> < em > < / em > < /一口>


https://docs.ansible.com/ansible/latest/user_guide/vault.html

你可以通过--extra-vars "name=value"在命令行上传递变量。Sudo密码变量为ansible_sudo_pass。所以你的命令看起来像这样:

ansible-playbook playbook.yml -i inventory.ini --user=username \
--extra-vars "ansible_sudo_pass=yourPassword"

更新2017: Ansible 2.2.1.0现在使用var ansible_become_pass。两种方法似乎都有效。

更新2021: ansible_become_pass仍然有效,但现在,我们应该使用-e而不是——extra-vars

你可以使用ansible库,它会将你的密码编码到加密库中。之后,你可以使用变量从金库在剧本。

关于ansible vault的一些文档 http://docs.ansible.com/playbooks_vault.html < / p >

我们正在使用它作为每个环境的vault。要编辑vault,我们有如下命令:
ansible-vault edit inventories/production/group_vars/all/vault < / p > 如果你想调用保险库变量,你必须使用ansible-playbook的参数如下 ansible-playbook -s --vault-password-file=~/.ansible_vault.password < / p >

是的,我们存储仓库密码在本地目录明文,但这不是更危险的存储根密码为每个系统。根密码在保险库文件中,或者您可以将它像sudoers文件一样用于您的用户/组。< br > < br > 我建议在服务器上使用sudoers文件。admin组的示例如下:
%admin ALL=(ALL) NOPASSWD:ALL < / p >

我在这个问题上撕了我的头发,现在我找到了一个解决方案,这是我想要的:

每台主机1个加密文件,包含sudo密码

/etc/ansible/hosts:

[all:vars]
ansible_ssh_connection=ssh ansible_ssh_user=myuser ansible_ssh_private_key_file=~/.ssh/id_rsa


[some_service_group]
node-0
node-1

然后为每个主机创建一个加密的var文件,如下所示:

ansible-vault create /etc/ansible/host_vars/node-0

与内容

ansible_sudo_pass: "my_sudo_pass_for_host_node-0"

如何组织保险库密码(通过——ask-vault-pass输入)或CFG由您决定

基于此,我怀疑你可以加密整个hosts文件…

如果你愿意将密码保存在纯文本文件中,另一种选择是使用带有——extra-vars参数的JSON文件(确保将该文件排除在源代码控制之外):

ansible-playbook --extra-vars "@private_vars.json" playbook.yml

Ansible从1.3开始就支持这个选项

Ansible vault已经在这里被建议了几次,但我更喜欢git-crypt加密我的剧本中的敏感文件。如果你使用git来保存你的ansible playbook,这是一个snap。我发现ansible vault的问题是,我不可避免地会遇到我想要使用的文件的加密副本,在我工作之前必须解密它。git-crypt提供了一个更好的工作流程。

使用这个,你可以把你的密码放在你的剧本中的一个变量中,并像这样将你的剧本标记为.gitattributes中的加密文件:

 my_playbook.yml filter=git-crypt diff=git-crypt

你的剧本将在Github上透明加密。然后你只需要在你用来运行ansible的主机上安装加密密钥,或者按照文档上的说明用gpg来设置它。

这里有一个关于像你的ssh-agent转发SSH密钥一样转发gpg密钥的好问题:https://superuser.com/questions/161973/how-can-i-forward-a-gpg-key-via-ssh-agent

sudo密码存储为一个名为ansible_sudo_pass的变量。 你可以用几种方法设置这个变量:

每台主机,在您的目录主机文件中 (inventory/<inventoryname>/hosts)

[server]
10.0.0.0 ansible_sudo_pass=foobar

每组,在你的目录组文件 (inventory/<inventoryname>/groups)

[server:vars]
ansible_sudo_pass=foobar

每组,在组变量 (group_vars/<groupname>/ansible.yml)

ansible_sudo_pass: "foobar"

每组加密 (ansible-vault create group_vars/<groupname>/ansible.yml)

ansible_sudo_pass: "foobar"

非常简单,只需在变量file中添加:

例子:

$ vim group_vars/all

加上这些:

Ansible_connection: ssh
Ansible_ssh_user: rafael
Ansible_ssh_pass: password123
Ansible_become_pass: password123

你可以像这样在hosts文件中为你的剧本写sudo密码:

[host-group-name]
host-name:port ansible_sudo_pass='*your-sudo-password*'

你可以像下面这样使用sshpass实用程序:

$ sshpass -p "your pass" ansible pattern -m module -a args \
-i inventory --ask-sudo-pass

我们也可以在ansible中使用EXPECT BLOCK来生成bash并根据您的需要自定义它

- name: Run expect to INSTALL TA
shell: |
set timeout 100
spawn /bin/sh -i


expect -re "$ "
send "sudo yum remove -y xyz\n"


expect "$ "
send "sudo yum localinstall -y \{\{ rpm_remotehost_path_for_xyz }}\n"


expect "~]$ "
send "\n"


exit 0
args:
executable: /usr/bin/expect

--extra-vars "become_pass=Password"调用你的剧本

become_pass=('ansible_become_password', 'ansible_become_pass')

这对我很有用… 创建文件/etc/sudoers./p> . d/90-init-users文件
echo "user ALL=(ALL)       NOPASSWD:ALL" > 90-init-users

其中“user”是您的用户id。

只是一个补充,所以没有人会经历我最近遇到的烦恼:

我相信,最好的解决方案是沿着上面的toast38coza的大致路线。如果将密码文件和剧本静态绑定在一起是有意义的,那么使用vars_files(或include_vars)遵循他的模板。如果你想让它们分开,你可以在命令行上提供仓库内容,如下所示:

ansible-playbook --ask-vault-pass -e@<PATH_TO_VAULT_FILE> <PLAYBOOK_FILE>

回想起来,这是显而易见的,但这里有一些陷阱:

  1. 那个血腥的@标志。如果省略它,解析将无声地失败, ansible-playbook将继续进行,就好像您从未在第一个位置指定该文件一样。

  2. 您必须显式地导入保险库的内容,可以使用命令行——extra-vars/-e,也可以在YAML代码中导入。--ask-vault-pass标志本身不做任何事情(除了提示您输入一个稍后可能使用或不使用的值)。

愿你把“@”也写进去,节省一个小时。

使用ansible 2.4.1.0和以下函数可以工作:

[all]
17.26.131.10
17.26.131.11
17.26.131.12
17.26.131.13
17.26.131.14


[all:vars]
ansible_connection=ssh
ansible_user=per
ansible_ssh_pass=per
ansible_sudo_pass=per

然后用这个目录运行剧本:

ansible-playbook -i inventory copyTest.yml

一个更聪明的方法是将你的sudo密码存储在一个安全的库中,如LastPassKeePass,然后使用-e@将它传递给ansible-playbook,但不是在实际文件中硬编码内容,你可以使用构造-e@<(...)在子shell中运行命令,并将其输出(STDOUT)重定向到匿名文件描述符,有效地将密码提供给-e@<(..)

例子

$ ansible-playbook -i /tmp/hosts pb.yml \
-e@<(echo "ansible_sudo_pass: $(lpass show folder1/item1 --password)")

以上是做几件事,让我们分解一下。

  • ansible-playbook -i /tmp/hosts pb.yml -显然运行一个剧本通过ansible-playbook
  • $(lpass show folder1/item1 --password)" -运行LastPass CLI lpass并检索要使用的密码
  • echo "ansible_sudo_pass: ...password..." -接受字符串'ansible_sudo_pass: '并将其与lpass提供的密码相结合
  • -e@<(..) -将上述内容放在一起,并将<(...)的子shell连接为ansible-playbook使用的文件描述符。

进一步的改善

如果你不想每次都输入,你可以这样简单地输入。首先在.bashrc中创建一个别名,如下所示:

$ cat ~/.bashrc
alias asp='echo "ansible_sudo_pass: $(lpass show folder1/item1 --password)"'

现在你可以像这样运行你的剧本:

$ ansible-playbook -i /tmp/hosts pb.yml -e@<(asp)

参考文献

五年过去了,我可以看出这仍然是一个非常相关的主题。有点像leucos的答案,我发现在我的情况下,只使用ansible工具(没有任何集中的身份验证,令牌或其他东西)。这假设您在所有服务器上都有相同的用户名和相同的公钥。如果你不这样做,当然你需要更具体,并在主机旁边添加相应的变量:

[all:vars]
ansible_ssh_user=ansible
ansible_ssh_private_key_file=home/user/.ssh/mykey
[group]
192.168.0.50 ansible_sudo_pass='\{\{ myserver_sudo }}'


ansible-vault create mypasswd.yml
ansible-vault edit mypasswd.yml

添加:

myserver_sudo: mysecretpassword

然后:

ansible-playbook -i inv.ini my_role.yml --ask-vault --extra-vars '@passwd.yml'

至少这样你就不用写更多指向密码的变量了。

以上@toast38coza的解决方案对我来说很管用;只是现在Ansible中已经弃用了sudo:是的。 使用成为become_user代替
tasks:
- name: Restart apache service
service: name=apache2 state=restarted
become: yes
become_user: root

我的黑客自动化这是使用一个环境变量,并通过--extra-vars="ansible_become_pass='\{\{ lookup('env', 'ANSIBLE_BECOME_PASS') }}'"访问它。

导出一个env变量,但避免bash/shell历史记录(前面有一个空格或其他方法)。例如:

     export ANSIBLE_BECOME_PASS='<your password>'

在将额外的ansible_become_pass变量传递给ansible-playbook时查找env变量,例如:

ansible-playbook playbook.yml -i inventories/dev/hosts.yml -u user --extra-vars="ansible_become_pass='\{\{ lookup('env', 'ANSIBLE_BECOME_PASS') }}'"

好的替代答案:

如果你正在使用通过密码管理器,你可以使用模块passwordstore,这使得这非常容易。

假设您将用户的sudo密码保存为pass as

Server1 /用户

然后您可以像这样使用解密后的值

\{\{ lookup('community.general.passwordstore', 'Server1/User')}}"

我在我的清单中使用它:

---
servers:
hosts:
server1:
ansible_become_pass: "\{\{ lookup('community.general.passwordstore', 'Server1/User')}}"

请注意,您应该运行gpg-agent,这样您就不会在每次运行“成为”任务时看到pinentry提示。

如需更新

只要运行你的剧本与旗帜-K,他会问你的sudo密码

通用电气ansible-playbook yourPlaybookFile.yaml -K

来自医生

要为sudo指定密码,请运行ansible-playbook和——ask-be -pass (-K)命令

你可以在剧本执行时传递它。语法是-

ansible-playbook -i inventory my.yml \
--extra-vars 'ansible_become_pass=YOUR-PASSWORD-HERE'

但出于安全考虑,这并不是一个好主意。最好使用可靠的拱顶

首先更新你的库存文件如下:

[cluster:vars]
k_ver="linux-image-4.13.0-26-generic"
ansible_user=vivek  # ssh login user
ansible_become=yes  # use sudo
ansible_become_method=sudo
ansible_become_pass='\{\{ my_cluser_sudo_pass }}'
 

[cluster]
www1
www2
www3
db1
db2
cache1
cache2

接下来,创建一个名为password的新加密数据文件。Yml,执行如下命令:

$ ansible-vault create passwd.yml

设置保险箱密码。在提供密码后,该工具将启动您用$ editor定义的任何编辑器。附加以下内容 my_cluser_sudo_pass: your_sudo_password_for_remote_servers 在vi/vim中保存并关闭文件。最后运行playbook,如下所示:

$ ansible-playbook -i inventory --ask-vault-pass --extra-vars '@passwd.yml' my.yml

如何重新编辑我的加密文件

ansible-vault edit passwd.yml

如何更改加密文件的密码

ansible-vault rekey passwd.yml

只是提示其他解决方案。 你可以设置你的ansible用户运行sudo而不需要密码(这是GCP虚拟机的默认设置)

sudo visudo

添加行(tom是用户):

tom ALL=(ALL) NOPASSWD:ALL