Ansible - ghdrako/doc_snipets GitHub Wiki

Install on Ubuntu distro - wsl2

wsl --help 
wsl --list -o 
wsl --install
sudo apt-add-repository ppa:ansible/ansible
sudo apt-get update
# sudo apt-get install ansible
sudo apt install python3-pip
sudo pip3 install pywinrm
sudo pip3 install pyvmomi
sudo pip3 install ansible
sudo pip3 install ansible[azure]
$ sudo apt update
$ sudo apt install software-properties-common -y
$ sudo apt-add-repository --yes --update ppa:ansible/ansible
$ sudo apt install ansible -y
$ ansible --version

Install RHEL8

1 #!/bin/bash 
2 sudo subscription-manager register 
3 sudo subscription-manager repos --enable ansible-2.9-for-\ 
4 rhel-8-x86_64-rpms 
5 sudo yum install ansible

Ansible virtual env

Connecting the Ansible control node with inventory servers

create an Ansible user called ansible and set up passwordless ssh to connect to the inventory servers from the Ansible control node.

Within your control node to create an ansible user, add the user to the sudoers list, and generate an ssh key pair for passwordless authentication:

$ sudo su - root
$ useradd -m ansible
$ echo 'ansible ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
$ sudo su – ansible
$ ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa  # Create the SSH key on the Ansible control node 
$ cat ~/.ssh/id_rsa.pub

$ ssh-copy-id ansible@web  # or add pk manulally to /etc/sudoers in managed machines
$ ssh-copy-id ansible@deb

$ $ ssh web hostname  # werify if passwordless connection establish

Within node servers:

$ ssh web
$ sudo su - root
$ useradd -m ansible
$ echo 'ansible ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
$ sudo su - ansible
$ ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa

Add the public key of our control node to the authorized_keys file of the ansible user. That will allow passwordless connectivity from the control node to the web server using the ansible user.

$ vim ~/.ssh/authorized_keys
$ sudo chmod 600 /home/ansible/.ssh/authorized_keys

And once we are done, we will exit from the prompts until we reach the control node. Once you are in the control node server, switch the user to ansible and try doing an ssh to the web server using the following commands:

$ sudo su - ansible
$ ssh web

Setting up an inventory file

The default location for inventory is a file called /etc/ansible/hosts. You can specify a different inventory file at the command line using the -i option.

$ sudo chown -R ansible:ansible /etc/ansible
# hosts
[frontends]
testserver ansible_host=192.168.1.13 ansible_port=22 myvar="This is inventory file."
[webservers]
web ansible_host=web
[dbservers]
db ansible_host=db
[all:vars]
ansible_python_interpreter=/usr/bin/python3

The [all:vars] section has a provision for variables that will apply to all groups. we're explicitly defining ansible_python_interpreter to python3 so that Ansible uses python3 instead of python2.

[all:vars]
ansible_connection=ssh
ansible_port=22
ansible_user=admin
ansible_pass=P@$$word123

Setting up the Ansible configuration file

  • By setting an environment variable, ANSIBLE_CONFIG, pointing to the Ansible configuration file
  • By creating an ansible.cfg file in the current directory
  • By creating an ansible.cfg file in the home directory of the current user
  • By creating an ansible.cfg file in the /etc/ansible directory. the first method overrides the next.

ansible.cfg file in the current directory:

[defaults]
inventory = ./hosts
host_key_checking = False
# list our inventory 
$ ansible-inventory --list -y
# show all hosts
$ ansible --list-hosts all
#  list all hosts that have the webservers role
$ ansible --list-hosts webservers
# check whether Ansible can connect to these servers 
$ ansible all -m ping

Ansible commandline

ansible --version

### Remote execution
ansible all -m ping
ansible -m ping -i hosts all
ansible <hostgroup> -a <command>
ansible all -a "ifconfig -a"

ansible -m copy -a 'src=hello.txt dest=/home/dev' -i hosts all
ansible testserver -i hosts -m ping
ansible testserver -i hosts -m command -a uptime
ansible testserver -i hosts -m command -a tail /var/log/syslog --e ansible_sudo_pass=xxxx
ansible testserver -i hosts -m setup
ansible testserver -i hosts -m setup -a filter=ansible_distribution*
ansible testserver -i hosts -m copy -a src=/etc/apt/sources.list dest=/tmp/sources.list
ansible testserver -i hosts -m file -a dest=/tmp/user1/new mode=777 owner=<owner> group=<group> state=directory
ansible testserver -i hosts -m file -a dest=/tmp/user1/new mode=777 state=absent
ansible testserver -i hosts -m apt -a name=nginx -b --e ansible_sudo_pass=xxxx
ansible testserver -i hosts -m apt -a name=nginx state=present -b --e ansible_sudo_pass=xxxx
ansible testserver -i hosts -m service -a name=nginx state=stop -b --e ansible_sudo_pass=xxxx
ansible testserver -i hosts -m service -a name=nginx state=stoped -b --e ansible_sudo_pass=xxxx

Ansible tasks and modules

Ansible tasks form the basic building block of running Ansible commands. Ansible tasks are structured in the following format:

$ ansible <options> <inventory>

Ansible modules are a reusable unit of code that does a particular thing very well, such as running a shell command, and creating and managing users. You can use Ansible modules with Ansible tasks to manage the configuration within the managed nodes.

 ansible -m shell -a "uname" all

we have provided the following flags:

  • -m: The name of the module (shell module here)
  • -a: The parameters to the module (uname in this case)

The command finally ends with where we want to run this task. Since we've specified all, it runs the task on all servers. We can pick and choose to run this on a single server, a set of servers, a role, or multiple roles, or use a wildcard to select the combination we want.

The tasks have three possible statuses – SUCCESS, CHANGED, and FAILURE.

  • SUCCESS status denotes that the task was successful, and Ansible took no action.
  • CHANGED status denotes that Ansible had to change the existing configuration to apply the expected configuration, and
  • FAILURE denotes an error while executing the task.

Ansible modules are reusable scripts that we can use to define configuration within servers. Each module targets a particular aspect of configuration management. Modules are used in both Ansible tasks and playbooks. There are a large number of modules available for consumption, and they are available at https://docs.ansible.com/ ansible/2.9/modules/modules_by_category.html.

Ansible playbook

Ansible playbooks are a collection of Ansible tasks to produce the desired configuration within target managed nodes.

Ansible playbooks consist of multiple plays, and each play is mapped to a group of hosts using a role and consists of a series of tasks required to achieve them.

Simple playbook that pings all servers

$cat  ping.yaml
---
  - hosts: all
    tasks:
      - name: Ping all servers
        action: ping

The YAML file contains a list of plays, as evident by the list directive. Each play consists of a hosts attribute that defines the role where we want to apply the play. The tasks section consist of a list of tasks, each with a name and action attributes. In the preceding example, we have a single play with a single task that pings all servers.

ansible-playbook --syntax-check <YAML>    # Syntax Check 
ansible-playbook <YAML> -C                # Test run
ansible-playbook <YAML> -C -D             # Dry run
ansible-playbook <YAML> -l <host>         # Run on single host
ansible-playbook <YAML> --verbose         # Verbose on successful tasks
ansible-playbook <YAML> -f 10             # Run 10 hosts parallel
ansible-playbook <YAML>                   # Run on all hosts defined

ansible-playbook <YAML> --list-hosts
ansible-playbook <YAML> --list-tasks

ansible-playbook -i hosts vars_playbook.yml -e "myvar='Command line var'"

There are three elements of play execution:

  • Gathering facts: This is where Ansible checks for all hosts that are part of the role, logs into each instance, and gathers information from each host that it uses while executing the tasks from the plays.
  • Run tasks: Then it runs the tasks of each play, as defined in the playbook.
  • Play recap: Ansible then provides a recap of the tasks it executed and the hosts it ran that on. This includes a list of all successful and failure responses.

Updating packages and repositories

$ apt-update.yaml
---
- hosts: webservers:dbservers       #  attribute defines a colon-separated list of roles/hosts inventory to apply to the playbook
  become: true                      # attribute specifies whether we want to execute the play as a root user 
                                    # Ansible will perform all play tasks with sudo privileges
    tasks:
      - name: Update apt packages
        apt: update_cache=yes cache_valid_time=3600

Installing application packages and services

$ cat install-webserver.yaml
---
- hosts: webservers
  become: true
    tasks:
      - name: Install packages
        apt:
          name:
            - apache2
            - php
            - libapache2-mod-php
            - php-mysql
            update_cache: yes
            cache_valid_time: 3600
            state: present
      - name: Start and Enable Apache service
        service: name=apache2 state=started enabled=yes
$ cat install-dbserver.yaml
- hosts: dbservers
  become: true
    tasks:
    - name: Install packages
      apt:
        name:
        - python-pymysql
        - mysql-server
        update_cache: yes
        cache_valid_time: 3600
        state: present
    - name: Start and enable MySQL service
      service:
        name: mysql
        state: started
        enabled: true
$ cat playbook.yaml
---
- import_playbook: apt-update.yaml
- import_playbook: install-webserver.yaml
- import_playbook: install-dbserver.yaml
- import_playbook: setup-webservers.yaml
- import_playbook: setup-dbservers.yaml

Executing the playbooks

$ ansible-playbook playbook.yaml

Designing for reusability

Ansible provides variables for turning Ansible playbooks into reusable templates. You can substitute variables in the right places using Jinja2 markup.

Ansible variables

There are multiple places where you can define your variables:

  • Within the Ansible playbook within the vars section
  • In your inventory
  • In reusable files or roles
  • Passing variables through the command line
  • Registering variables by assigning the return values of a task

You can define variables using a simple key-value pair within the YAML files and by following the standard YAML syntax. Variables can broadly be of three types:

  • simple variables,
  • list variables, and
  • dictionary variables.

Jinja2 templates

Ansible allows for templating files using dynamic Jinja2 templates. You can use the Python syntax within the file, starting with {{ and ending with }}. That will allow you to substitute variables during runtime and run complex computations on variables.

Example - supply the MySQL username and password dynamically during execution

$cat index.php
<html>
<head>
<title>PHP to MQSQL</title>
</head>
<body>
<?php
mysqli_connect('db', '{{ mysql_user }}', '{{ mysql_password
}}') or die('Could not connect the database : Username or
password incorrect');
echo 'Database Connected successfully';
?>
</body>
</html>

Debugging

List facts and state of a host

ansible <host> -m setup                            # All facts for one host
ansible <host> -m setup -a 'filter=ansible_eth*'   # Only ansible fact for one host
ansible all -m setup -a 'filter=facter_*'          # Only facter facts but for all hosts

Save facts to per-host files in /tmp/facts

ansible all -m setup --tree /tmp/facts
⚠️ **GitHub.com Fallback** ⚠️