Skip to content
Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Development Linux Setup

GitHub release License pre-commit Known Vulnerabilities

Branch Build Status Coding Style
master Build Status Coding Style
develop Build Status Coding Style

This is a collection of Ansible roles and tasks to setup a Linux development machine.

Read my Machine Setup Guide for instructions.


See markosamuli/macos-machine for my macOS setup.


This setup has been tested on the following Linux releases:

Older releases are only tested using Travis CI builds and might not be fully supported:

Ubuntu on WSL

I've used this playbook to install packages on Ubuntu running on Windows Subsystem for Linux on Windows 10.

I'm currently running Ubuntu 20.04 LTS on WSL2 and will not be testing any future configuration on WSL1.

Some packages are known not to work so I've added custom fact is_wsl that can be used to check if we're running Linux on Windows and these will be skipped during the set up.

Pengwin on WSL

I'm no longer using or testing the playbooks on Pengwin Linux since I've upgraded to WSL2 and Ubuntu 20.04 LTS and Debian buster on my Windows 10 environment.


Install Git and curl:

sudo apt update
sudo apt install curl git

You can run the installer script that will clone the code from GitHub and run the setup script.

curl -s | bash -

Getting Started

Clone this project locally and run the ./setup script.

git clone
cd linux-machine

Local options

You can pass custom variables to the Ansible playbook and roles by creating a machine.yaml file to customise your configuration.

cp machine.yaml.example machine.yaml

You can also use my customizations:

ln -s machine.msk.yaml machine.yaml

The setup script will detect if this file exists and passes it to the Ansible Playbook with --extra-vars.


The setup script will try to install Ansible

Ansible version

Ansible version 2.9 is installed by default.

You can define MACHINE_ANSIBLE_VERSION environment variable to change the installed version.

Example to use Ansible 2.8 instead of Ansible 2.9:


Force Ansible reinstall

To remove existing Ansible versions and force installation of Ansible, you can use the --reinstall-ansible argument, for example:

./setup --reinstall-ansible

Installing Ansible with APT

The setup script will install Ansible using APT from Ansible PPAs if the ansible command is not found on your system.

Ubuntu 20.04 LTS will not use Ansible PPAs as the builds for this release are missing.

Version PPA
2.8 ansible/ansible-2.8
2.9 (default) ansible/ansible-2.9

Installing Ansible from PyPI into virtualenv

If an acceptable Ansible APT package installation candidate can't be found the setup script will try to install Ansible with pip in a local virtuelenv.

If virtuelenv can't be found the setup script the setup will fail.

You can disable installation from PyPI with --disable-ansible-pypi argument, for example:

./setup --disable-ansible-pypi

Installing Ansible from PyPI into pyenv environment

If the user has set up a local development environment with pyenv and this is defined in a .python-version file in the repository root, the setup script will install Ansible into this environment.

Same as with the local virtualenv, you can disable installation from PyPI with --disable-ansible-pypi argument, for example:

./setup --disable-ansible-pypi

Software installed by the playbooks


Zsh is installed by default. You can disable this in the configuration:

install_zsh: false

Homebrew on Linux (aka Linuxbrew)

Homebrew can be installed on Linux by enabled the following option:

install_linuxbrew: true

To enable and install:

make install-linuxbrew

Installation will be done using markosamuli.linuxbrew Ansible role.

Terminals for desktop environments

Installed on all non-WSL environments:

Developer tools

Installed on all non-WSL environments:

  • Meld, a visual diff and merge tool


To install Slack desktop application via Snap package:

install_slack: true

Productivity applications

Installed on non-WSL environments:

To enable and install:

make install-productivity

To disable:

install_productivity: false


Antivirus software can be installed:

To enable and install:

make install-antivirus

To enable manually:

install_antivirus: true

Security tools

Security tools that can be installed:

To enable and run the security playbook:

make install-security

To enable manually:

install_security: true

Security hardening

Install optional security hardening tools:

  • passwdqc for password/passphrase strength checking and enforcement
  • USBGuard for protecting system against rogue USB devices
  • debsums tool for verification of installed package files against MD5 checksums

To enable and run the security hardening playbook:

make install-security-hardening

To enable manually:

install_security_hardening: true


Install optional system monitoring tools:

To enable and run the monitoring playbook:

make install-monitoring

To enable manually:

install_monitoring: true

Command line tools

Run the tools playbook:

make install-tools

Visual Studio Code

Visual Studio Code will be installed on non-WSL environments via Snap package.

See Developing on WSL for instructions how to install and use Visual Studio Code Remote - WSL extension.


Latest version of Vim will be installed using the package manager.

To install Neovim enable it in machine.yaml:

install_neovim: true

asdf version manager

You can install asdf version manager by adding the following option to your machine.yaml:

install_asdf: true

To configure asdf plugins and package versions to install, add them into your machine.yaml configuration.

  - name: kubectl
  - name: concourse


Use Ubuntu/Debian packages to install Python on the system:

  • Python with python3 package — installed Python version will depend on the OS release version
  • pip with python3-pip package
  • [virtualenv] from PyPI

Use pyenv to install and manage Python versions for the current user:

Run Python playbook:

make install-python

You can disable installation by adding the following option to your machine.yaml:

install_python: false

The markosamuli.pyenv role will modify your .bashrc and .zshrc files during the setup. If you want to disable this, edit machine.yaml file and disable the following configuration option.

pyenv_init_shell: false


To install Ruby for development, enable it in your machine.yaml configuration:

install_ruby: true

This will install:

Run Ruby playbook:

make install-ruby

To change the installed rubies and default version, add the following to your machine.yaml file and customize it to your needs:

  env: user
  version: v1.1.2
  default_ruby: 2.6.3
    - version: 2.6.3

The role doesn't update your .bashrc or .zshrc files but adds a global initialization script in /etc/profile.d/ If this doesn't work on your environment, add something like below to initialize rbenv in your shell:

if [ -z "${RBENV_ROOT}" ]; then
  if [ -d "$HOME/.rbenv" ]; then
    export PATH=$HOME/.rbenv/bin:$PATH;
    export RBENV_ROOT=$HOME/.rbenv;
    eval "$(rbenv init -)";


Install Rust programming language with markosamuli.rust role.

Enable with:

install_rust: true

To avoid modifying path during install:

rust_modify_path: false

Run Rust playbook:

make install-rust

To uninstall Rust, run:

rustup self uninstall


Run Node.js playbook:

make install-node

You can disable installation by adding the following option to your machine.yaml:

install_nodejs: false


Go programming language installed using markosamuli.golang Ansible role.

Run Go playbook:

make install-golang

You can disable installation by adding the following option to your machine.yaml:

install_golang: false

Go tools installed for development:

  • golint is a linter for Go source code
  • goimports is a tool for updating your Go import lines
  • errcheck is a program for checking for unchecked errors in go programs
  • go-callvis is a development tool to help visualize call graph of a Go program using interactive view
  • gopkgs is a tool that provides list of available Go packages that can be imported
  • Stringer is a tool to automate the creation of methods that satisfy the fmt.Stringer interface
  • guru is a tool for answering questions about Go source code
  • staticcheck is a linter for Go source code


You can install Lua programming language by adding the following option to your machine.yaml file:

install_lua: true

Run Lua playbook:

make install-lua

This will also install LuaRocks package manager and luacheck rock using the custom luarocks module.


Latest version of Git will be installed.

Vagrant and VirtualBox

Vagrant and VirtualBox are no longer installed by default, but you can enable them by adding:

install_vagrant: true


Docker will be installed by default.

Run Docker playbook:

make install-docker

To disable installation, add:

install_docker: false


To install Packer add:

install_packer: true


Terraform is installed using tfenv Terraform version manager.

Run Terraform playbook:

make install-terraform

Disable Terraform installation with:

install_terraform: false

Amazon Web Services

  • aws-shell - interactive shell for AWS CLI
  • AWS Vault - a vault for securely storing and accessing AWS credentials in development environments
  • cli53 - command line tool for Amazon Route 53

You can disable installation by adding the following option to your machine.yaml:

install_aws: false

Google Cloud Platform

Google Cloud SDK installed from the archive file under user home directory.

Run Google Cloud SDK playbook:

make install-gcloud

Default install path is in ~/google-cloud-sdk, but you can install it to another location, for example if you prefer ~/opt/google-cloud-sdk add the following option:

gcloud_install_path: ~/opt

To prefer python3 over python2 during Google Cloud SDK install:

gcloud_prefer_python3: true

The markosamuli.gcloud role will modify your .bashrc and .zshrc files. To disable this and manage the configuration yourself, disable the following configuration option in the machine.yaml file:

gcloud_setup_shell: false

You can disable installation by adding the following option to your machine.yaml:

install_gcloud: false

If you prefer to install Google Cloud SDK using package manager, enable it in the machine.yaml configuration file:

gcloud_install_from_package_manager: true

Changes to existing configuration

The installer makes changes to your ~/.bashrc and ~/.zshrc files, so take backup copies of them before running the script.

Ansible Roles

The following external Ansible roles are installed and used. See requirements.yml file for the installed versions.

To install roles:

make install-roles

To update roles to the latest release versions:

make update-roles

To remove any outdated roles:

make clean-roles
Role Build status
markosamuli.asdf Build Status
markosamuli.aws_tools Build Status
markosamuli.gcloud Build Status
markosamuli.golang Build Status
markosamuli.linuxbrew Build Status
markosamuli.nvm Build Status
markosamuli.packer Build Status
markosamuli.pyenv Build Status
markosamuli.vagrant Build Status
markosamuli.hyper Build Status


You should have Python 3.7 or newer installed for the development tools and pre-commit hooks to work.

Install development environment, including Git pre-commit hooks:

make setup-dev

Lint code and configuration:

make lint


This is based on my previous setup markosamuli/machine that was forked off from caarlos0/machine to suit my needs.