-
Notifications
You must be signed in to change notification settings - Fork 11
/
configure-ssh-keys.yml
128 lines (108 loc) · 4.2 KB
/
configure-ssh-keys.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
- name: Configure SSH keys on the new machine
gather_facts: yes # we need ansible_user_id
hosts: all
vars:
key_passphrase:
"{{ lookup('passwordstore', 'ssh/pass/' + ssh_key_name + ' create=true') }}"
key_type:
"{{ ssh_key_suffix | default('') | regex_search('rsa|ed25519|ecdsa') or 'rsa' }}"
key_size:
"{{ '4096' if key_type == 'rsa' else omit }}"
tasks:
- assert:
that:
- ssh_key_name is defined
- passwordstore_path is defined
fail_msg: Some variables that should be defined in host_vars are missing.
- name: ensure directories exist
file:
dest: "{{ ansible_env.HOME }}/{{ item }}"
state: directory
mode: 0700
loop:
- .ssh
- .ssh/keys
# Allow to either use a key that already exists on the machine,
# or create a new one with a unique name (to avoid confusion).
- name: Ensure we use unique names for the keys
block:
- name: check for private key on the machine
find:
paths: "{{ ansible_env.HOME }}/.ssh/keys"
pattern: "{{ ssh_key_name }}"
register: existing_key
- name: check for key passphrase in passwordstore
find:
# FIXME we assume that passwordstore_path is the same for all hosts
paths: "{{ passwordstore_path }}/ssh/pass"
pattern: "{{ ssh_key_name }}.gpg"
register: known_keys
delegate_to: localhost
- name: Abort if the key was lost
fail:
msg: >
Key named {{ ssh_key_name }} had been created before, but cannot
be found on this machine. Use a different name if you want to
create a new key.
when:
- existing_key.matched == 0
- known_keys.matched != 0
- name: generate ssh key if not present
user:
name: "{{ ansible_user_id }}"
generate_ssh_key: yes
ssh_key_type: "{{ key_type }}"
ssh_key_bits: "{{ key_size }}"
ssh_key_file: .ssh/keys/{{ ssh_key_name }}
ssh_key_comment: "{{ ssh_key_name }}"
ssh_key_passphrase: "{{ key_passphrase }}"
register: user_info
- name: configure default ssh id
copy:
content: |
# this file should be included at the beginning of ~/.ssh/config
IdentityFile ~/.ssh/keys/{{ ssh_key_name }}
dest: "{{ ansible_env.HOME }}/.ssh/config_default_id"
- name: save public key on ansible control machine
copy:
content: "{{ user_info.ssh_public_key }}"
dest: "files/ssh-public-keys/{{ ssh_key_name }}.pub"
delegate_to: localhost
- name: allow target hosts to ssh into each other
authorized_key:
key: "{{ lookup('file', 'ssh-public-keys/' + hostvars[item].ssh_key_name + '.pub') }}"
user: "{{ ansible_user_id }}"
loop: "{{ play_hosts }}"
- debug: var=user_info.ssh_public_key
when: user_info is changed
- name: Update ansible control machine
hosts: localhost
tasks:
- name: aggregate user_info status from all hosts
set_fact:
hosts_changed: "{{ hosts_changed + [hostvars[item].user_info.changed] }}"
when: hostvars[item].user_info is defined
loop: "{{ groups['all'] }}"
vars:
hosts_changed: []
# it would be annoying to run this always
- name: Update repos and services with new key info
when: True in hosts_changed
block:
- name: push new key passphrase(s) to passwordstore
shell:
cmd: git push
chdir: "{{ passwordstore_path }}"
- name: commit public key(s) to ansible-setup repo
shell: >
git add files/ssh-public-keys/ &&
git commit -m "Add new hosts' public key(s)" -- files/ssh-public-keys
- name: update public keys in hosting services
# use default browser
command: xdg-open {{ item }}
loop:
- "https://bitbucket.org/account/user/%7Be4e0b20b-ddd2-43b6-b3dc-fc37b2039717%7D/ssh-keys/"
- "https://github.com/settings/keys"
- "https://gitlab.com/profile/keys"
- name: push public key(s) to ansible-setup repo
shell: git push