为Ansible指定sudo密码

问题描述 投票:183回答:22

如何以非交互方式为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**

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

ansible
22个回答
126
投票

您可以通过--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。要么似乎工作。


4
投票

如果您熟悉将密码保存在纯文本文件中,另一个选择是使用带有--extra-vars参数的JSON文件(确保从源代码控制中排除该文件):

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

Ansible has supported this option since 1.3


4
投票

你可以在hosts文件中为你的playbook写sudo密码,如下所示:

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

4
投票

这里有几次建议使用Ansible保险库,但我更喜欢使用git-crypt来加密我的剧本中的敏感文件。如果你使用git来保存你的ansible playbooks,那就快点了。我在ansible vault中发现的问题是,我不可避免地会遇到我想要使用的文件的加密副本,并且必须在我工作之前解密它。 git-crypt提供了更好的工作流程IMO。

使用此功能,您可以将密码放入playbook中的var中,并将您的playbook标记为.gitattributes中的加密文件,如下所示:

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

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

转发gpg密钥有很好的问答,例如你的ssh-agent转发SSH密钥:https://superuser.com/questions/161973/how-can-i-forward-a-gpg-key-via-ssh-agent


2
投票

您可以使用ansible保险库,它将您的密码编码为加密保险库。之后,您可以在playbooks中使用Vault中的变量。

关于ansible 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


2
投票

只需用--extra-vars "become_pass=Password"打电话给你的剧本

become_pass=('ansible_become_password', 'ansible_become_pass')


2
投票

您可以使用sshpass实用程序,如下所示,

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

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

0
投票

很简单,只添加变量文件:

例:

$ vim group_vars/all

并添加以下内容:

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

0
投票

只是一个附录,所以没有其他人经历我最近做的烦恼:

AFAIK,最好的解决方案是沿着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代码中显式导入Vault的内容。 --ask-vault-pass标志本身不做任何事情(除了提示您输入以后可能使用或不使用的值)。

可以包括你的“@”并节省一个小时。


0
投票

使用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

199
投票

The docs强烈建议不要在纯文本中设置sudo密码,而是在运行--ask-sudo-pass时在命令行上使用ansible-playbook


2016年更新:

Ansible 2.0(不是100%时)将--ask-sudo-pass标记为已弃用。 The docs现在推荐使用--ask-become-pass,同时也在sudo的整个剧本中交换使用become


0
投票

五年后,我可以看到这仍然是一个非常相关的主题。有些镜像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'

至少这种方式你不必写更多指向密码的变量。


0
投票

@ toast38coza的上述解决方案为我工作;只是那个sudo:yes现在在Ansible中被弃用了。请改用而使用become和become_user。

tasks:
 - name: Restart apache service
   service: name=apache2 state=restarted
   become: yes
   become_user: root

-2
投票

这对我有用...用NOPASSWD创建文件/etc/sudoers.d/90-init-users文件

echo "user ALL=(ALL)       NOPASSWD:ALL" > 90-init-users

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


95
投票

可能最好的方法 - 假设你不能使用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能够解密。注意:您可以使用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


42
投票

看一下代码(runner/__init__.py),我想你可以在你的库存文件中设置它:

[whatever]
some-host ansible_sudo_pass='foobar'

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


42
投票

我不认为ansible会让你在标志中指定一个密码。可以在配置中的某处设置这可以设置但是这将使得使用ansible总体上不太安全并且不会被推荐。

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

如果您运行sudo visudo并输入如下所示的行,则用户'privilegedUser'在运行sudo service xxxx start之类的内容时不必输入密码:

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

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"

16
投票

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

[all:vars]
ansible_sudo_pass=default_sudo_password_for_all_hosts

[group1:vars]
ansible_sudo_pass=default_sudo_password_for_group1

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由您决定

基于此我怀疑你可以加密整个主机文件...


6
投票

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

Example

$ 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的文件描述符。

Further improvements

如果你不想每次都能输入那么简单的东西。首先在你的.bashrc中创建一个别名,如下所示:

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

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

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

References

© www.soinside.com 2019 - 2024. All rights reserved.