I had to set up multiple machines with slightly varying configs repeatedly.
After having to SSH into the machines once in a while and deal with default
bash, I realized that I’m seriously not used to the lack of features,
aliases1, and
theme(s) that zsh + oh-my-zsh provide. In fact, I feel
slightly less efficient when forced to use just plain bash.
Many years ago, I read multiple comments recommending
Ansible to automate tasks. Although Ansible may
have been VERY overkill for this (a simple shell script would have sufficed), I
decided to try my hand at it to, ya know, learn something new. Apart from the
docs2, I used
Lorenzo
Bettini’s
playbook and Gabrgomes’ playbook
as references.
I’m sure I’m not doing it the best way; instead of running the playbook
locally, it would make more sense to have a control node that executes these
tasks remotely on targeted hosts. I also have no doubt that there are better
ways to write Ansible
Playbooks.
But eh, this gets the job done 🤷. This was a 2-4 hour experiment so please
don’t judge me. TIA.
Ensure that python3-pip is installed, optionally create a virtualenv, and pip3
install ansible. Stuff this in a shell script, or use the control node & remote
hosts method.
min-user-setup.ansible.yml:
---
# run me with `ansible-playbook -K min-user-setup.ansible.yml`- name: Setup Compooterhosts: localhosttasks:
- name: Install git, zsh, tmux, fzf, xclip, vimbecome: trueansible.builtin.package:
name:
- git - zsh - tmux - fzf - xclip - vimstate: present - name: Change user shell to zshbecome: truename: "{{ ansible_env.USER }}"shell: /usr/bin/zsh - name: Download Oh My Zsh installation scriptansible.builtin.get_url:
url: https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.shdest: /tmp/install_ohmyzsh.shmode: "0777" - name: Run OhMyZsh installation scriptansible.builtin.command:
cmd: sh /tmp/install_ohmyzsh.sh - name: Change .zshrc themeansible.builtin.replace:
path: "{{ ansible_env.HOME }}/.zshrc"regexp: 'ZSH_THEME=\"robbyrussell\"'replace: 'ZSH_THEME="essembeh"' - name: Enable .zshrc DISABLE_UNTRACKED_FILES_DIRTYansible.builtin.replace:
path: "{{ ansible_env.HOME }}/.zshrc"regexp: '# DISABLE_UNTRACKED_FILES_DIRTY=\"true\"'replace: 'DISABLE_UNTRACKED_FILES_DIRTY="true"' - name: Disable .zshrc omz:updateansible.builtin.replace:
path: "{{ ansible_env.HOME }}/.zshrc"regexp: "# zstyle ':omz:update' mode disabled"replace: "zstyle ':omz:update' mode disabled" - name: Change tmux configansible.builtin.copy:
dest: "{{ ansible_env.HOME }}/.tmux.conf"content: | set -g default-terminal "screen-256color"
set -g status-bg red
set -g status-fg blackmode: "0664" - name: Create .local/binansible.builtin.file:
path: "{{ ansible_env.HOME }}/.local/bin/"state: directorymode: "0775" - name: Get custom utilitiesansible.builtin.get_url:
url: https://...dest: "{{ ansible_env.HOME }}/.local/bin/custom-utils"mode: "0775" - name: Add .local/bin to pathansible.builtin.lineinfile:
path: "{{ ansible_env.HOME }}/.zshrc"insertafter: 'export ZSH=\$HOME/\.oh-my-zsh'line: "path+={{ ansible_env.HOME }}/.local/bin/"# clipboard: `echo 'hello' | cb`# may have to use xsel if xclip doesn't work (xsel -ip) - name: Add alias cbansible.builtin.lineinfile:
path: "{{ ansible_env.HOME }}/.zshrc"insertafter: "EOF"line: 'alias cb="xclip -i"' - name: Add alias objdansible.builtin.lineinfile:
path: "{{ ansible_env.HOME }}/.zshrc"insertafter: "EOF"line: 'alias objd="objdump -dlS --visualize-jumps=color"'...
Footnotes
1 Gotta love glod and glols. These aliases of
git log --graph come with the oh-my-zsh git
plugin. A lot
of these aliases have become muscle memory at this point. ↩
2 Ansible’s docs are pretty darn good, but holy moly
that search is occasionally difficult to go through due to the sheer number of
features. It’s a good thing that built-in gets ranked to the top. Although…
when I was experimenting with it a week `or so ago, built-in wasn’t ranked to the
top. Looks like they changed it — going through the recent release notes, it
looks like they tweak the weights of pages for ordering search results. I may
have been visiting the docs when there was improper weighting. Regardless, good
documentation once you get the hang of it after a half-hour. ↩