Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
505 views
in Technique[技术] by (71.8m points)

ansible - How to define private SSH keys for servers in dynamic inventories

I ran into a configuration problem when coding an Ansible playbook for SSH private key files. In static Ansible inventories, I can define combinations of host servers, IP addresses, and related SSH private keys - but I have no idea how to define those with dynamic inventories.

For example:

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

- hosts: tag_Name_server2
  gather_facts: no
  roles:
    - roles2

I use the below command to call that playbook:

ansible-playbook test.yml -i ec2.py --private-key ~/.ssh/SSHKEY.pem

My questions are:

  1. How can I define ~/.ssh/SSHKEY.pem in Ansible files rather than on the command line?
  2. Is there a parameter in playbooks (like gather_facts) to define which private keys should be used which hosts?
  3. If there is no way to define private keys in files, what should be called on the command line when different keys are used for different hosts in the same inventory?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

TL;DR: Specify key file in group variable file, since 'tag_Name_server1' is a group.


Note: I'm assuming you're using the EC2 external inventory script. If you're using some other dynamic inventory approach, you might need to tweak this solution.

This is an issue I've been struggling with, on and off, for months, and I've finally found a solution, thanks to Brian Coca's suggestion here. The trick is to use Ansible's group variable mechanisms to automatically pass along the correct SSH key file for the machine you're working with.

The EC2 inventory script automatically sets up various groups that you can use to refer to hosts. You're using this in your playbook: in the first play, you're telling Ansible to apply 'role1' to the entire 'tag_Name_server1' group. We want to direct Ansible to use a specific SSH key for any host in the 'tag_Name_server1' group, which is where group variable files come in.

Assuming that your playbook is located in the 'my-playbooks' directory, create files for each group under the 'group_vars' directory:

my-playbooks
|-- test.yml
+-- group_vars
     |-- tag_Name_server1.yml
     +-- tag_Name_server2.yml

Now, any time you refer to these groups in a playbook, Ansible will check the appropriate files, and load any variables you've defined there.

Within each group var file, we can specify the key file to use for connecting to hosts in the group:

# tag_Name_server1.yml
# --------------------
# 
# Variables for EC2 instances named "server1"
---
ansible_ssh_private_key_file: /path/to/ssh/key/server1.pem

Now, when you run your playbook, it should automatically pick up the right keys!


Using environment vars for portability

I often run playbooks on many different servers (local, remote build server, etc.), so I like to parameterize things. Rather than using a fixed path, I have an environment variable called SSH_KEYDIR that points to the directory where the SSH keys are stored.

In this case, my group vars files look like this, instead:

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

Further Improvements

There's probably a bunch of neat ways this could be improved. For one thing, you still need to manually specify which key to use for each group. Since the EC2 inventory script includes details about the keypair used for each server, there's probably a way to get the key name directly from the script itself. In that case, you could supply the directory the keys are located in (as above), and have it choose the correct keys based on the inventory data.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...