ubuntu-dev-playbook icon indicating copy to clipboard operation
ubuntu-dev-playbook copied to clipboard

Ansible roles and Makefiles to configure my Ubuntu LTS based servers, virtual machines, and desktops

ubuntu-dev-playbook

Test Lint Calendar Versioning

Ansible Playbook to configure my laptops and desktops

I care about not having to think too much about my setup between machines. Especially when I want to get right to work.

For that reason, it is very comfortable for me to have the same base configuration on each machine (look, feel, keyboard shortcuts, core software, etc.).

My journey to the current state of this repo

  • I found a cool bash script on the internet (I didn't understand most of it) 🤷
  • I modified cool bash script for my needs and it worked! 🚀
  • I learned about Makefiles. 😄
  • I proceeded to do everything with Makefiles. 🤩🤩🤩
  • I got tired of running successive Make targets over and again 😐.
  • I used Ansible at work and decided to take a course to learn more about it. 🤓
  • I put off actually taking the plunge to use Ansible. 🕒🕕🕘🕛
  • I finally took the plunge and decided to use Ansible for my configuration. ✔️

Supported Ubuntu LTS Versions

I will support the LTS versions I use. There are no plans to support non-LTS versions.

LTS Last Supported Branch/Tag
Ubuntu 20.04 (including elementary OS 6) main
Ubuntu 18.04 2020.1.0

Use Cases


I've aligned ansible tags/roles around my common use cases:

  • Terminal/WSL
  • Dotfiles
  • Hyper-V
  • Desktop

Terminal/WSL

Shell

Development Tooling

  • ansible,
  • docker,
  • docker-compose,
  • nodejs, yarn
  • python3.8,
  • gh GitHub CLI
  • yarn
  • terraform
  • linode CLI

Dotfiles

Check out their Getting Started Documentation

The ansible role yadm does more or less the following:

yadm clone -b main https://github.com/iancleary/dotfiles --bootstrap

This clones my dotfiles repo via HTTPS using yadm's bootstrap standard command.

My Bootstrap script is iancleary/dotfiles/blob/main/.config/yadm/bootstrap. It's purpose is to:

  • loads my dotfiles (including SSH keys)
  • decrypt the private key (prompts for password),
  • add the key to ssh-agent,
  • tests the connection,
  • and exit.

Hyper-V

This role allows you to set the screen resolution in /etc/default/grub.

Desktop

Integrated Development Environment

If you prefer a fully open source option, checkout VSCodium! Set "code_executable" to "/snap/bin/codium".

Application Base

  • Flatpak,
  • Snap,

AppImageLauncher

Application Launcher

  • ULauncher, A ctrl + spacebar productivity bar, Ulauncher is inspired by Alfred for macOS and similar semantic search tools that followed in its wake.

Backups

Screenshots and GIFs

Flameshot keybinding to the Print Screen key using gsettings

  • Peek, a simple screen recorder with an easy to use interface

Utilities

  • Caffeine,
  • Nordvpn,
  • PDFSlicer
  • Blanket: Background sounds
  • Flatseal: Manage flatpak permissions
  • WhatIP: Info on your IP
  • Bitwarden: A secure and free fassword manager for all of your devices

Music

  • Spotify,

Notes

  • cherrytree,
  • Standard Notes,

System Info

Email, Contacts, Calendar

  • TBD

File Storage

  • Tresorit

Existing Machine

On an existing machine, I run the following bash command, to ensure I am consistent with my playbook

Make All

make all

This target runs four other targets in series:

  • bootstrap
  • bootstrap-check
  • install
  • non-ansible

Let's go through each.

Make bootstrap

This installs several packages with apt and python packages per the requirements-ansible.txt file.

This includes Ansible, using Python3.

This also moves the home-local-bin.sh file to the /etc/profile.d/ folder as described above.

The yarn roles does a similar operation, except with Ansible instead of bash.

Make bootstrap-check

This is to confirm both the ansible and psutil Python3 packages are installed and on the $PATH.

If the pip installation falls back to using the --user flag, packages will be located in the following directory under $HOME:

Goal: export PATH="$HOME/.local/bin:$PATH" without duplication!

#/etc/profile.d/home-local-bin.sh

addToPATH() {
  case ":$PATH:" in
    *":$1:"*) :;; # already there
    *) PATH="$1:$PATH";; # or PATH="$PATH:$1"
  esac
}

# Important for python pip packages installed with --user
addToPATH "$HOME/.local/bin"

make bootstrap will set this up for you!

Source: duplicate-entries-in-path-a-problem

Make install

This runs the playbook.yml Ansible playbook.

The following two commands yield the same bash command:

make install
ansible-playbook playbook.yml \
-i inventory \
--ask-become-pass \
-e '{"users": [{"username": "$(shell whoami)"}]}'

Note: $(shell whoami) in a Makefile translates to $(whoami) in bash.

The "-e" is for extra variable and is from my Ansible Galaxy role iancleary/ansible-role-zsh#example-playbook

Make non-ansible

This the targets that I found easier to maintain with bash or Makefile scripts.

# configure Flameshot with gsettings to bind to PrtScr
make flameshot-keybindings

# Ubuntu 20.04 defaults
make python-three-eight-install
make python-three-eight-supporting

...

Naming Convention for Make Targets

make check and make install are two of the standard Makefile targets for this repo.


New Machine Setup Scripts

For a new machine, I run the following command to set up my computer:

Please make sure you adjust your hostname as Ansible keys off this variable. I like to do this during the initial configuration of the machine.

This will prompt you for your sudo password for the bash script and then once later for ansible's "BECOME PASSWORD" prompt.

Voila! 🎉🎉🎉

New Terminal Setup

wget -qO- \
https://github.com/iancleary/ubuntu-dev-playbook/raw/main/run_terminal.sh | \
bash

New Desktop Setup

wget -qO- \
https://github.com/iancleary/ubuntu-dev-playbook/raw/main/run_desktop.sh | \
bash

Overriding Defaults

Not everyone's development environment and preferred software configuration is the same.

You can override any of the defaults configured in default.config.yml by creating a config.yml file and setting the overrides in that file. For example, you can customize the installed packages and apps with something like:

    nodejs_version: "14.x"
    nodejs_npm_global_packages:
      - name: "@vue/cli"
      - name: "nativefier"
      - name: "markdownlint-cli"
      - name: "carbon-now-cli"

Any variable can be overridden in config.yml; see the supporting roles' documentation for a complete list of available variables.

Order of precedence for variables

  • Any content in the config.yml has the highest precedence (not version controlled; sensitive)
  • The version controlled default.config.yml file.

This allows hostnames to remain private outside of version control, for say secret operations 🕵️

Example Using This Repo As Is

For example, a config.yml could contain:

---
nodejs_npm_global_packages:
  - name: "@vue/cli"
  - name: "@gridsome/cli"

Example Forking This Repo

For example, a default.config.yml could contain:

---
nodejs_npm_global_packages:
  - name: "@vue/cli"

Then run make all

Voila (with your edits)! 🚀🚀🚀


Quick Note on /etc/profile.d/

Investigate this folder and your ~/.bashrc, ~/.zshrc, etc. files will become simpler and more maintainable! 🚀

Let's stuff a few more lines of configuration into that file, it will be fine 😬😬😬😬.

Tl;dr is that most shells source all files in that folder, similar to source ~/.bashrc on a fresh Ubuntu install. The main advantage for using the /etc/profile.d/ folder is that it is modular and maintainable.

Fast forward to your using that folder as it was intended.

A zen like calm washes over you now that there is a single file per application and use case!

Your messy filing cabinet of assorted patches is no more. 🔥

The . /etc/profile command is used to manually source the `/etc/profile.d/ folder.

Changes

See CHANGELOG for history.

Linting

Linting is performed on common file types:

Requirements_ansible.txt

Notable Ansible Modules Used with regards to dependencies

  • snap
    • This drives the ansible >=2.8.0 requirement

Authors

I benefited from the source work of others, see AUTHORS.md.

My choice to open source my work here is to share back with you.

If you wish to contribute, see CONTRIBUTING.md