Laziness with git and Ansible
Since I hosted my own git instance, a gogs server, there was no real backup instance, if my server was down. To comprehend that, I decided to host mirrors of some of my repositories on Codeberg. I added the mirror repositories as alt repos. But now I’ve to perform two commands to push both repos git push and git push alt. Since this was not possible in my IDE without trouble, I used the terminal for that anyway. But, as most developers, I’m lazy and wanted to improve and simplify this process for me.
The first step was a shell script I wrote, which performed both commands, placed in the path. This was already an improvement, but I still have to go to the directory of the git repository in the terminal, if I just opened the project in the IDE GUI. So there was still improvement to do. I added case handling for some arguments to the shell script. With which I could run the command for different repositories from anywhere on the system.
case $1 in
--website) echo "pushing website to all repos."
cd $WEBSITE
git push origin
git push alt;;
--md-html) echo "pushing md-html-converter to all repos."
cd $MD_HTML_CONVERTER
git push origin
git push alt;;
At this point this process was working pretty well. But as I wrote in the title, this isn’t the end of the journey.
For a project at work I was introduced to Ansible automation. I took over a project from another guy, and so I got to learn Ansible. I thought pretty fast, I’d use that in my homelab as well, to improve for example some everyday tasks.
Interlude: Ansible
Ansible is an open-source automation software. It makes automation pretty easy, I’ll give you a short overview.
It’s a python program, which uses ssh to execute tasks defined in playbooks on defined host(s). The scripts contain most importantly playbook(s), an inventory and var files. They’re all written in YAML, what makes it a bit painful — yes, I don’t like YAML — because of its hypercorrectness. One wrong blank space could kill your whole program. I speak from experience…
But at its starting point it’s pretty simple. You have to define the hosts, on which you perform the tasks, in the inventory file — optionally you can use an ini file here as well. There are many possibilities of grouping hosts, but that’s not the topic now. If you want to use variables, you can create var files and define them there. They have also the possibility of grouping. The playbook is written in a configuration style through defining which task should be executed at which point and if there are any preconditions. You can use when clauses for example.
Ansible has a mass of built-in modules to perform many actions without any extra installations. You have to make sure of course, that for example git is installed on the host, where you want to execute the playbooks. Although there is a community based library called Ansible Galaxy where you are able to get more modules.
My use case
First I used Ansible for updating all my hosts at once. That took only a fraction of the time, but if there was a reboot required I’ll get no information about that in the first place. So I put that project down and went for something else. I’m hosting my website on two different devices, just like in an Active-Active HA cluster. So I have to pull changes on my website on two different devices.
Here is Ansible coming in again. I decided to extend my shell script to also pull the changes on my hosts via Ansible.
--website) echo "pushing website to all repos."
cd $WEBSITE
git push origin
git push alt
cd $PLAYBOOKS
ansible-playbook -i inventory/inventory.ini website-pull.yaml;;
Now I went to my Ansible project: I made a new category in my inventory and created a new playbook. As I already had a shell script on every host in the path to execute just one command to pull the repo, I just triggered this shell script with Ansible. The shell script just contains a ´´change directory´´ into the repo path and a ´´git pull´´. The Ansible playbook looks like this:
- hosts: git_website
gather_facts: false
tasks:
- name: git pull baumsplitter website on known hosts
shell: .local/bin/website-pull
The gather_facts: false entry stops Ansible from collecting information about the host it’s connecting to. This is not necessary in my case and saves a bit time. It executes the shell script through the built-in shell module and leaves the host after execution. Ansible executes each task on all hosts simultaneously, which makes the process pretty efficient. In this case it takes only slightly longer as when I’d execute one git pull command.
Thoughts
At this point the playbook is very very manageable as it contains just one task. But it’s working fine and safes me a bunch of time, especially when I have to make multiple pushes and pulls in a short time. With one command execution, everything is updated and online. For this little script, which works well in “production state” I’m pretty happy with it.
I’m planing to extend this kind of playbooks for other project which are needed to pull instantly on the host device. The easiest way to manage multiple repos and devices will be different playbooks, so the playbooks themselves will stay manageable and simple. I think that’s great. Although the playbooks are most of the time easy to read, it’s way more comfortable to use multiple playbook when executing them through a shell script anyway.
I’m definitely lazier than before, but I can say I learned something ;)
~ BaumSplitter41
23.05.2026 – 23:15