Ansible

From Logic Wiki
Jump to: navigation, search


Installation

Installation of the development machine

pip install ansible
brew install hudochenkov/sshpass/sshpass

Installation of ubuntu server

sudo apt update
sudo apt install ansible
sudo apt install sshpass

Running playbooks

To run all playbooks write this command in the ansible folder.

Be sure SSH Key based authentication is sorted before. See below.

ansible-playbook ./playbooks/all.yml  -i ./inventory/hosts

Folders and files

Hosts

Add / update servers to ./inventory/hosts file with either name or ip addresses

They can be grouped by tags like

[web_servers]
192.168.1.200
192.168.1.201
[database_servers]
192.168.1.204

They can be used as below in the playbook

 - hosts: web_servers

Test it by

ansible -i ./inventory/hosts servers -m ping --user logicmade --ask-pass

servers is the name of the group in hosts logicmade is the username

Setting variables next to server names

[web_servers]
192.168.1.200 apache_package=apache2 php_package=libapache-mod-php
192.168.1.201 apache_package=https php_package=php
[database_servers]
192.168.1.204

then we can use them in playbooks like

- hosts: all
  become: true
  tasks: 
  - name install apache and php
    package:
      name:
        - "{{ apache_package }}"
        - "{{ php_package }}"
      state : latest
      update_cache: yes

Playbooks

In a playbook yaml file become: true means it runs as sudo

To run a playbook :

ansible-playbook ./playbooks/apt.yml --user logicmade --ask-pass --ask-become-pass -i ./inventory/hosts

Ad-Hoc Commands

it starts with ansible and the command after -m flag

ansible all --key-file ~/.ssh/ansible -i inventory -m ping

Modules

Modules are pre-defined tasks in Ansible. Like apt, debug, git, file etc. see all module list for detail.

Conditions

"when" is used for conditions.

gather_facts

To get the facts for the nodes (or just one of them / 192.168.1.204 like below) we can run

ansible all -m gather_facts --limit 192.168.1.204 

Then we can use any of them like

when: ansible_distribution == "Ubuntu"

or combine them like

when: ansible_distribution == "Ubuntu" and ansible_distribution_version == "24.0"

Templates

Create "templates" folder in the root. When we use them in playbook templates are relative to playbook path.

Template files have the extension of .j2

Variables used in moustache format.

Example template for nginx site

site_name = {{ site_name}}
    server {
        listen 80;
        server_name {{ site_name}}.{{ site_type}}.bookitfor.me.uk;

        location / {
            proxy_pass http://localhost:{{ internal_port }};
            proxy_http_version 1.1;

            proxy_set_header Upgrade \$http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host \$host;

            proxy_set_header X-Real-IP \$remote_addr;
            proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto \$scheme;

            proxy_cache_bypass \$http_upgrade;
        }
    }

Using template in playbook and variables

variables can be defined in playbook before tasks like

- name : Site creation
  hosts: all
  become: true
  vars: 
    site_name: somesite
    site_type: api
    internal_port: 3001
  tasks:

or we can pass them from cli like

ansible-playbook playbook.yml -e "site_name=example.com site_type=api internal_port:3001"

Key base Authentication

Setting Up SSH Key-Based Authentication

Generate Key Pair: On the Ansible controller, run command below to create keys.

ssh-keygen -t rsa -f ~/.ssh/ansible-keys

Distribute Public Key

Copy the public key to managed nodes using

ssh-copy-id -i ~/.ssh/ansible-keys.pub user@node.

Configure Ansible Inventory

Specify the private key in your inventory file:

[servers]
node1 ansible_host=192.168.1.10 ansible_user=admin ansible_ssh_private_key_file=~/.ssh/ansible-keys

Fixing sudo issue

In the server run sudo visudo and add this line

logicmade ALL=(ALL) NOPASSWD: ALL

logicmade is the username to be escalated

To be safe, you can also create a dedicated file:

sudo visudo -f /etc/sudoers.d/logicmade

Now we can run a playbook like this

ansible-playbook ./playbooks/apt.yml  -i ./inventory/hosts

Add:

logicmade ALL=(ALL) NOPASSWD: ALL

Interactive prompts

- name: Example playbook with prompts
  hosts: all
  become: yes

  vars_prompt:
    - name: username
      prompt: "Enter the username"
      private: no

    - name: password
      prompt: "Enter the password"
      private: yes

  tasks:
    - name: Create a user
      user:
        name: "{{ username }}"
        password: "{{ password }}"

with defaults

vars_prompt:
  - name: domain_name
    prompt: "Enter domain"
    private: no
    default: "example.com"

Pass vairables via CLI

ansible-playbook playbook.yml -e "domain_name=example.com email=test@example.com"

Block, Rescue, Always

We can use them for error handling or logging

 tasks:
   - name: Attempt and graceful roll back demo
     block:
       - name: Print a message
         ansible.builtin.debug:
           msg: 'I execute normally'

       - name: Force a failure
         ansible.builtin.command: /bin/false

       - name: Never print this
         ansible.builtin.debug:
           msg: 'I never execute, due to the above task failing, :-('
     rescue:
       - name: Print when errors
         ansible.builtin.debug:
           msg: 'I caught an error'

       - name: Force a failure in middle of recovery! >:-)
         ansible.builtin.command: /bin/false

       - name: Never print this
         ansible.builtin.debug:
           msg: 'I also never execute :-('
     always:
       - name: Always do this
         ansible.builtin.debug:
           msg: "This always executes"

Tips

Vault

  • No blank lines
  • No special characters in password like (+)
  • In playbook it's relative to playbook's folder.

like :

/playbooks/test.yml
/aws_vault.yml

then

- name: Show AWS key from vault
  hosts: localhost
  gather_facts: false

  vars_files:
    - ../aws_vault.yml

  tasks:
    - name: Display the AWS Access Key ID
      debug:
        msg: "aws_access_key_id = {{ aws_access_key_id }}"

Create Vault

ansible-vault create  group_vars/all/vault.yml

Edit Vault

ansible-vault edit  group_vars/all/vault.yml

Verify Vault file

ansible all -i inventory/hosts -m debug -a "var=aws_access_key_id" --ask-vault-pass

aws_access_key_id is a key in the vault.

Vault Password File

Choose a location outside your repo, e.g.:

mkdir -p ~/.ansible
echo "MySuperSecretVaultPassword" > ~/.ansible/.vault_pass
chmod 600 ~/.ansible/.vault_pass

Create vault with password file

ansible-vault create playbooks/vault_aws.yml --vault-password-file ~/.ansible/.vault_pass

Run your playbook using the password file

ansible-playbook -i inventory/hosts playbooks/install_aws.yml \
 --vault-password-file ~/.ansible/.vault_pass