Using GIT With Ansible: A Hands On Example of Enhancing Our Automated Systems

Ansible’s real strengths are the fast speed of learning the basics and its simplicity. We all keep some configuration in a GIT service like my dot config files in Github. It is very quick and easy to automate the check out of a repository, and to distribute files from it with the built in Ansible modules.

Don’t forget to join my Discord: https://discord.gg/YbSYGsQYES

We can use the ansible.builtin.git module for cloning a GIT repository. In our case the necessary information for the module are the repo URL, the destination where we want to check out and optionally a git tag or version.

Copying the following code in a playbook will create a great foundation.

- name: Check out my dotfiles repository from Github
  ansible.builtin.git:
     repo: https://github.com/tmolnar0831/dotfiles.git
     dest: /home/tmolnar/stuff/dotfiles
     version: 4bfbaa2917844a46ab936bddba5125af16c10bca

Then the ansible.builtin.copy module can distribute the files to their designated places. Using the copy module is easy and straightforward.

We have to feed it with the source file to copy, the destination where we want to copy it, a user and group permission to set and the file permissions. In this case the source is on the remote server, so we notify Ansible about it with the remote_src parameter.

The task in our playbook should look like this.

- name: Copy the config files to my home
  ansible.builtin.copy:
    src: '{{ item.src }}'
    dest: '{{ item.dest }}'
    owner: tmolnar
    group: tmolnar
    mode: '0644'
    remote_src: true
  loop:
    - { src: /home/tmolnar/stuff/dotfiles/.vimrc, dest: /home/tmolnar/.vimrc }
    - { src: /home/tmolnar/stuff/dotfiles/.bashrc, dest: /home/tmolnar/.bashrc }

Putting these tasks together and optionally extending the code with our needs we have a playbook that checks out GIT repositories and moves the files from them to their place.

A very basic initial VM config can look like the following playbook.

---
- name: Basic OS and user setup
  hosts: all
  become_method: ansible.builtin.su

  tasks:
    - name: Install the basic packages
      ansible.builtin.apt:
        name:
          - vim
          - tmux
          - python3
          - python3-apt
          - sshpass
          - git
          - wget
          - curl
        state: present
      become: true
      become_user: root

    - name: Check out my dotfiles repository from Github
      ansible.builtin.git:
        repo: https://github.com/tmolnar0831/dotfiles.git
        dest: /home/tmolnar/stuff/dotfiles
        version: 4bfbaa2917844a46ab936bddba5125af16c10bca

    - name: Copy the config files to the root home
      ansible.builtin.copy:
        src: '{{ item.src }}'
        dest: '{{ item.dest }}'
        owner: root
        group: root
        mode: '0644'
        remote_src: true
      loop:
        - { src: /home/tmolnar/stuff/dotfiles/.vimrc, dest: /root/.vimrc }
        - { src: /home/tmolnar/stuff/dotfiles/.bashrc-root, dest: /root/.bashrc}
      become: true
      become_user: root

    - name: Copy the config files to my home
      ansible.builtin.copy:
        src: '{{ item.src }}'
        dest: '{{ item.dest }}'
        owner: tmolnar
        group: tmolnar
        mode: '0644'
        remote_src: true
      loop:
        - { src: /home/tmolnar/stuff/dotfiles/.vimrc, dest: /home/tmolnar/.vimrc }
        - { src: /home/tmolnar/stuff/dotfiles/.bashrc, dest: /home/tmolnar/.bashrc }

The playbook is idempotent and it configures files in the home of the user and the root. (Note the become keywords in the tasks.)

ansible-playbook -i inventory.ini play-os-base-config.yml --ask-become-pass --limit local
BECOME password: 

PLAY [Basic OS and user setup] *****************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************************
ok: [local]

TASK [Install the basic packages] **************************************************************************************************
ok: [local]

TASK [Check out my dotfiles repository from Github] ********************************************************************************
ok: [local]

TASK [Copy the config files to the root home] **************************************************************************************
ok: [local] => (item={'src': '/home/tmolnar/stuff/dotfiles/.vimrc', 'dest': '/root/.vimrc'})
ok: [local] => (item={'src': '/home/tmolnar/stuff/dotfiles/.bashrc-root', 'dest': '/root/.bashrc'})

TASK [Copy the config files to my home] ********************************************************************************************
ok: [local] => (item={'src': '/home/tmolnar/stuff/dotfiles/.vimrc', 'dest': '/home/tmolnar/.vimrc'})
ok: [local] => (item={'src': '/home/tmolnar/stuff/dotfiles/.bashrc', 'dest': '/home/tmolnar/.bashrc'})

PLAY RECAP *************************************************************************************************************************
local                      : ok=5    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

We have automated some basic GIT handling. This playbook can be separated into a well-functioning role later.

Don’t forget to join my Discord: https://discord.gg/YbSYGsQYES

3 thoughts on “Using GIT With Ansible: A Hands On Example of Enhancing Our Automated Systems

  1. Although tools like ansible, [chezmoi](https://www.chezmoi.io/) and [homeshick](https://github.com/andsens/homeshick) work, I find that a bare git repo works just fine for my needs.
    “`zsh
    git init –bare $HOME/.dotfiles
    alias config=’/usr/bin/git –git-dir=$HOME/.dotfiles/ –work-tree=$HOME’
    config config status.showUntrackedFiles no
    config remote add origin git@github.com:svanzoest/dotfiles.git
    config branch -M laptop
    config push -u origin laptop
    “`
    where the `~/.dotfiles` directory is a git bare repository. any file within the home folder can be versioned with normal commands like:
    “`zsh
    config status
    config add .vimrc
    config commit -m “Add vimrc”
    config push
    “`
    For every device you can create a new branch.

    Liked by 1 person

Leave a comment