Ansible
Concepts and Terms
- Host: A remote server.
- Group: Several hosts group together.
- Inventory: A collection of all the hosts and groups Ansible manage.
- Modules: Unit of code that Ansible send to the remote nodes for execution.
- Tasks: Unit of action that combine a module, its arguments and parameters.
- Playbooks: An ordered list of tasks along with its necesary parameters that define a receipe to configure a system.
- Handlers: Special tasks that are triggered by other tasks, typically used for things like restarting a service.
- Roles: Group related tasks, variables, files, templates, and handlers into reusable units.
Setup test environment with DigitalOcean
- Use local machine as control node and DigitalOcean droplets as remote hosts.
- Refer DigitalOcean to provision droplets.
Command
Adhoc command
# Test connection to the ansible hosts
ansible all -i hosts -m ping
ansible app -i hosts -m ping
# Format
ansible target -i inventory -mmodule -a "module options"
# Run bash
ansible all -i hosts -a "uptime"
ansible server1 -i inventory -a "tail /var/log/nginx/error.log" --become
# Install and removing package
ansible all -i hosts -m apt -a "name=nginx" --become
ansible all -i hosts -m apt -a "name=nginx state=absent" --become
# Restart service
ansible webservers -i inventory -m service -a "name=nginx state=restarted" --become -K
# Copy file
ansible all -i hosts -m copy -a "src=./fileA dest=~/fileA"
# Gather info about host
ansible host1 -i hosts -m setup -a "filter=*ipv*"
Playbook command
# Executing playbook
ansible-playbook -i hosts playbook.yml -vvv
# Listing playbook task
ansible-playbook -i hosts playbook.yml --list-tasks
# List/Executing/Skipping by tags
ansible-playbook -i hosts playbook.yml --list-tags
ansible-playbook -i hosts playbook.yml --tags=setup
ansible-playbook -i hosts playbook.yml --exclude-tags=setup
# Starting executing at specific task
ansible-playbook -i hosts playbook.yml --start-at-task=Copy index page
# Limit targets
ansible-playbook -l dev -i hosts playbook.yml
Files
Sample hosts
file
[app]
host1 ansible_host=159.203.163.103 ansible_user=root ansible_port=22 ansible_ssh_private_key_file=/Users/khlim/.ssh/digital_ocean
[sample]
server1 ansible_host=203.0.113.111
server2 ansible_host=203.0.113.112
server3 ansible_host=203.0.113.113
[sample:vars]
ansible_user=sammy
ansible_port=22
ansible_ssh_private_key_file=/home/sammy/.ssh/custom_id
Sample playbook.yml
Playbook to install nginx and vim
---
- hosts: all
become: true
tasks:
- name: Install Packages
apt: name={{ item }} update_cache=yes state=latest
loop: [ 'nginx', 'vim' ]
tags: [ 'setup' ]
- name: Copy index page
copy:
src: index.html
dest: /var/www/html/index.html
owner: www-data
group: www-data
mode: '0644'
tags: [ 'update', 'sync' ]
Playbook to install docker
---
- hosts: all
become: true
vars:
container_count: 4
default_container_name: docker
default_container_image: ubuntu
default_container_command: sleep 1d
tasks:
- name: Install aptitude
apt:
name: aptitude
state: latest
update_cache: true
- name: Install required system packages
apt:
pkg:
- apt-transport-https
- ca-certificates
- curl
- software-properties-common
- python3-pip
- virtualenv
- python3-setuptools
state: latest
update_cache: true
- name: Add Docker GPG apt Key
apt_key:
url: https://download.docker.com/linux/ubuntu/gpg
state: present
- name: Add Docker Repository
apt_repository:
repo: deb https://download.docker.com/linux/ubuntu jammy stable
state: present
- name: Update apt and install docker-ce
apt:
name: docker-ce
state: latest
update_cache: true
- name: Install Docker Module for Python
pip:
name: docker
- name: Pull default Docker image
community.docker.docker_image:
name: "{{ default_container_image }}"
source: pull
- name: Create default containers
community.docker.docker_container:
name: "{{ default_container_name }}{{ item }}"
image: "{{ default_container_image }}"
command: "{{ default_container_command }}"
state: present
with_sequence: count={{ container_count }}
Playbook to initialize server
---
- hosts: all
become: true
vars:
created_username: sammy
tasks:
- name: Install aptitude
apt:
name: aptitude
state: latest
update_cache: true
- name: Setup passwordless sudo
lineinfile:
path: /etc/sudoers
state: present
regexp: '^%sudo'
line: '%sudo ALL=(ALL) NOPASSWD: ALL'
validate: '/usr/sbin/visudo -cf %s'
- name: Create a new regular user with sudo privileges
user:
name: "{{ created_username }}"
state: present
groups: sudo
append: true
create_home: true
- name: Set authorized key for remote user
ansible.posix.authorized_key:
user: "{{ created_username }}"
state: present
key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}"
- name: Disable password authentication for root
lineinfile:
path: /etc/ssh/sshd_config
state: present
regexp: '^#?PermitRootLogin'
line: 'PermitRootLogin prohibit-password'
- name: Update apt and install required system packages
apt:
pkg:
- curl
- vim
- git
- ufw
state: latest
update_cache: true
- name: UFW - Allow SSH connections
community.general.ufw:
rule: allow
name: OpenSSH
- name: UFW - Enable and deny by default
community.general.ufw:
state: enabled
default: deny
Roles
Tutorial 1: How to Use Ansible Roles to Abstract your Infrastructure Environment
Tutorial 2: Ansible Roles: Basics, Creating & Using
Example:
- hosts: all
become: true
roles:
- role: webserver
vars:
nginx_version: 1.17.10-0ubuntu1
tags: example_tag