Skip to content

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