Ansible
Now a long running way I have been using to manage my dotfiles have been exclusively through ansible. There are several pluses to managing through ansible and there are some negatives
Pros
- there is tons of online documentation
- its used more than just managing dotfiles
- ansible vault allows for plain storage of ssh keys! which is really cool
- you can also store a bunch of other cool stuff with ansible vault (think auth passcodes)
Cons
- it can be terribly slow
- it can be hard to make it work for certain tasks, such as installing neovim plugins
- tags can be great and super annoying
- yaml sucks
Basic Ansible
lets create a simple ansible script to clone neovim from source and build it from a specific tagged version
What is ansible?
From their github
Ansible is a radically simple IT automation system. It handles configuration management, application deployment, cloud provisioning, ad-hoc task execution, network automation, and multi-node orchestration. Ansible makes complex changes like zero-downtime rolling updates with load balancers easy. More information on the Ansible website.
You are probably thinking... wait... aren't we talking about dotfiles and environments?
Why yes we are!
This is a tool designed for "servers" and if you squint your eyes you will realize that you are just working on a "server."
NOTE: feel free to just watch
Install ansible
as all adventures start...
pip3 install ansible
The heart of ansible
Typically when you are working with ansible you are using an inventory, which is a list of all servers you have proper access to, and a series of playbooks. The playbooks are where we specify the tasks we wish to perform on one or more nodes (machines). The playbook is the heart of ansible
As a friend once said
ansible is the helicopter that drops godzilla
... godzilla being k8s
Since we are operating on our own machine we wont need the inventory part, its
just localhost
Lets just jump right into the playbook side of ansible which is where all the work is done
Your First Playbook
Lets start off by creating a playbook that will use git to download the contents of neovim to a directory in a directory of our choosing
- create a new directory, lets call it
mfansible
- create a file called
neovim.yml
- input the following
- name: My first playbook
hosts: localhost
tasks:
with this alone we can now execute ansible and see the effects
ansible-playbook neovim.yml
and you should see output that is similar to
➜ ansible-neovim-example git:(master) ✗ ansible-playbook neovim.yml
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [The Great Neovim editor] *****************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************
ok: [localhost]
PLAY RECAP *************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Congrats!
you have ran your first ansible script!
Lets do some git
Lets clone down neovim!
When it comes to using ansible, one of my favorite features is the docs and how they are organized. it just makes it so simple to google and get the exact answer out you need. ChatGPT is nice to use, but can sometimes lead you into too much usage of odd features like scripting
- Google ansible git clone
- scroll the documentation and copy the one they suggest
- perhaps combine a few to make this most efficient!
But where do we put the code we find? Well... remember that empty tasks
key?
Expected Task Output
- name: My first playbook
hosts: localhost
tasks:
- name: Git neovim
ansible.builtin.git:
repo: "https://github.com/neovim/neovim.git"
dest: "{{ lookup('ansible.builtin.env', 'HOME') }}/personal/neovim"
version: v0.10.2
Become familiar with the build first
there will be several libs that you may require to get this working so to do this correctly you will first want to build neovim by hand and keep track of the libraries that you need. There is likely a list of requirements in the BUILD.md
Making neovim requires packages
Here are the packages i needed to install from apt to get neovim
sudo apt install cmake gettext lua5.1 liblua5.1-0-dev
Lets get the libraries first
Lets translate what I installed into an ansible command.
- google how to ansible apt
- copy the proper command
Expected Code
Your code should look something like this
- name: My first playbook
hosts: localhost
tasks:
- name: Git neovim
ansible.builtin.git:
repo: "https://github.com/neovim/neovim.git"
dest: "{{ lookup('ansible.builtin.env', 'HOME') }}/personal/neovim"
version: v0.10.2
- name: Install helping libs
become: true
ansible.builtin.apt:
pkg:
- lua5.1
- liblua5.1-0-dev
- cmake
- gettext
OH NO! Crash!
If you are using apt and have to use sudo you should see the following error.
TASK [Install neovim's deps] *********************************************************
fatal: [localhost]: FAILED! => {"changed": false, "module_stderr": "sudo: a password is required\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}
Well ansible does have the ability to become the sudo but it needs the creds to do it, you can type in those creds before installing by using the -K flag
Now build!
Now all we have to build neovim and then sudo make install! We do the same process
- google make
- copy the relevant instructions
- implement the new tasks
- ...
- neovim (which is profit)!
To make neovim (from BUILD.md)
The command to run to make neovim is the following:
cd neovim && make CMAKE_BUILD_TYPE=RelWithDebInfo
then to install it we need to execute
sudo make install
Expected output
- name: My first playbook
hosts: localhost
tasks:
- name: Git neovim
ansible.builtin.git:
repo: "https://github.com/neovim/neovim.git"
dest: "{{ lookup('ansible.builtin.env', 'HOME') }}/personal/neovim"
version: v0.9.4
- name: Install helping libs
become: true
ansible.builtin.apt:
pkg:
- lua5.1
- liblua5.1-0-dev
- cmake
- gettext
- name: neovim
make:
chdir: "{{ lookup('ansible.builtin.env', 'HOME') }}/personal/neovim"
params:
CMAKE_BUILD_TYPE: "RelWithDebInfo"
- name: neovim install
become: true
make:
target: install
chdir: "{{ lookup('ansible.builtin.env', 'HOME') }}/personal/neovim"
And that is ansible
that is what it takes to create neovim ansible.
Why would i use this over a bash script
A bash script is great when you can execute it on a machine, but ansible allows you to execute all these operations on a bunch of host machines at once, your machine, uniform syntax (yml). It also allows for some custom logic based on operating system so you could interchange out the fetching mechanism to make it machine independent
Ansible can be real great. It "seems" easier to maintain than having a bunch of bash scripts for each operating system. It can also make automating your setup a bit easier.
But for me... its a no at this point. I prefer a single script that i control
- some basic convention. Convention over configuration is a mantra i support