AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

Ansible git Clone via SSH: Deploy Keys & Repository Guide

By Luca Berton · Published 2024-01-01 · Category: installation

How to clone git repositories via SSH with Ansible. Configure deploy keys, accept host keys, manage private repos, and automate git-based deployments.

Ansible git Clone via SSH: Deploy Keys & Repository Guide

How to checkout git repository via SSH?

I'm going to show you a live Playbook with some simple Ansible code. I'm Luca Berton and welcome to today's episode of Ansible Pilot

See also: ansible.builtin.git Module: Clone & Checkout Git Repositories (Guide)

Ansible checkout git repository

Today we're talking about Ansible module git. The full name is ansible.builtin.git which means is part of the collection of modules "builtin" with ansible and shipped with it. This module is pretty stable and out for years. The purpose is to Deploy software (or files) from git checkouts in our managed hosts. If you would like to fetch via SSH please refer to: Checkout git repository HTTPS - Ansible module git

Parameters and Return Values

The parameter list is pretty wide but I'll summarize the most useful. • repo _path_ • dest _string_ • update _boolean_ • key_file _path_ - SSH private key

The parameter list is pretty wide but I'll summarize the most useful. The only required parameters are "repo" and "dest". The "repo" parameter specifies the source repository URL, in our use case, in the SSH way. The "dest" parameter specifies the destination path. The "update" parameter retrieves new revisions from the already synched origin repository. The "key_file" parameter specifies the path in the filesystem where to store the SSH private key. Please note that the SSH private key is a path on the target host. Please note also that the SSH public key needs to be already shared in your Git server. • after _string_

The most interesting return value is "after" which contains the last commit after the update process.

See also: Ansible git Module: Clone Repos & Checkout Commits (ansible.builtin.git Guide)

Demo

Let's jump in a real-life playbook to checkout a git repository with Ansible • git_ssh.yml

---
- name: git module Playbook
  hosts: all
  vars:
    repo: "git@github.com:lucab85/ansible-pilot.git"
    dest: "/home/devops/ansible-pilot"
    sshkey: "~/.ssh/id_rsa"
  tasks:
    - name: ensure git pkg installed
      ansible.builtin.yum:
        name: git
        state: present
        update_cache: true
      become: true

- name: checkout git repo ansible.builtin.git: repo: "{{ repo }}" dest: "{{ dest }}" key_file: "{{ sshkey }}"

code with ❤️ in GitHub

Conclusion

Now you know how to checkout git repository via SSH with Ansible.

See also: Failed to Connect via SSH in Ansible: Full Troubleshooting Guide

SSH Authentication Methods

Deploy key (recommended)

- name: Install deploy key
  ansible.builtin.copy:
    content: "{{ vault_deploy_key }}"
    dest: /home/deploy/.ssh/deploy_key
    owner: deploy
    mode: '0600'
  no_log: true

- name: Clone private repo ansible.builtin.git: repo: git@github.com:myorg/private-repo.git dest: /opt/myapp version: main key_file: /home/deploy/.ssh/deploy_key accept_hostkey: true

SSH agent forwarding

# ansible.cfg
[ssh_connection]
ssh_args = -o ForwardAgent=yes
- name: Clone using forwarded agent
  ansible.builtin.git:
    repo: git@github.com:myorg/private-repo.git
    dest: /opt/myapp
    accept_hostkey: true

SSH config on remote host

- name: Configure SSH for GitHub
  ansible.builtin.copy:
    content: |
      Host github.com
        IdentityFile ~/.ssh/deploy_key
        StrictHostKeyChecking accept-new
    dest: /home/deploy/.ssh/config
    owner: deploy
    mode: '0600'

Pre-add Host Keys

- name: Add GitHub host key
  ansible.builtin.known_hosts:
    name: github.com
    key: "github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl"

Complete Deployment Playbook

---
- name: Deploy app from Git (SSH)
  hosts: webservers
  become: true
  tasks:
    - name: Install git
      ansible.builtin.package:
        name: git
        state: present

- name: Deploy SSH key ansible.builtin.copy: content: "{{ vault_deploy_ssh_key }}" dest: /home/www-data/.ssh/deploy_key owner: www-data mode: '0600' no_log: true

- name: Clone repository ansible.builtin.git: repo: git@github.com:myorg/webapp.git dest: /var/www/webapp version: main key_file: /home/www-data/.ssh/deploy_key accept_hostkey: true force: true become_user: www-data register: git_result notify: restart webapp

- name: Show deployed version debug: msg: "Deployed {{ git_result.after[:8] }}"

SSH vs HTTPS

| Method | Pros | Cons | |--------|------|------| | SSH | No password in URLs, deploy keys | Key management, port 22 | | HTTPS | Works through firewalls | Token in URL if logged |

FAQ

"Permission denied (publickey)" fix

Check key permissions: chmod 600 deploy_key Ensure key is added to GitHub as deploy key Verify key_file path is correct Check key ownership matches become_user

Clone Repository

- name: Clone repository
  ansible.builtin.git:
    repo: git@github.com:myorg/myapp.git
    dest: /opt/myapp
    version: main
  become: true
  become_user: deploy

Clone with SSH Key

- name: Deploy SSH key
  ansible.builtin.copy:
    content: "{{ vault_deploy_key }}"
    dest: /home/deploy/.ssh/deploy_key
    owner: deploy
    mode: '0600'
  become: true

- name: Clone with specific key ansible.builtin.git: repo: git@github.com:myorg/myapp.git dest: /opt/myapp key_file: /home/deploy/.ssh/deploy_key accept_hostkey: true version: main become: true become_user: deploy

Checkout Specific Branch/Tag

# Branch
- git:
    repo: git@github.com:myorg/myapp.git
    dest: /opt/myapp
    version: develop

# Tag - git: repo: git@github.com:myorg/myapp.git dest: /opt/myapp version: v2.5.0

# Specific commit - git: repo: git@github.com:myorg/myapp.git dest: /opt/myapp version: abc123def456

HTTPS Clone

- ansible.builtin.git:
    repo: https://github.com/myorg/myapp.git
    dest: /opt/myapp
    version: main

Deployment Pattern

---
- name: Deploy application
  hosts: webservers
  become: true
  vars:
    app_version: v2.5.0
    app_dir: /opt/myapp
  tasks:
    - name: Clone/update repository
      ansible.builtin.git:
        repo: git@github.com:myorg/myapp.git
        dest: "{{ app_dir }}"
        version: "{{ app_version }}"
        force: true
      register: git_result
      become_user: deploy
      notify: restart app

- name: Install dependencies ansible.builtin.pip: requirements: "{{ app_dir }}/requirements.txt" virtualenv: "{{ app_dir }}/venv" when: git_result.changed

- name: Run migrations ansible.builtin.command: cmd: "{{ app_dir }}/venv/bin/python manage.py migrate" chdir: "{{ app_dir }}" when: git_result.changed run_once: true

handlers: - name: restart app service: name=myapp state=restarted

Key Parameters

| Parameter | Description | |-----------|-------------| | repo | Repository URL (SSH or HTTPS) | | dest | Local clone path | | version | Branch, tag, or commit hash | | key_file | SSH private key path | | accept_hostkey | Auto-add host to known_hosts | | force | Discard local changes | | depth | Shallow clone depth | | update | Pull if already cloned (default: true) | | single_branch | Clone only specified branch | | recursive | Initialize submodules |

Shallow Clone (Faster)

- git:
    repo: git@github.com:myorg/myapp.git
    dest: /opt/myapp
    depth: 1
    single_branch: true
    version: main

FAQ

"Permission denied (publickey)" error?

Check SSH key permissions: chmod 600 ~/.ssh/deploy_key Ensure accept_hostkey: true or add GitHub to known_hosts Check the key is added to the repository's deploy keys

How do I handle local changes?

force: true discards local changes. Without it, the task fails if there are uncommitted changes.

Can I clone submodules?

- git:
    repo: git@github.com:myorg/myapp.git
    dest: /opt/myapp
    recursive: true  # Init and update submodules

Clone via SSH

- ansible.builtin.git:
    repo: git@github.com:myorg/myapp.git
    dest: /opt/myapp
    version: main
    accept_hostkey: true
  become: true
  become_user: deploy

Deploy Key Setup

# 1. Generate deploy key
- community.crypto.openssh_keypair:
    path: /home/deploy/.ssh/deploy_key
    type: ed25519
    owner: deploy
    mode: '0600'
  become: true

# 2. Clone with specific key - git: repo: git@github.com:myorg/myapp.git dest: /opt/myapp key_file: /home/deploy/.ssh/deploy_key accept_hostkey: true become: true become_user: deploy

SSH Config for Multiple Repos

# Deploy SSH config for multiple GitHub repos
- copy:
    content: |
      Host github-myapp
        HostName github.com
        User git
        IdentityFile ~/.ssh/myapp_deploy_key
        IdentitiesOnly yes

Host github-config HostName github.com User git IdentityFile ~/.ssh/config_deploy_key IdentitiesOnly yes dest: /home/deploy/.ssh/config owner: deploy mode: '0600' become: true

# Use custom host alias - git: repo: git@github-myapp:myorg/myapp.git dest: /opt/myapp

Accept Host Key Safely

# Option 1: accept_hostkey (adds on first connect)
- git:
    repo: git@github.com:myorg/myapp.git
    dest: /opt/myapp
    accept_hostkey: true

# Option 2: Pre-populate known_hosts - known_hosts: name: github.com key: "github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl" state: present become: true become_user: deploy

SSH Agent Forwarding

# ansible.cfg
# [ssh_connection]
# ssh_args = -o ForwardAgent=yes

# Then git uses your local SSH agent - git: repo: git@github.com:myorg/myapp.git dest: /opt/myapp

Full Deploy Playbook

- hosts: webservers
  become: true
  vars:
    app_repo: git@github.com:myorg/myapp.git
    app_version: v2.5.0
    deploy_user: deploy
  tasks:
    - name: Ensure deploy user SSH directory
      file:
        path: "/home/{{ deploy_user }}/.ssh"
        state: directory
        owner: "{{ deploy_user }}"
        mode: '0700'

- name: Deploy SSH key copy: src: keys/deploy_key dest: "/home/{{ deploy_user }}/.ssh/deploy_key" owner: "{{ deploy_user }}" mode: '0600'

- name: Clone/update repository git: repo: "{{ app_repo }}" dest: /opt/myapp version: "{{ app_version }}" key_file: "/home/{{ deploy_user }}/.ssh/deploy_key" accept_hostkey: true become_user: "{{ deploy_user }}" register: git_result notify: restart app

- name: Install dependencies command: /opt/myapp/install.sh when: git_result.changed

FAQ

"Permission denied (publickey)" error?

Check: key file permissions (must be 0600), correct user (become_user), key added to GitHub/GitLab as deploy key.

How to use with GitLab?

Same approach — just change github.com to your GitLab hostname. Deploy keys work identically.

Can I use HTTPS instead?

Yes, but SSH keys are more secure than embedding tokens in URLs. For HTTPS: repo: https://{{ token }}@github.com/myorg/repo.git

Related Articles

Ansible become guideunderstanding Ansible roles

Category: installation

Watch the video: Ansible git Clone via SSH: Deploy Keys & Repository Guide — Video Tutorial

Browse all Ansible tutorials · AnsiblePilot Home