Ansible - ghdrako/doc_snipets GitHub Wiki
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
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
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
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
- 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 --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 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 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.
$ 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
$ 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
$ ansible-playbook playbook.yaml
Ansible provides variables for turning Ansible playbooks into reusable templates. You can substitute variables in the right places using Jinja2 markup.
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.
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>
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