- ansible cheat-sheet:
- things you should probably do when installing ansible:
- how to install ansible:
- Command(AD HOC) cheat-sheet:
- AD HOC vs playbook:
- Playbooks
- playbook examples in order of complexity
1- create a ssh key just for ansible to use, you can check this video for more info.
ssh-keygen -t ed25519 -C 'ansible default'
Remember to not put any passphrase for it. I would also recommend putting it into a different file (so that its only for ansible to use) as shown in the image above.
now you should copy the ssh key created to the said server:
ssh-copy-id -i ~/.ssh/ansible.pub 10.24.34.57
Basically be it any OS linux-based, or just WSL for windows, and you need some newer version of python installed.
for more info visit this ansible installation documentation page.
The managed node needs any newer version of python installed and also a user account that can SSH to the node with an interactive POSIX shell.
check that you have pip installed
python3 -m pip -V
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python3 get-pip.py --user
python3 -m pip install --user ansible
check whether it was correctly installed:
ansible --version
sudo apt-add-repository ppa:ansible/ansible
ping all machines:
#remember to always use command ssha before using ansible, since that will set the ssh-agent in work
#to ping all the servers
ansible all -m ping
#to ping all the server from the "virtualmachines" group according to the inventory config
ansible virtualmachines -m ping -i inventory.yaml
#Show Ansible inventory information, by default it uses the inventory script JSON format
ansible-inventory -i inventory.yaml --list
ansible all -a "df -h" -u root
ansible-inventory --list -y
ansible all --list-hosts
# run the gather_facts command on the destination server
ansible all -m gather_facts --limit <destination>
#check playbook syntax
ansible-playbook create_users.yml --syntax-check
use "when" and the variables from gather_facts command to conditionally specify which server you want your plays to run at:
ansible all -m gather_facts --limit <destination>
it should look something like this:
for example for the ansible_distribution variable:
and use it in a play like this:
general: like always (will run no matter what tag we targeted)
self-defined: like ubuntu in this next example
and to list all the tags from a playbook:
ansible-playbook --list-tags install_latest_tree_package.yaml
to run while targeting a specific tag :
ansible-playbook --tags ubuntu -K install_latest_tree_package.yaml
to run while targeting many tag :
ansible-playbook --tags "ubuntu,db" -K install_latest_tree_package.yaml
more on changing UFW rules and status here and its examples
above we have an example of installation of apache, as you will later see, this service will automatically start after the installation but in many Operating systems -for example CentOS- (and services other than apache) this may not occur, so we have to have an specific play for starting services, we may later also need to know how to stop, ... services.
version1:
just to install and start the httpd (apache for centos) after running the playbook
- in this setup after logging to the centos server we can see that httpd is running however since its disabled, after a reboot, we will again need to run this playbook to again start the service. to fix this, the version 2 of this playbook did the next:
and this is a very simple thing to fix, we just need to add one line:
and after running the playbook with this new line, the service should look likes this:
for example we change this line from the "/etc/httpd/conf/httpd.conf" file and after it we should restart the httpd (apache for centos) package, so the change is applied:
we need to know exactly what line we will be changing:
Be very carefull when using the lineinfile module because this change may happen everytime that the playbook runs, because the playbooks doesn't know that you have already ran this, for example:
you may want to add "Aa12345" after the word "hi" the line 5, what happens is Aa12345 will be added the amount of times you run this playbook,
cause the playbook cant know that has already be ran before and you will end up with something like this:
hi Aa12345Aa12345Aa12345Aa12345
but this will not happen for most of the other plays, for example installation ... , since something has already been installed, the play wont change a thing.
before and after running this playbook:
see a list of users with this command: cat /etc/passwd
as of right now the latest added users are:
run the playbook to add users :
and this should be the output of cat /etc/passwd
after running the playbook:
to test it:
and should be known as simone and be able to use sudo:
Roles allow us to better split up our tasks.
you should define the roles in the playbook.yml and then create a "roles" folder in the same path as the playbook, inside of the roles folder there should be folder for each of the roles defined in the playbook, named with their respective role_names.
each role_folder should have a tasks folder inside:
and inside the tasks directory corresponding to each role there should be a main.yml that is called a taskbook instead of a playbook, because it should start with tasks instead of host specifications and ...
- remember if you are coping files and you need the "files" directory you should also copy the files directory into the said role_folder
to create varibles for each of our hosts, we can create a hosts_vars directory and create files named after the host(ip, dns or domain name of the hosts -> basically whatever you are calling it in the inventory file with .yml file-extension)
we did this with the webservers:
do you remember when we did this:
we used variable named apache to register when a changed happened in the state, but as mentioned before this is not very clever, because you can possibly only use that variable in one time:
- you could handle this scenario:
- when task A is done -> do task B
- A -> B
- when task A is done -> do task B
- but you couldn't easy handle this scenario:
- when task A is done -> do task B and when B is done -> do task C
- to do this you would have to use 2 variables:
- A -> B
- B -> C
- to do this you would have to use 2 variables:
- when task A is done -> do task B and when B is done -> do task C
but there is an easier way to handle this scenario without using variables:
we will completely remove the restart task and the variables like this:
we will now create a folder in the said directory where this taskbook existed and call it handlers, with a main.yml file inside of it and inside of it the task that should run with the name of the notification should exists:
and the main taskbook should look like this:
the ssh agent has some configuration. the path to this config file(/etc/ssh/sshd_config) is the same across different distributions of linux however the contents may vary. Sometimes you want this config to be the same across the different servers that are under your management, for this, you can use templates:
we will create a copy of this file and save it with the same name (sshd_config) but with a j2 file extension(jinja2)
first we check that AllowUsers doesn't already exist in the file:
and then we add it to the sshd_config_ubuntu.j2 and sshd_config_centos.j2 file:
and now will set the value of this variable:
we will now add it to our host vars for each of the servers
and now add a base task(for every server) to add this file to their respective ssh config path file:
and since this notified a handler we should create one for it:
after running this, the /etc/ssh/sshd_config file for each server should have an extra line (which is the AllowUsers one)
- install_latest_tree_package.yaml
- install_zip.yml
- uninstall_tree_package.yaml
- print_arr.yml
- install_php_and_apache_on_ubuntu_and_centos.yml
- copy-files-to-server.yml
- install-terraform.yml
- change_httpd_config_and_restart.yml
- create_users.yml
- start_httpd_centos.yml
- roles playbook is inside the role-example folder