Linux Automation with ansible - Part 1: Basics
I used to struggle with linux automation, fixing the same thing again and again. Coming back to old servers and not remembering how I had fixed something.
Same issue with deploying websites. It used to take like 20 commands changing permissions, making users, configuring services just to get some site running.
Not anymore.
Ansible - The last linux automation tool Iβll use.
Battle tested, used by millions, ansible is gold. Joy to configure, especially with ai. LLMs are great at making ansible scripts. Weβll do everything with ansible, adding users, editing config files, deploying websites, everything. 0 manual commands on the server. If we have to do something more, we improve the ansible script.
First Iβll show the anatomy of ansible, then how to install and use it, finally Iβll share my ansible scripts
What can Ansible do
Everything ! Setup a server from scratch - setup ssh, new users, permissions, deploy websites, install, and configure services. The same scripts can also be used on localhost!
Instead of manual commands, try to do everything with ansible. Do once, use again and again.
Anatomy of Ansible
hosts
file: has info about servers on which commands will be runplaybooks
: yml scripts. Have commands to runexecution
: Run a playbook on a specified host, with specified user -
ansible-playbook ./playbooks/zsh.yml -i ./inventory/hosts -l serverNameInHostsFile --user serverUserName
Thatβs it.
Install Ansible
- Local (debian) -
sudo apt install ansible
- Remote Server - Make sure python is installed
Thatβs it !
Setup Ansible
I suggest making a dedicated ansibleDir to keep all your playbooks, hosts and configuration files in one place. Here is my Ansible Dir on github: https://github.com/gyaaniguy/ansible-guide
ansiblDir
βββ inventory
β βββ hosts
βββ playbooks
β βββ caddy.yml
β βββ configs
β β βββ Caddyfile.j2
β β βββ upload_settings.ini
β βββ ssh
β βββ some-ssh-key.pub
βββ Readme.md
Running Ansible
# Test Command
ansible -i ./inventory/hosts servers -m ping --user root
# Regular command
ansible-playbook ./playbooks/zsh.yml -l serverNameInHostsFile -i ./inventory/hosts --user serverUserName
# ssh login pass -> This is required if ssh uses password to login
ansible-playbook ... --ask-pass
# Run in localhost
ansible-playbook ... -l local
# If playbook commands need elevated privileges on the server, give Ansible that password.
ansible-playbook ... --ask-become-pass
# Pass extra vars to the playbook
ansible-playbook ... --extra-vars "bare_repo=/home/user/repo.git"
# Verbose mode - Use when getting errors -> pass error to AI
ansible-playbook ... -vv
Hosts file
Straightforward
[serverNameInHostsFile]
servername.com
[local]
localhost ansible_connection=local
Playbooks
Playbooks are the scripts containing list of commands that ansible executes on your server. I wonβt go into too much detail, explaining its syntax. But here are some pointers -
- AI is really good at making, fixing and even adding more commands to the playbooks. Since ansible scripts are simple and has detailed logging in verbose mode
-vv
, AI is able to fix errors easily. - Ansible has a large selection of built in commands to handle everything -
- make user
- file operations
- package manager commands
- lots more..
- Custom variable are supported.
ansible-playbook --extra-vars="var=value"
. This makes ansible really powerful - create different users, deploy different websites etc. become: true
- run some task or whole script as sudo- See
handlers
- simple functions that can be run when called with the βnotifyβ command
Use my playbooks as a base, then use ai to imrpove upon them.
Example playbooks
- Simple:
apps.yml
Playbook to install packages. Performs 2 tasks. updates repo, then installs packages using apt-get.
- name: Install required packages
hosts: all
become: true
tasks:
- name: Update package cache
#become: true
apt:
update_cache: yes
upgrade: dist
- name: Install packages
#become: true
apt:
name:
- sudo
- zsh
- git
- curl
- unzip
- zip
- software-properties-common
- build-essential
- rsync
- htop
- neovim
state: present
install_recommends: no
- Complex:
user.yml
Add a User
I really like this one. Not only does it create a user, it does so with a custom password + configures the user - copies a ssh pub key and a zsh config file to the server.
Just one simple script and user creation has never been better !
- name: Create a login username
hosts: all
vars:
username: "{{ u | default('user') }}"
password: "{{ p | password_hash('sha512') }}"
tasks:
- name: Add a username
ansible.builtin.user:
name: "{{ username }}"
password: "{{ password }}"
groups:
- sudo
- www-data
state: present
shell: /bin/zsh
system: no
create_home: yes
home: "/home/{{ username }}"
- name: Add SSH key
ansible.builtin.authorized_key:
user: "{{ username }}"
state: present
key: "{{ lookup('file', './ssh/somepubkey.pub') }}"
- name: Copy .zshrc file
ansible.builtin.copy:
src: ./configs/.zshrc
dest: "/home/{{ username }}/.zshrc"
owner: "{{ username }}"
group: "{{ username }}"
mode: '0644'
Of course on localhost you will first need to create a ssh/public_key.pub key, which will be copied. Or you can remove the βAdd SSH keyβ task.
Execute above script:
ansible-playbook ./playbooks/user.yml \
--user root \
-i ./inventory/hosts \
-l serverName \
--extra-vars="u=aUsername p=aSentenceIsAGoodPasswordNotThisThough"
Next steps:
Explore my ansible setup. Iβll write an article on deploying laravel with ansible soon.