Introduction
I’d been wanting to check out Ansible for a while. When I learn a new technology I prefer to have a real use for it. Up to this point I hadn’t found one for Ansible, until I decided to switch my daily driver from Ubuntu to Debian. I realized that I could probably codify all of the software installs and configuration using Ansible, so that the next time I rebuild my workstation it would be automated. I’d like to share what I’ve come up with.
Setup
After installing Debian on my workstation, I updated the apt cache and installed the required dependency - which was unecessary as it was already in the Debian build I used:
sudo apt update
sudo apt install software-properties-common
Then I added the official Ansible repo:
sudo add-apt-repository --update ppa:ansible/ansible
And installed Ansible:
sudo apt install ansible
Making a Playbook
I started with installing some basic command line utils found in the default apt repos by making a playbook file called software.yml
:
---
- hosts: localhost
connection: local
become: true
tasks:
- name: Install apt packages
ansible.builtin.apt:
state: present
update_cache: true
name:
- htop
- tree
- neofetch
To apply this playbook, I ran sudo ansible-playbook software.yml
. After the success message, I was able to verify it worked by running one of the utilities, like neofetch
.
This was great, but I realized some of the software I needed (vscode, firefox, github cli) would require adding their official repos. It took a lot of searching and cross referencing Ansible documentation with installation documentation from the respective software sites. Eventually, I came up with this:
- name: Add Mozilla gpg key
ansible.builtin.apt_key:
url: https://packages.mozilla.org/apt/repo-signing-key.gpg
state: present
- name: Add Mozilla repository
apt_repository:
repo: deb [arch=amd64] https://packages.mozilla.org/apt mozilla main
- name: Add VSCode gpg key
ansible.builtin.apt_key:
url: https://packages.microsoft.com/keys/microsoft.asc
state: present
- name: Add VSCode repository
apt_repository:
repo: deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main
- name: Add Github gpg key
ansible.builtin.apt_key:
url: https://cli.github.com/packages/githubcli-archive-keyring.gpg
state: present
- name: Add Github repository
apt_repository:
repo: deb [arch=amd64] https://cli.github.com/packages stable main
Now I could add the corresponding packages to the apt install section:
- name: Install apt packages
ansible.builtin.apt:
state: present
update_cache: true
name:
- htop
- tree
- neofetch
- code
- firefox
- gh
Awesome! Except there was one app I use a lot, Obsidian, that didn’t have an official apt repo and instead published releases to GitHub. I found that I could install the latest release using the following:
- name: Install Obsidian
ansible.builtin.apt:
deb: "https://github.com/obsidianmd/obsidian-releases/releases/download/v1.5.12/obsidian_1.5.12_amd64.deb"
This worked, but I realized this would quickly not be the latest version and wouldn’t have any way to update it. So, I went down a rabbit hole of trying to program Ansible to pull the latest release info from GitHub and then install it. In the end I came up with this:
- name: Get Obsidian Releases
ansible.builtin.uri:
url: https://api.github.com/repos/obsidianmd/obsidian-releases/releases/latest
return_content: true
register: json_response
- name: Install Obsidian
ansible.builtin.apt:
deb: "{{ item.browser_download_url }}"
loop_control:
label: "{{ item.browser_download_url }}"
loop: "{{ json_response.json.assets }}"
when: item.browser_download_url is search("amd64.deb")
register: download_url
And it worked! It essentially curl’s the GitHub API for the latest release of the Obsidian official repo, parses the JSON to pick the url of the .deb
package from a list of other package types, then downloads and installs the file from that url.
Shell Configuration
At this point I had a lot of the software I wanted, but there were a number of shell configurations that I wanted to change like dark mode, screen timeout, and enabling titlebar buttons . My playbook was getting pretty big, so I made a new one called settings.yml
.
I found some of the settings I wanted to change by looking for them specifically. They all involved dconf key modification, so it was a big help when I found the following command:
dconf watch /
This puts the terminal in a monitoring mode, displaying the key and value as you change settings in graphical interfaces. So much better than digging through documentation or Stack Overflow!
With that, I found the keys and values to change and came up with this for my settings:
---
- hosts: localhost
connection: local
tasks:
- name: Screen timeout 30min
dconf:
key: /org/gnome/desktop/session/idle-delay
value: "uint32 1800"
- name: Prefer Dark
dconf:
key: /org/gnome/desktop/interface/color-scheme
value: "'prefer-dark'"
- name: Window Theme
dconf:
key: /org/gnome/desktop/interface/gtk-theme
value: "'Adwaita-dark'"
- name: Titlebar buttons
dconf:
key: /org/gnome/desktop/wm/preferences/button-layout
value: "'appmenu:minimize,maximize,close'"
One ansible-playbook settings.yml
later and I could see the changes like dark mode and titlebar buttons happen right in front of me. Cool!
Conclusion
It was nice to get my feet wet with Ansible. That said, I wonder how much I’d use it in a professional setting. I think it would depend how much of the infrastructure is self hosted. It seems like it would at least be useful for the provisioning of developer workstations.
I’ve left out some of the code for brevity. You can find the complete files at this github repo.
Cheers!
Rick
Resources
- Ansible Official Documentation - https://docs.ansible.com/