Anjan Biswas
Anjan Biswas

Reputation: 731

How to deploy code from local git repository to remote server using Ansible

I am using Ansible 2.5. I need to do deploy code from local(controller) git repository to remote server.

I was trying with a Ansible-playbook with git module that can only deploy code from local repository to another local path or remote repository to another remote path. Its based on hosts configuration.

- git:
    repo: /home/pi/Desktop/kk/Vue-Example/
    dest: /home/pi/Desktop/bb

Here repo will be local(controller-machine) git repository path and dest will be remote machine location.

Upvotes: 8

Views: 5594

Answers (3)

mcsim
mcsim

Reputation: 1798

Here is my take:

---
- name: Create repo directory
  file:
    path: "{{project_src_destination}}"
    state: directory
- name: Init repo
  command: git init {{project_src_destination}}
  args:
    creates: "{{project_src_destination}}/.git"
- name: Test repo state
  command: git show {{project_branch}}
  args:
    chdir: "{{project_src_destination}}"
  register: result
  ignore_errors: true
  changed_when: result.rc != 0
- name: Upload the repo
  local_action:
    module: command git push ssh://{{inventory_hostname}}/{{project_src_destination}} {{project_branch}}
    chdir: "{{project_src_source}}"
  when: 'result.rc != 0'
- name: Checkout the newly created branch
  command: git checkout {{project_branch}}
  args:
    chdir: "{{project_src_destination}}"
  register: result
  changed_when: "'Switched' in result.stdout"

Unlike the previous answer, there is no need to create an intermediary archive. Can be advantageous, if one needs to do incremental updates.

A completely different approach would be just to use rsync:

- name: Copy sources
  ansible.posix.synchronize:
    src: "{{project_src_host}}"
    dest: "{{project_src_destination}}"
    delete: true
    rsync_opts:
      - "--exclude=.git"
      - "--exclude=*.pb.go"
      - "--exclude=*.o"
      - "--exclude=*.d"
      - "--filter=:- .gitignore"

Here the idea is to mostly rely on .gitignore to not copy intermediate compilation results.

Upvotes: 1

bitinerant
bitinerant

Reputation: 1571

This is exactly the workflow I wanted as well - to extract files from a local git repo I know I can depend on. In my case, I use a specific commit ID (a version that has been well-tested) rather than a branch name. If you want this, just replace 'master' below with the commit ID.

- tasks:
    - name: Make temp directory
      tempfile:
        state: directory
      register: temp_git_archive
      delegate_to: localhost
      become: no
      changed_when: False
    - name: Extract latest git commit on branch master
      shell: git archive master |tar --extract --directory={{ temp_git_archive.path }}
      args:
        chdir: /home/pi/Desktop/kk/Vue-Example/  # YOUR LOCAL GIT REPO
      delegate_to: localhost
      become: no
      changed_when: False
    - name: Copy to remote
      copy:
        src: "{{ temp_git_archive.path }}"
        dest: /home/pi/Desktop/bb  # YOUR DESTINATION DIRECTORY
    - name: Delete temp directory
      file:
        path: "{{ temp_git_archive.path }}"
        state: absent
      when: temp_git_archive.path is defined
      delegate_to: localhost
      become: no
      changed_when: False

It may be possible to use the Ansible 'git' and 'unarchive' modules in place of the 'shell' module above, but I prefer doing it in one step.

Upvotes: 7

error404
error404

Reputation: 2823

You have wrongly interpreted the use of git module of ansible. It is used to clone the remote repo at the dest path i.e either in the controller machine or in the remote hosts. You have specified local path which doesn't exists for git module as git would try to send a http/ssh request and such path doesn't exists.

The quote of the repo value from ansible is

repo: git, SSH, or HTTP(S) protocol address of the git repository.

In case you are looking to clone on the controller machine reason being ssh keys then you can use the git module delegate to localhost then use the copy module to copy from controller to remote machine

---
- name: play to checkout
  hosts: remote-hosts
  tasks:
    - name: git checkout
      repo: "{{ repo_url }}"
      dest: /tmp
      delegate_to: localhost
    - name: copy module
      synchronize:
        src: ...
        dest: ...

Upvotes: 1

Related Questions