如何以非交互方式为Ansible指定sudo密码?
我正在运行这样的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**
有办法吗?我希望尽可能自动化我的项目部署。
答案 0 :(得分:199)
The docs 强烈建议不要在纯文本中设置sudo密码,而是在运行--ask-sudo-pass
时在命令行上使用ansible-playbook
2016年更新:
Ansible 2.0(不是100%时)将--ask-sudo-pass
标记为已弃用。 The docs现在建议改为使用--ask-become-pass
,同时也在sudo
整个播放手册中更换become
。
答案 1 :(得分:124)
您可以通过--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
。两者似乎都有效。
答案 2 :(得分:92)
可能最好的方法 - 假设你不能使用scottod提供的NOPASSWD解决方案是将Mircea Vutcovici的解决方案与Ansible vault结合使用。
例如,你可能会有这样的剧本:
- 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可以在您运行Playbook时解密。注意:您可以使用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
答案 3 :(得分:42)
我认为ansible不允许您按照自己的意愿在标志中指定密码。 可以在配置中的某个位置设置此设置,但这会使得整体使用安全性不那么安全,并且不会被推荐。
您可以做的一件事是在目标计算机上创建用户,并为所有命令或受限制的命令列表授予无密码sudo权限。
如果您运行sudo visudo
并输入如下所示的行,则用户'privilegedUser'在运行sudo service xxxx start
之类的内容时不必输入密码:
%privilegedUser ALL= NOPASSWD: /usr/bin/service
答案 4 :(得分:42)
查看代码(runner/__init__.py
),我想您可以在库存文件中设置它:
[whatever]
some-host ansible_sudo_pass='foobar'
ansible.cfg
配置文件中似乎也有一些规定,但现在没有实施(constants.py
)。
答案 5 :(得分:19)
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"
答案 6 :(得分:16)
您可以一次为组或所有服务器设置密码:
[all:vars]
ansible_sudo_pass=default_sudo_password_for_all_hosts
[group1:vars]
ansible_sudo_pass=default_sudo_password_for_group1
答案 7 :(得分:11)
我正在把头发撕成一片,现在我找到了一个能满足我想要的解决方案:
每个包含sudo密码的主机1个加密文件
的/ etc / ansible /主机:
[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由您决定
基于此我怀疑你只能加密整个主机文件......
答案 8 :(得分:6)
一种更明智的方法是将sudo
密码存储在安全的保管库中,例如LastPass或KeePass,然后使用{ {1}},而不是对实际文件中的内容进行硬编码,您可以使用结构ansible-playbook
在子Shell中运行命令,并将其输出(STDOUT)重定向到匿名文件描述符,从而有效地进行输入-e@
的密码。
-e@<(...)
上面正在做几件事,让我们分解一下。
-e@<(..)
-显然是通过ansible-playbook来运行剧本$ ansible-playbook -i /tmp/hosts pb.yml \
-e@<(echo "ansible_sudo_pass: $(lpass show folder1/item1 --password)")
-运行LastPass CLI ansible-playbook -i /tmp/hosts pb.yml
并检索要使用的密码$(lpass show folder1/item1 --password)"
-接受字符串'ansible_sudo_pass:',并将其与lpass
提供的密码组合echo "ansible_sudo_pass: ...password..."
-将以上内容放在一起,并连接lpass
的子外壳作为-e@<(..)
使用的文件描述符。如果您不想每次都键入,则可以简单地进行如下操作。首先像这样在您的<(...)
中创建一个别名:
ansible-playbook
现在您可以像这样运行剧本:
.bashrc
答案 9 :(得分:4)
如果您愿意将密码保存在纯文本文件中,另一个选择是使用带有--extra-vars参数的JSON文件(确保从源代码管理中排除该文件):
ansible-playbook --extra-vars "@private_vars.json" playbook.yml
答案 10 :(得分:4)
Ansible vault在这里曾被提出过几次,但我更喜欢使用git-crypt来加密我的剧本中的敏感文件。如果你使用git来保存你的ansible playbooks,那就快点了。我在ansible vault中发现的问题是,我不可避免地会遇到我想要使用的文件的加密副本,并且必须在我工作之前解密它。 git-crypt
提供了更好的工作流程IMO。
使用此功能,您可以将密码放入游戏手册中的var中,并在.gitattributes
中将您的剧本标记为加密文件,如下所示:
my_playbook.yml filter=git-crypt diff=git-crypt
您的剧本将在Github上透明加密。然后,您只需要在用于运行ansible的主机上安装加密密钥,或者按照文档中的说明使用gpg
进行设置。
转发gpg
密钥时,有一个很好的Q&amp; A,例如ssh-agent
转发SSH密钥:https://superuser.com/questions/161973/how-can-i-forward-a-gpg-key-via-ssh-agent。
答案 11 :(得分:4)
您可以在主机文件中为您的剧本编写sudo密码,如下所示:
[host-group-name]
host-name:port ansible_sudo_pass='*your-sudo-password*'
答案 12 :(得分:2)
您可以使用sshpass
实用程序,如下所示
$ sshpass -p "your pass" ansible pattern -m module -a args \
-i inventory --ask-sudo-pass
答案 13 :(得分:2)
只需使用--extra-vars "become_pass=Password"
become_pass=('ansible_become_password', 'ansible_become_pass')
答案 14 :(得分:2)
您可以使用 ansible vault 将密码编码到加密保管库中。之后,您可以在playbooks中使用Vault中的变量。
关于安塞尔保险库的一些文件:
http://docs.ansible.com/playbooks_vault.html
我们将其用作每个环境的保险库。要编辑保险库,我们的命令如下:
ansible-vault edit inventories/production/group_vars/all/vault
如果要调用vault变量,则必须使用带有以下参数的ansible-playbook:
ansible-playbook -s --vault-password-file=~/.ansible_vault.password
是的,我们将保管库密码以纯文本形式存储在本地目录中,但它并不像每个系统的商店根密码那样危险。 Root密码在Vault文件中,或者您可以将其设置为您的用户/组的sudoers文件。
我建议在服务器上使用sudoers文件。以下是组管理员的示例:
%admin ALL=(ALL) NOPASSWD:ALL
答案 15 :(得分:1)
实现这一目标的自动化方法是使用环境变量并通过--extra-vars="ansible_become_pass='{{ lookup('env', 'ANSIBLE_BECOME_PASS') }}'"
访问它。
导出一个环境变量,但要避免使用bash / shell历史记录(以空格或其他方法开头)。例如:
export ANSIBLE_BECOME_PASS='<your password>'
查找环境变量,同时将额外的ansible_become_pass
变量传递到ansible-playbook
中,例如:
ansible-playbook playbook.yml -i inventories/dev/hosts.yml -u user --extra-vars="ansible_become_pass='{{ lookup('env', 'ANSIBLE_BECOME_PASS') }}'"
好的替代答案:
ansible_become_pass
。这是体面的。但是,对于偏执狂的团队,他们需要共享ans Vault密码,并使用个人帐户执行ansible比赛,因此他们会使用共享的Vault密码来彼此反向操作操作系统密码(相同的盗窃)。可以说,您需要信任自己的团队吗?@
prefix to read the ansible variable from the file desriptor。至少避免bash历史记录。不确定,但希望子外壳回声不会在审核日志记录(例如auditd)中被捕获和暴露。答案 16 :(得分:1)
对于新的更新
只需使用标志 -K 运行您的剧本,他就会询问您的 sudo 密码
例如ansible-playbook yourPlaybookFile.yaml -K
来自文档
<块引用>要为 sudo 指定密码,请使用 --ask-become-pass(简称 -K)运行 ansible-playbook
答案 17 :(得分:0)
我们也可以在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
答案 18 :(得分:0)
非常简单,只添加变量文件:
示例:
$ vim group_vars/all
并添加以下内容:
Ansible_connection: ssh
Ansible_ssh_user: rafael
Ansible_ssh_pass: password123
Ansible_become_pass: password123
答案 19 :(得分:0)
只是一个附录,所以没有人经历我最近所做的烦恼:
AFAIK,最好的解决方案是按照以上toast38coza的常规思路进行解决。如果将您的密码文件和剧本静态地绑定在一起是有意义的,那么请遵循vars_files
(或include_vars
)跟随他的模板。如果要将它们分开,则可以在命令行上提供保管库内容,如下所示:
ansible-playbook --ask-vault-pass -e@<PATH_TO_VAULT_FILE> <PLAYBOOK_FILE>
回想起来很明显,但这是陷阱:
血腥的 @ 标志。如果您将其保留,解析将无提示失败,并且ansible-playbook将继续进行,就好像您从来没有指定文件一样。
您必须使用命令行--extra-vars / -e或在您的YAML代码中显式导入Vault的内容。 --ask-vault-pass
标志本身不会做任何事情(除了提示您提供一个以后可能会使用或可能不会使用的值)。
愿您添加“ @”并节省一个小时。
答案 20 :(得分:0)
使用可使用的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
答案 21 :(得分:0)
五年后,我看到这仍然是一个非常相关的主题。我仅在使用ansible工具(没有任何集中式身份验证,令牌或任何其他手段)的情况下,在某种程度上反映了leucos的答案,这是我发现的最佳答案。这假定您在所有服务器上都具有相同的用户名和相同的公用密钥。如果不这样做,那么当然需要更加具体,并在主机旁边添加相应的变量:
[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'
至少,这样,您不必编写更多指向密码的变量。
答案 22 :(得分:0)
@ toast38coza的上述解决方案为我工作;只是 sudo:是现在在Ansible中已弃用。 改为使用 become 和 become_user 。
SELECT p.type_prod, p.model_prod, mc.chipset_motherboard
FROM prodotti p
INNER JOIN motherboard_component mc ON(mc.label_motherboard = p.type_prod AND mc.model_motherboard = p.model_prod)
答案 23 :(得分:0)
如果您使用pass密码管理器,则可以使用模块passwordstore,这非常容易。
假设您将用户的sudo密码保存为通行证
服务器1 /用户
然后您可以像这样使用解密后的值
{{ lookup('community.general.passwordstore', 'Server1/User')}}"
我在库存中使用它
---
servers:
hosts:
server1:
ansible_become_pass: "{{ lookup('community.general.passwordstore', 'Server1/User')}}"
请注意,您应该正在运行gpg-agent,以便每次运行“成为”任务时都不会看到pinentry提示。
答案 24 :(得分:0)
您可以在剧本执行期间传递它。语法是 -
ansible-playbook -i inventory my.yml \
--extra-vars 'ansible_become_pass=YOUR-PASSWORD-HERE'
但出于安全原因,这不是一个好主意。最好使用 ansible Vault
首先按如下方式更新您的库存文件:
[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
答案 25 :(得分:-2)
这对我有用...... 使用NOPASSWD创建文件/etc/sudoers.d/90-init-users文件
echo "user ALL=(ALL) NOPASSWD:ALL" > 90-init-users
其中“user”是您的用户ID。