4
\$\begingroup\$

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
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.