Automating Development Environments with Ansible & Chezmoi

Kevin Howell

Red Hat

Agenda

  • Background & Framing
  • Ansible
  • Chezmoi
  • Inspiration

About Me

  • Principal Software Engineer at Red Hat
  • console.redhat.com subscriptions Tech Lead
  • Raleigh, NC
  • @kahowell@mastodon.social
  • https://kahowell.net

Why

System replacement

Multiple machines

Share between Work & Home

Pets vs. Cattle

What about pet cows?

Other Motivations

Learn a new skill

Share

Cool Factor

https://xkcd.com/1205/

Framing

Layers

G Base OS Install Base OS Install System Customizations System Customizations Base OS Install->System Customizations User Customizations User Customizations Base OS Install->User Customizations Packages Packages System Customizations->Packages System Config System Config System Customizations->System Config User Config User Config User Customizations->User Config Tools Tools User Customizations->Tools Scripts Scripts User Customizations->Scripts

Base OS Install

Just install and accept defaults.

  • … vs Kickstart/unattended install
  • … vs Custom Install Image

Ansible - Why

  • automate lots of things
  • python

Ansible Installation

dnf install -y ansible

for Ubuntu

apt install -y ansible

Basic Ansible Setup

# go to a standard role directory
mkdir -p ~/.ansible/roles; cd ~/.ansible/roles
# create a role
ansible-galaxy role init $USER-environment

Ansible Role Contents

├── defaults
│   └── main.yml
├── files
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── README.md
├── tasks
│   └── main.yml
├── templates
├── tests
│   ├── inventory
│   └── test.yml
└── vars
    └── main.yml

Ansible - Basic Workflow

# update it to do some stuff
$EDITOR tasks/main.yml
# run it - lazy shortcut
ansible -K localhost -c local \
  -m include_role -a name=$USER-environment

(and commit/push to a repo for sharing)

Packages

Package types:

  • rpm/deb
  • flatpak
  • snap
  • homebrew (linuxbrew)
- name: Install RPMs
  ansible.builtin.dnf:
    name:
      - '@Development Tools'
      - ansible-lint

Package Origin Preferences

  • Distro packages
  • Flatpak
  • Homebrew
  • Snap

System Config - Files

files/no-passwords.conf

PasswordAuthentication no

Ansible:

- name: Disable ssh password authentication
  become: true
  ansible.builtin.copy:
    src: no-passwords.conf
    dest: /etc/ssh/sshd_config.d/no-passwords.conf
    mode: '0600'

System Config - Templates

templates/sudoers-custom.j2

{{ ansible_user_id }} ALL=(ALL) NOPASSWD: ALL

Ansible:

- name: Land sudoers template
  ansible.builtin.template:
    src: sudoers-custom.j2
    dest: /etc/sudoers.d/sudoers-custom
    validate: /usr/sbin/visudo -cf %s

Using Ansible Elsewhere

ansible-galaxy role install \
  --force \
  git+https://github.com/$USER/$USER-environment
ansible -K localhost -c local \
  -m include_role -a name=$USER-environment

Note

You can apply remotely as well, see docs.

Ansible - Other Capabilities

  • Manage users/groups
  • Manage services/jobs (systemd & cron)
  • Execute commands/scripts

Chezmoi

Chezmoi - Why

  • lighter weight
  • better than files in a git repo
  • ergonomics

Chezmoi Installation

# also pulls dotfiles if you already use chezmoi
sh -c "$(curl -fsLS get.chezmoi.io)" \
  -- init \
  --apply \
  $GITHUB_USERNAME

User Config

  • vim vs. emacs
  • vs. vscode
  • vs. vscodium
  • .bashrc
  • .zshrc
  • .gitconfig
chezmoi add ~/.bashrc
chezmoi git commit
chezmoi git push

Templates

dot_gitconfig.tmpl

[user]
  name = Kevin Howell
  email = {{ .email }}
[core]
  editor = vim
[diff]
  tool = meld
[init]
  defaultBranch = main

Tools

Useful code that isn’t distro packaged (yet)

GitHub Releases

Python Packages

Managing GitHub Releases

~/.local/share/chezmoi/ .chezmoiexternal.toml.tmpl

{{ $versions := (fromYaml (include "versions.yaml")) -}}
["bin/ollama"]
    type = "file"
    executable = true
    url = "https://github.com/ollama/ollama/releases/download/{{ $versions.ollama }}/ollama-linux-amd64"

Tip

You can use this with renovate to get automated updates.

Managing Python Packages

~/.local/share/chezmoi/ run_after_poetryinstall.sh

#!/bin/bash
cd ~/tools/python  # make sure include this in $PATH
poetry install --no-root --sync

Note

Can follow a similar pattern for npm packages.

Tip

You can use this with renovate/dependabot to get automated updates.

Scripts

  1. scripts git repo (can add to $PATH)
  2. directly in dotfiles repo

Using Chezmoi Elsewhere

chezmoi init $username --apply

Inspiration

  • Browse Ansible Galaxy for roles (https://galaxy.ansible.com)
  • Browse Ansible collections docs (https://docs.ansible.com)
  • Search GitHub for topic: chezmoi (https://github.com/topics/chezmoi)
  • Search github for dotfiles repos

My Repos

  • https://github.com/kahowell/kahowell-environment
  • https://github.com/kahowell/dotfiles

Red Hat Developer

  • no-cost subscription for individuals
  • free sandbox environments
  • https://developers.redhat.com

Q&A

Thanks for attending!

  • @kahowell@mastodon.social
  • https://kahowell.net

red.ht/SCALE2024