I have an ansible playbook that checks out a GitLab private repository. It utilizes the GitLab Users API to generate an SSH key for the target host and adds it to my GitLab user's SSH keys.
This works, but I'm wondering how I can make it better. In particular, each ssh key is titled based on the "{{ ansible_hostname }}_deployer"
, so each server must have a unique hostname. Is there a better way to name my SSH keys?
Any other suggestions you have are welcome.
Note that the repeated when: not user_ssh_keys.json | selectattr('title', 'equalto', deployer_gitlab_key_title) | list | length > 0
conditions ensure that the tasks that copy the host's SSH public key to GitLab do not run if GitLab already has an SSH key with the same title as what would be uploaded by this host.
group_vars/my_group
# gitlab vars
deployer_user: user
deployer_group: user
deployer_user_ssh_key_file: .ssh/id_rsa
deployer_gitlab_api: https://gitlab.example.com/api/v4
# Generated at
https://gitlab.example.com/profile/personal_access_tokens
deployer_gitlab_token: secret_token_here
deployer_gitlab_key_title: "{{ ansible_hostname }}_deployer"
roles/web/tasks/main.yml
- name: Make sure deployer user has ssh key
user:
name: '{{ deployer_user }}'
generate_ssh_key: yes
- name: "Check if GitLab has this user's SSH key"
uri:
url: "{{ deployer_gitlab_api }}/user/keys"
method: GET
status_code: [200]
headers:
private-token: "{{ deployer_gitlab_token }}"
Content-Type: "application/json"
register: user_ssh_keys
- name: Assign ssh key to a variable
shell:
cat /home/{{ deployer_user }}/{{ deployer_user_ssh_key_file }}.pub
register: deployer_user_public_key
when: not user_ssh_keys.json | selectattr('title', 'equalto', deployer_gitlab_key_title) | list | length > 0
- name: Push the generated ssh key to the GitLab instance
uri:
url: "{{ deployer_gitlab_api }}/user/keys"
method: POST
status_code: [201, 400]
headers:
private-token: "{{ deployer_gitlab_token }}"
Content-Type: "application/json"
body: >
{
"title": "{{ deployer_gitlab_key_title }}",
"key": "{{ deployer_user_public_key.stdout_lines.0 }}"
}
body_format: json
when: not user_ssh_keys.json | selectattr('title', 'equalto', deployer_gitlab_key_title) | list | length > 0
- name: Ensure .ssh/config file exists
file: state=touch path="/home/{{ deployer_user }}/.ssh/config"
when: not user_ssh_keys.json | selectattr('title', 'equalto', deployer_gitlab_key_title) | list | length > 0
- name: Disable host key checking
lineinfile: dest=/home/{{ deployer_user }}/.ssh/config line='Host *\n \tStrictHostKeyChecking no\n\tUserKnownHostsFile=/dev/null'
when: not user_ssh_keys.json | selectattr('title', 'equalto', deployer_gitlab_key_title) | list | length > 0
- name: Add deploy group to sudoers file and validate
lineinfile: dest=/etc/sudoers state=present regexp='^%{{ deployer_group }}' line='%{{ deployer_group }} ALL=(ALL) NOPASSWD:ALL' validate="visudo -cf %s"
- name: Checkout source code
git:
repo: "git@gitlab.example.com:john.doe/my_repo.git"
dest: /home/{{ deployer_user }}/my_repo
key_file: /home/{{ deployer_user }}/.ssh/id_rsa
accept_hostkey: true