如何为文件中的动态库存提取的服务器定义ssh私钥

Cla*_*eng 52 ansible ansible-playbook

在为ssh私钥文件编写ansible playbook时遇到了一个配置问题.

我们知道,我们可以在静态库存服务器的ansible hosts文件中定义与主机服务器,ip和相关ssh私钥的组合.

但我不知道如何使用动态库存服务器来定义它.

例如:

---
- hosts: tag_Name_server1
  gather_facts: no
  roles:
    - role1

- hosts: tag_Name_server2
  gather_facts: no
  roles:
    - roles2
Run Code Online (Sandbox Code Playgroud)

下面的命令用于调用该剧本:

ansible-playbook test.yml -i ec2.py --private-key ~/.ssh/SSHKEY.pem
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  1. 如何在ansible文件中定义〜/ .ssh/SSHKEY.pem,而不是在命令行中定义
  2. 我想playbook中可能有一个参数,比如"gather_facts"来定义哪个私钥应该用于上面的主机,但看起来没有这样的参数?
  3. 如果无法在文件中定义私钥,如果不同的密钥文件将用于一个剧本的不同动态获取服务器,那么应​​该在命令行中定义什么?

谢谢您的意见

Tir*_*iro 49

TL; DR:在组变量文件中指定密钥文件,因为'tag_Name_server1'是一个组.


注意:我假设您正在使用EC2外部库存脚本.如果您正在使用其他动态库存方法,则可能需要调整此解决方案.

这是我一直在挣扎,开启和关闭,数月的问题,我终于找到了一个解决方案,这要归功于布莱恩可口可乐的建议在这里.诀窍是使用Ansible的组变量机制自动传递您正在使用的机器的正确SSH密钥文件.

EC2清单脚本会自动设置可用于引用主机的各种组.你在剧本中使用它:在第一部剧中,你告诉Ansible将'role1'应用于整个'tag_Name_server1'组.我们希望指示Ansible为'tag_Name_server1'组中的任何主机使用特定的SSH密钥,这是组变量文件的来源.

假设您的playbook位于'my-playbooks'目录中,为'group_vars'目录下的每个组创建文件:

my-playbooks
|-- test.yml
+-- group_vars
     |-- tag_Name_server1.yml
     +-- tag_Name_server2.yml
Run Code Online (Sandbox Code Playgroud)

现在,只要你在剧本中引用这些组,Ansible就会检查相应的文件,并加载你在那里定义的任何变量.

在每个组var文件中,我们可以指定用于连接组中主机的密钥文件:

# tag_Name_server1.yml
# --------------------
# 
# Variables for EC2 instances named "server1"
---
ansible_ssh_private_key_file: /path/to/ssh/key/server1.pem
Run Code Online (Sandbox Code Playgroud)

现在,当你运行你的剧本时,它应该自动选择正确的键!


使用环境变量来实现可移植性

我经常在许多不同的服务器(本地,远程构建服务器等)上运行playbooks,所以我喜欢参数化.我没有使用固定路径,而是使用一个名为SSH_KEYDIR的环境变量,该变量指向存储SSH密钥的目录.

在这种情况下,我的组vars文件看起来像这样,而是:

# tag_Name_server1.yml
# --------------------
# 
# Variables for EC2 instances named "server1"
---
ansible_ssh_private_key_file: "{{ lookup('env','SSH_KEYDIR') }}/server1.pem"
Run Code Online (Sandbox Code Playgroud)

进一步改进

可能有一堆巧妙的方法可以改进.首先,您仍需要手动指定每个组使用哪个键.由于EC2清单脚本包含有关每个服务器使用的密钥对的详细信息,因此可能有一种方法可以直接从脚本本身获取密钥名称.在这种情况下,您可以提供密钥所在的目录(如上所示),并根据清单数据选择正确的密钥.

  • 感谢您的回复。真的有帮助。另外,我也想分享一下:如果您不想在`group_vars`中创建一个文件名,例如`tag_Name_server1.yml` **和**,那么您会知道您所有的AWS EC2实例可能共享相同的SSH密钥,您可以执行以下操作:`ansible -i ./inventory/ec2.py --limit“ tag_Name_server1” -m ping all“,然后仅创建此文件:`./inventory/group_vars/ all.yml`。因此,即使您使用“ all”,“-limit”选项也会将主机数过滤为仅具有正确标签/值组合的主机。 (3认同)

小智 24

我能找到解决这个问题的最佳方法是在ansible.cfg中指定私钥文件(我通常将它保存在与playbook相同的文件夹中):

[defaults]
inventory=ec2.py
vault_password_file = ~/.vault_pass.txt
host_key_checking = False
private_key_file = /Users/eric/.ssh/secret_key_rsa
Run Code Online (Sandbox Code Playgroud)

尽管如此,它仍然为playbook中的所有主机设置全局私钥.

注意:您必须指定密钥文件的完整路径 - 静默忽略~user/.ssh/some_key_rsa.

  • 谢谢tchu,这很有效.但它仍然与我的期望有一些差距,让我们看看它是否会在ansible 2.0+ lol中得到优化 (2认同)

kai*_*ser 14

您可以在运行命令时直接定义要直接使用的密钥:

ansible-playbook \
        \ # Super verbose output incl. SSH-Details:
    -vvvv \
        \ # The Server to target: (Keep the trailing comma!)
    -i "000.000.0.000," \
        \ # Define the key to use:
    --private-key=~/.ssh/id_rsa_ansible \
        \ # The `env` var is needed if `python` is not available:
    -e 'ansible_python_interpreter=/usr/bin/python3' \ # Needed if `python` is not available
        \ # Dry–Run:
    --check \
    deploy.yml
Run Code Online (Sandbox Code Playgroud)

复制粘贴:

ansible-playbook -vvvv --private-key=/Users/you/.ssh/your_key deploy.yml
Run Code Online (Sandbox Code Playgroud)


Ken*_*uat 6

我正在使用以下配置:

#site.yml:
- name: Example play
  hosts: all
  remote_user: ansible
  become: yes
  become_method: sudo
  vars:
    ansible_ssh_private_key_file: "/home/ansible/.ssh/id_rsa"
Run Code Online (Sandbox Code Playgroud)


小智 5

我遇到了类似的问题,并通过对ec2.py进行了补丁并向ec2.ini添加了一些配置参数来解决了该问题。该修补程序采用ec2_key_name的值,并以ssh_key_path为其前缀,并将ssh_key_suffix添加到末尾,并写出ansible_ssh_private_key_file作为该值。

必须在新的“ ssh”部分中将以下变量添加到ec2.ini中(如果默认值与您的环境匹配,则这是可选的):

[ssh]
# Set the path and suffix for the ssh keys
ssh_key_path = ~/.ssh
ssh_key_suffix = .pem
Run Code Online (Sandbox Code Playgroud)

这是ec2.py的补丁:

204a205,206
>     'ssh_key_path': '~/.ssh',
>     'ssh_key_suffix': '.pem',
422a425,428
>         # SSH key setup
>         self.ssh_key_path = os.path.expanduser(config.get('ssh', 'ssh_key_path'))
>         self.ssh_key_suffix = config.get('ssh', 'ssh_key_suffix')
> 
1490a1497
>         instance_vars["ansible_ssh_private_key_file"] = os.path.join(self.ssh_key_path, instance_vars["ec2_key_name"] + self.ssh_key_suffix)
Run Code Online (Sandbox Code Playgroud)