===== initiation ansible =====
===== references =====
* https://xavki.blog/youtube-ma-chaine/
* https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-ansible-on-ubuntu-20-04-fr
* https://docs.ansible.com/ansible/latest/index.html
* https://www.redhat.com/fr/topics/automation/learning-ansible-tutorial
===== installation et environement =====
==== install ====
via package APT
root@disi-dellat:~# apt update
root@disi-dellat:~# apt install ansible
Les paquets suivants ont été installés automatiquement et ne sont plus nécessaires :
libfwupdplugin1 libsysmetrics1
Veuillez utiliser « apt autoremove » pour les supprimer.
Les paquets supplémentaires suivants seront installés :
ieee-data python3-argcomplete python3-dnspython python3-jmespath python3-kerberos python3-libcloud
python3-netaddr python3-ntlm-auth python3-requests-kerberos python3-requests-ntlm python3-selinux
python3-winrm
Paquets suggérés :
cowsay sshpass ipython3 python-netaddr-docs
Les NOUVEAUX paquets suivants seront installés :
ansible ieee-data python3-argcomplete python3-dnspython python3-jmespath python3-kerberos python3-libcloud
python3-netaddr python3-ntlm-auth python3-requests-kerberos python3-requests-ntlm python3-selinux
python3-winrm
0 mis à jour, 13 nouvellement installés, 0 à enlever et 3 non mis à jour.
Il est nécessaire de prendre 9 379 ko dans les archives.
Après cette opération, 88,6 Mo d'espace disque supplémentaires seront utilisés.
Souhaitez-vous continuer ? [O/n] O
...
Paramétrage de python3-netaddr (0.7.19-3ubuntu1) ...
Paramétrage de python3-winrm (0.3.0-2) ...
Paramétrage de ansible (2.9.6+dfsg-1) ...
==== user ansible ====
nous allons travailler avec un user nommé ans qui sera utiliser pour notre gestion ansible
sur le server-node on créé ce user avec un uid specifique ici 1033
root@disi-dellat:~# adduser ans --uid 1033
$ su - ans
Mot de passe :
ans@disi-dellat:~$
ans@disi-dellat:~$ ansible --version
ansible 2.9.6
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/ans/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3/dist-packages/ansible
executable location = /usr/bin/ansible
python version = 3.8.10 (default, Mar 15 2022, 12:22:08) [GCC 9.4.0]
apres l'avoir créé sur notre noeud serveur , on créé aussi sur notre client exemple :
root@PrecisT36:~# adduser ans --uid=1033
Adding user `ans' ...
Adding new group `ans' (1033) ...
Adding new user `ans' (1033) with group `ans' ...
Creating home directory `/home/ans' ...
Copying files from `/etc/skel' ...
New password:
==== ssh keyGen ====
generation d'une clé SSH pour l'utilisateur ans avec nom specifique id_rsa_ansible_sn (ansible-server-node) et passphrass assoviée
ans@disi-dellat:~$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ans/.ssh/id_rsa): /home/ans/.ssh/id_rsa_ansible_sn
Created directory '/home/ans/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/ans/.ssh/id_rsa_ansible_sn
Your public key has been saved in /home/ans/.ssh/id_rsa_ansible_sn.pub
The key fingerprint is:
SHA256:Jlw3secret9oGC1dIQ ans@disi-dellat
The key's randomart image is:
+---[RSA 3072]----+
| o.. *|
| ... |
+----[SHA256]-----+
==== ssh-key copy ====
on recopie notre clée public ssh vers le noeud client (nodept3)
ans@disi-dellat:~$ ssh-copy-id ans@nodept3
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/ans/.ssh/id_rsa_ansible_sn.pub"
The authenticity of host 'nodept3 (192.168.1.68)' can't be established.
ECDSA key fingerprint is SHA256:vsbLgBSECRETy5I684I.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
ans@nodept3's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'ans@nodept3'"
==== SSH config ====
generation d'un fichier .ssh/config afin de specifier quelle clé/ID utiliser vers quel node
ans@disi-dellat:~$ cat .ssh/config
host nodept3
HostName nodept3
IdentityFile ~/.ssh/id_rsa_ansible_sn
User ans
==== ssh vers node client ====
maintenant le ssh vers ce noeud client se fait sans password, mais avec passPhrase toutefois :
ans@disi-dellat:~$ ssh 'ans@nodept3'
Enter passphrase for key '/home/ans/.ssh/id_rsa_ansible_sn': upAnSibleSSHdo
ans@PrecisT36:~$
==== ssh-agent ====
on va lancer un agent ssh pour stocker l'association passPhrase-clé afin d'eviter de saisir la passPhrse a chaque lancement
ans@disi-dellat:~$ eval `ssh-agent`
Agent pid 296069
ans@disi-dellat:~$ ssh-add -l
The agent has no identities.
ans@disi-dellat:~$ ssh-add ~/.ssh/id_rsa_ansible_sn
ans@disi-dellat:~$ ssh-add -l
3072 SHA256:Jlw3+M8dcv1SECRETC1dIQ ans@disi-dellat(RSA)
demonstration de ssh entre notre node-server et le client (nodept3 = PrecisT36)
ans@disi-dellat:~$ ssh nodept3
ans@PrecisT36:~$
==== convert openssh key to pem ====
si par megarde on rencontre un soucis d'usage d'openssl sur la clé ssh (retrait de la passphrase par exemple) , il est alors utile de forcer une format RSA/PEM sur notre clé initialement au format OPENSSH
ans@disi-dellat:~$ file ~/.ssh/id_rsa_ansible_sn
/home/ans/.ssh/id_rsa_ansible_sn: OpenSSH private key
ans@disi-dellat:~$ ssh-keygen -p -f ~/.ssh/id_rsa_ansible_sn -m pem
Enter old passphrase:
Key has comment 'ans@disi-dellat'
Enter new passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved with the new passphrase.
ans@disi-dellat:~$ file ~/.ssh/id_rsa_ansible_sn
/home/ans/.ssh/id_rsa_ansible_sn: PEM RSA private key
on peux pour backup retirer la passphrase (et stocker cette clé privée non protégée ailleurs)
ans@disi-dellat:~$ cp ~/.ssh/id_rsa_ansible_sn ~/.ssh/id_rsa_ansible_sn-cpp
ans@disi-dellat:~$ openssl rsa -in ~/.ssh/id_rsa_ansible_sn-cpp -out ~/.ssh/id_rsa_ansible_sn-cpp-nop
Enter pass phrase for /home/ans/.ssh/id_rsa_ansible_sn-cpp:
writing RSA key
===== ansible test =====
premier test ansible depuis le node-server vers le client avec un simple "ping/pong"
ans@disi-dellat:~$ ansible -i "nodept3," all -m ping
nodept3 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
on demande a faire du ansible avec un inventaire contenant que "nodept3" avec le group all et le module ping
===== ansible.cfg =====
le fichier de configuration d'ansible peut etre à plusieurs endroit avec une precedence de preference d'acces qui suis cet ordre
- ANSIBLE_CONFIG : variable d'env qui contient la location du fichier
- fichier ansible.cfg dans le repertoire du repertoire du playbook en cours
- ~/.ansible/ansible.cfg
- /etc/ansible/ansible.cfg
les differentes sections de parametrage par defaut
ans@disi-dellat:~$ grep "^\[" /etc/ansible/ansible.cfg
[defaults]
[inventory]
[privilege_escalation]
[paramiko_connection]
[ssh_connection]
[persistent_connection]
[accelerate]
[selinux]
[colors]
[diff]
===== ansible-config =====
la commande //ansible-config// dispose des parametres //view// et //list// pour voir repectivement les valeurs postionnées dans le ansible.cfg utilisé et la list de tous les parametres que l'on va pouvoir positionner
* view
ans@disi-dellat:~$ ansible-config view
# config file for ansible -- https://ansible.com/
# ===============================================
# nearly all parameters can be overridden in ansible-playbook
# or with command line flags. ansible will read ANSIBLE_CONFIG,
# ansible.cfg in the current working directory, .ansible.cfg in
# the home directory or /etc/ansible/ansible.cfg, whichever it
# finds first
[defaults]
# some basic default values...
#inventory = /etc/ansible/hosts
#library = /usr/share/my_modules/
#module_utils = /usr/share/my_module_utils/
#remote_tmp = ~/.ansible/tmp
#local_tmp = ~/.ansible/tmp
#plugin_filters_cfg = /etc/ansible/plugin_filters.yml
#forks = 5
#poll_interval = 15
#sudo_user = root
#ask_sudo_pass = True
#ask_pass = True
#transport = smart
#remote_port = 22
#module_lang = C
#module_set_locale = False
...
* List
ans@disi-dellat:~$ ansible-config list
ACTION_WARNINGS:
default: true
description:
- By default Ansible will issue a warning when received from a task action (module
or action plugin)
- These warnings can be silenced by adjusting this setting to False.
env:
- name: ANSIBLE_ACTION_WARNINGS
ini:
- key: action_warnings
section: defaults
name: Toggle action warnings
type: boolean
version_added: '2.5'
AGNOSTIC_BECOME_PROMPT:
default: true
description: Display an agnostic become prompt instead of displaying a prompt containing
the command line supplied become method
env:
- name: ANSIBLE_AGNOSTIC_BECOME_PROMPT
ini:
- key: agnostic_become_prompt
- ...
===== ansible config pipelining =====
sans pipelining
- creation fichier python
- creation directory
- envoie du fichier python via sftp
- run python distant
- recuperation stdout
avec pipelining
- creation fichier python
- envoie du contenu sur node distant dans l'interpreteur python via stdin
- recuperation stdout
ans@disi-dellat:~/ansible$ vim ansible.cfg
#pipelining = False
pipelining = True
===== ssh_connection persist =====
ans@disi-dellat:~/ansible$ vim ansible.cfg
[ssh_connection]
# ssh arguments to use
# Leaving off ControlPersist will result in poor performance, so use
# paramiko on older platforms rather than removing it, -C controls compression use
#ssh_args = -C -o ControlMaster=auto -o ControlPersist=60s
ssh_args = -C -o ControlMaster=auto -o ControlPersist=60s -o PreferredAuthentications=publickey
partager plusieurs sessions pour une meme connexion, faire persister la connexion 60s et preciser directement qu'on va faire de l'auth par publickey plutot que d'essayer toutes les methodes .
==== ansible fork ====
parallelisme de gestion de nodes, par exemple faire 10 clients à la fois
ans@disi-dellat:~/ansible$ vim ansible.cfg
[defaults]
forks = 10
===== ansible gather_facts =====
a chaque session, le server node va recuperer des info pour positionner les variables propres au client, son nom, son OS, ses @IP, interfaces reseau etc ...
ans@disi-dellat:~/ansible$ vim ansible.cfg
[defaults]
# smart - gather by default, but don't regather if already gathered
# implicit - gather by default, turn off with gather_facts: False
# explicit - do not gather by default, must say gather_facts: True
#gathering = implicit
gathering = implicit
autres optimations pour grosse structures => mitogen : https://mitogen.networkgenomics.com/ansible_detailed.html
voire faire du pull avec des clients ansible sur localhost qui vont chercher sur une depot git la config et la runner vian //ansible-pull// un a un quand bon leur semble
===== ansible CLI =====
la commande //ansible// en CLI est plutot utilisée pour des tests, petite taches, deblocage de situation etc ... en prod on va plutot jouer des playbook yaml avec //ansible-playbook// .
* -u on s'execute an distant avec tel user
* -b passer les commande en élévation de privileges (sudo)
* -k demander les password de la connexion ssh (si pas de partage de clé, oneshot ...)
* -K pour le pass de l'elevation de privilege
* -C ou --check ; dry run
* -D ou --diff ; fait un diff d'avant / apres actions, donc -C -D permet de simuler et voir sans toucher
* --ask-vault-pass ; dechiffrer un fichier vault
* --fault-password-file ; fichier pour dechiffrer
* --one-line ; stdout sur une seule ligne
* -m command -a la_commande ; lancer la commane -a a distance
exemple de lancement en mode ultra verbose avec le user distant jehan, utilisation d'un ssh-python (-c paramiko (cf paramiko.org) ) car autrement on reçois un //FAILED! => "to use the 'ssh' connection type with passwords, you must install the sshpass program"// et demande de prompt du password via -k pour appel final du module ping :
ans@disi-dellat:~/ansible$ ansible -vvv -i "nodept3," all -u jehan -c paramiko -k -m ping
exemple de lancement de commande
ans@disi-dellat:~/ansible$ ansible -i "nodept3," all -m command -a uptime --one-line
nodept3 | CHANGED | rc=0 | (stdout) 22:30:08 up 5:32, 1 user, load average: 0,01, 0,04, 0,08
exemple de lancement de commande via un shell qui permet des commandes plus complexe integrant des pipe
ans@disi-dellat:~/ansible$ ansible -i "nodept3," all -c paramiko -m shell -a "ps -auwx | grep jehan | wc -l" -u jehan -k -K
SSH password:
BECOME password[defaults to SSH password]:
nodept3 | CHANGED | rc=0 >>
105
===== ansible raw =====
utiliser ansible en distant sans utiliser python, par exemple pour une machine qui ne l'a pas encore on pourra faire un install python ! on utilise alors le module raw avec l'elevation de privilege + demande pass privilege (-K) :
ans@disi-dellat:~/ansible$ ansible -i "nodept3," all -b -K -m raw -a "apt install -y python3"
===== ansible module apt =====
plutot que d'utiliser le module// raw// puis //apt install// , il sera preferable d'utiliser le module //apt// et ses multiples options : https://docs.ansible.com/ansible/latest/collections/ansible/builtin/apt_module.html
ans@disi-dellat:~/ansible$ ansible -vv -i "nodept3," all -b -K -m apt -a "name=wireshark state=latest"
===== ansible module service =====
positionner l'etat d'un service via le module //service//
ans@disi-dellat:~/ansible$ ansible -i "nodept3," all -b -K -m service -a "name=apache2 state=stopped"
===== ansible copy =====
simple copy de fichier
ans@disi-dellat:~/ansible$ vim filetest.txt
ans@disi-dellat:~/ansible$ ansible -i "nodept3," all -b -K -m copy -a "src=filetest.txt dest=/tmp/filetest-ans.txt"
BECOME password:
nodept3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"checksum": "df800445bb74b4abb144b3f9bf03f90aa9618f4c",
"dest": "/tmp/filetest-ans.txt",
"gid": 0,
"group": "root",
"md5sum": "f61d358bbdd6a9bd2e93322023a4e29d",
"mode": "0644",
"owner": "root",
"size": 14,
"src": "/home/ans/.ansible/tmp/ansible-tmp-1660512072.1366317-239729049960172/source",
"state": "file",
"uid": 0
}
===== ansible fetch =====
recuperer un fichier depuis l'hote distant avec option d'ecrassement si existant localement (flat=yes)
ans@disi-dellat:~/ansible$ ansible -i "nodept3," all -b -K -m fetch -a "src=/tmp/filetest-ans.txt dest=/tmp/filetest-ans-fetch.txt flat=yes"
BECOME password:
nodept3 | CHANGED => {
"changed": true,
"checksum": "b0265654b260f04c119005b7a293389cdf566856",
"dest": "/tmp/filetest-ans-fetch.txt",
"md5sum": "dbd6c447a5077dc690557df11f9ada60",
"remote_checksum": "b0265654b260f04c119005b7a293389cdf566856",
"remote_md5sum": null
}
ans@disi-dellat:~/ansible$ cat /tmp/filetest-ans-fetch.txt
hello ansible
welcome back
===== ansible gather facts =====
recuperer tous les gather facts (informations sur l'hote distant)
ans@disi-dellat:~/ansible$ ansible -i "nodept3," all -m setup
nodept3 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.1.8"
],
"ansible_all_ipv6_addresses": [
...
"ansible_os_family": "Debian",
"ansible_pkg_mgr": "apt",
...
filtrer sur la distribution
ans@disi-dellat:~/ansible$ ansible -i "nodept3," all -m setup -a "filter=ansible_distribution"
nodept3 | SUCCESS => {
"ansible_facts": {
"ansible_distribution": "Ubuntu",
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false
}
===== ansible inventory ======
recensement de la liste des machines et variables attenantes avec les repartoires //hosts_vars// et //group_vars// . Son organisation est importante, on va pouvoir y "typer" (ranger par role, web, db etc ) la liste des nodes a gerer . Deux types d'object
* host
* group
l'inventory peut-etre en type ini (plat) ou yaml (structure en arbre), il peut-etre aussi en format json pour beneficier d'outils de gestion automatique.
on peut utiliser des patterns .
==== arboresence et group ====
le groupe //all// est parent de tous
exemple de definition de group contenant des hosts (format ini) :
=== format ini ===
[parent1]
srv1
[enfant1]
srv2
srv3
[enfant2]
srv4
[enfant3]
srv5
puis definition d'une hierarchie
[parent1:children]
enfant1
enfant2
[enfant2:children]
enfant3
=== format yaml ===
all:
children:
parent1:
hosts:
srv1:
children:
enfant1:
hosts:
srv2:
srv3:
enfant2:
hosts:
srv4:
children:
enfant3:
hosts:
srv5:
=== group in group ===
on peut imbriquer des groupes dans un groupe, ici parent2 au meme niveau que parent1
all:
children:
parent1:
parent2:
hosts:
srv1:
parent2:
hosts:
srv6:
srv7:
=== pattern ===
exemple au lieu de mettre //srv6:// et //srv7:// on met// srv[6:7]://
===== ansible editors =====
references
* https://docs.ansible.com/ansible/latest/community/other_tools_and_programs.html#popular-editors
* https://code.visualstudio.com/docs/setup/linux
===== ansible variables =====
* https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html
variables d'inventaires
partons sur cet exemple d'inventaire yml :
all:
children:
common:
children:
webserver:
hosts:
node[2:3]:
vars:
var1: "webserver"
dbserver:
hosts:
node4:
node5:
var1: "node5"
vars:
var1: "dbserver"
monitoring:
children:
webserver:
dbserver:
utilisation du module debug pour afficher une variable positionnée en ligne de commande
ans@disi-dellat:~/ansible$ ansible -i "nodept3," all -e "var1=helloA" -m debug -a 'msg={{ var1 }}'
nodept3 | SUCCESS => {
"msg": "helloA"
}
utilisation de notre 00_inventory.yml
ans@disi-dellat:~/ansible$ ansible -i 00_inventory.yml all -m debug -a 'msg={{ var1 }}'
[WARNING]: Skipping unexpected key (monitoring) in group (common), only "vars", "children" and "hosts" are valid
node2 | SUCCESS => {
"msg": "webserver"
}
node4 | SUCCESS => {
"msg": "dbserver"
}
node3 | SUCCESS => {
"msg": "webserver"
}
node5 | SUCCESS => {
"msg": "node5"
}
on voit que //var1// est bien surchargée pour node5 dans le group dbserver
===== ansible variable directory =====
il est preferable d'un point de vue organisation de créer une arborescence dans le filesystem pour tenir compte de la hierarchie des variable plutot que de tout mettre dans l'inventaire .
ans@disi-dellat:~/ansible$ mkdir group_vars
ans@disi-dellat:~/ansible$ vim group_vars/webserver.yml
ans@disi-dellat:~/ansible$ cat group_vars/webserver.yml
var1: "gp_webserver"
ans@disi-dellat:~/ansible$ cp group_vars/webserver.yml group_vars/dbserver.yml
ans@disi-dellat:~/ansible$ vim group_vars/dbserver.yml
ans@disi-dellat:~/ansible$ cat group_vars/dbserver.yml
var1: "gp_dbserver"
on a donc cette arborescence
ans@disi-dellat:~/ansible$ tree
.
├── 00_inventory.yml
├── 01_inventory.yml
├── ansible.cfg
├── filetest.txt
├── group_vars
│ ├── dbserver.yml
│ └── webserver.yml
└── inventory.yml
1 directory, 7 files
on adapte notre inventory en retirant les vars de group maintenant definis dans l'arborescence de FS
ans@disi-dellat:~/ansible$ cat 01_inventory.yml
all:
children:
common:
children:
webserver:
hosts:
node[2:3]:
dbserver:
hosts:
node4:
node5:
var1: "node5"
on relance le test des vars, il donne le meme resultat
ans@disi-dellat:~/ansible$ ansible -i 01_inventory.yml all -m debug -a 'msg={{ var1 }}'
node4 | SUCCESS => {
"msg": "gp_dbserver"
}
node5 | SUCCESS => {
"msg": "node5"
}
node2 | SUCCESS => {
"msg": "gp_webserver"
}
node3 | SUCCESS => {
"msg": "gp_webserver"
}
on peut ranger encore plus finement et en anticipant l'usage de fichiers "vaulter" comme ceci
ans@disi-dellat:~/ansible$ mkdir group_vars/webserver
ans@disi-dellat:~/ansible$ mv group_vars/webserver.yml group_vars/webserver/variables.yml
ans@disi-dellat:~/ansible$ touch group_vars/webserver/vault.yml
ans@disi-dellat:~/ansible$ mkdir group_vars/dbserver
ans@disi-dellat:~/ansible$ mv group_vars/dbserver.yml group_vars/dbserver/variables.yml
ans@disi-dellat:~/ansible$ tree
.
├── 00_inventory.yml
├── 01_inventory.yml
├── ansible.cfg
├── filetest.txt
├── group_vars
│ ├── dbserver
│ │ └── variables.yml
│ └── webserver
│ ├── variables.yml
│ └── vault.yml
└── inventory.yml
3 directories, 8 files
on peut aussi extraire la variable de host (node5) de l'inventaire pour en faire une gestion par l'arborescence
ans@disi-dellat:~/ansible$ mkdir -p host_vars/node5
ans@disi-dellat:~/ansible$ vim host_vars/node5/variables.yml
ans@disi-dellat:~/ansible$ cat host_vars/node5/variables.yml
var1: "node5"
ans@disi-dellat:~/ansible$ vim 01_inventory.yml
ans@disi-dellat:~/ansible$
ans@disi-dellat:~/ansible$ ansible -i 01_inventory.yml all -m debug -a 'msg={{ var1 }}'
node3 | SUCCESS => {
"msg": "gp_webserver"
}
node2 | SUCCESS => {
"msg": "gp_webserver"
}
node5 | SUCCESS => {
"msg": "node5"
}
node4 | SUCCESS => {
"msg": "gp_dbserver"
}
=== utilisation de all ===
on créé une variable pour all pour l'exemple
ans@disi-dellat:~/ansible$ mkdir group_vars/all
ans@disi-dellat:~/ansible$ vim group_vars/all/variables.yml
ans@disi-dellat:~/ansible$ cat group_vars/all/variables.yml
var1: "all"
ans@disi-dellat:~/ansible$ tail -4 01_inventory.yml
node5:
outcommon:
hosts:
node6:
ans@disi-dellat:~/ansible$
ans@disi-dellat:~/ansible$ ansible -i 01_inventory.yml all -m debug -a 'msg={{ var1 }}'
node6 | SUCCESS => {
"msg": "all"
}
node2 | SUCCESS => {
"msg": "gp_webserver"
}
node3 | SUCCESS => {
"msg": "gp_webserver"
}
node4 | SUCCESS => {
"msg": "gp_dbserver"
}
node5 | SUCCESS => {
"msg": "node5"
}
==== ansible-inventory list ====
afficher en txt l'arborescence de l'invetory, hosts, groups, vars
ans@disi-dellat:~/ansible$ ansible-inventory -i 01_inventory.yml --list
{
"_meta": {
"hostvars": {
"node2": {
"var1": "gp_webserver"
},
"node3": {
"var1": "gp_webserver"
},
"node4": {
"var1": "gp_dbserver"
},
"node5": {
"var1": "node5"
},
"node6": {
"var1": "all"
}
}
},
"all": {
"children": [
"common",
"outcommon",
"ungrouped"
]
},
"common": {
"children": [
"dbserver",
"webserver"
]
},
"dbserver": {
"hosts": [
"node4",
"node5"
]
},
"outcommon": {
"hosts": [
"node6"
]
},
"webserver": {
"hosts": [
"node2",
"node3"
]
}
}
ou plus lisible
ans@disi-dellat:~/ansible$ ansible-inventory -i 01_inventory.yml --graph --vars
@all:
|--@common:
| |--@dbserver:
| | |--node4
| | | |--{var1 = gp_dbserver}
| | |--node5
| | | |--{var1 = node5}
| | |--{var1 = gp_dbserver}
| |--@webserver:
| | |--node2
| | | |--{var1 = gp_webserver}
| | |--node3
| | | |--{var1 = gp_webserver}
| | |--{var1 = gp_webserver}
|--@outcommon:
| |--node6
| | |--{var1 = all}
|--@ungrouped:
|--{var1 = all}
=== graphic ====
enfin une vrai version graphique de l'inventaire en installant au prealable le necessaire :
root@disi-dellat:~# apt install python3-pip
root@disi-dellat:~# pip3 install ansible-inventory-grapher
root@disi-dellat:~# apt install graphviz graphicsmagick-imagemagick-compat
on peut lancer la serie de commandes
ans@disi-dellat:~/ansible$ ansible-inventory-grapher -i 01_inventory.yml all | dot -Tpng | display png:-
{{:docpublic:systemes:ansible-inventory-grapher-01.png?400|}}
===== ansible playbook =====
un fichier qui declanche les actions (tasks) , articuler l'inventory et les roles (ensemble de taches/variables) . Il peut aussi disposer lui meme d'actions mais a eviter .
la syntaxe YAML des playbook et primordiale
* https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html#playbook-syntax
* https://blog.stephane-robert.info/post/ecriture-de-playbooks-ansible/
=== premier playbook ===
ans@disi-dellat:~/ansible$ cat 0_playbook.yml
---
- name: Home_Playbook
hosts: all
remote_user: ans
tasks:
- name: j_debug
debug:
msg: "my var1 {{ var1 }}"
=== execution ===
il y a des erreurs sur les nodes non UP/existant (car appel de hosts: all !) , c'est normal ici .
ans@disi-dellat:~/ansible$ ansible-playbook -i 00_inventory.yml 0_playbook.yml
[WARNING]: Skipping unexpected key (monitoring) in group (common), only "vars", "children" and "hosts" are valid
PLAY [Home_Playbook] ********************************************************************************************
TASK [Gathering Facts] ******************************************************************************************
Thursday 18 August 2022 19:19:47 +0200 (0:00:00.016) 0:00:00.016 *******
[WARNING]: Unhandled error in Python interpreter discovery for host node4: Failed to connect to the host via
ssh: ssh: Could not resolve hostname node4: Temporary failure in name resolution
ok: [node3]
TASK [j_debug] **************************************************************************************************
Thursday 18 August 2022 19:19:48 +0200 (0:00:00.867) 0:00:00.884 *******
ok: [node3] => {
"msg": "my var1 gp_webserver"
}
PLAY RECAP ******************************************************************************************************
node2 : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0
node3 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node4 : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0
node5 : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0
Thursday 18 August 2022 19:19:48 +0200 (0:00:00.038) 0:00:00.922 *******
===============================================================================
Gathering Facts ------------------------------------------------------------------------------------------ 0.87s
j_debug -------------------------------------------------------------------------------------------------- 0
===== ansible module file =====
* https://docs.ansible.com/ansible/latest/collections/ansible/builtin/file_module.html
gestion de fichiers et repertoires
==== 1er playbook cnx ====
simple check de connexion avec ping
=== playbook ===
ans@disi-dellat:~/ansible$ cat 02_playbook_file.yml
---
- name: J_Playbook_File
hosts: node3
tasks:
- name: check_cnx
ping:
=== lancement cli ===
ans@disi-dellat:~/ansible$ ansible-playbook -i 01_inventory.yml -u ans 02_playbook_file.yml
PLAY [J_Playbook_File] ******************************************************************************************
TASK [Gathering Facts] ******************************************************************************************
Friday 19 August 2022 10:26:58 +0200 (0:00:00.016) 0:00:00.016 *********
ok: [node3]
TASK [check_cnx] ************************************************************************************************
Friday 19 August 2022 10:26:59 +0200 (0:00:00.850) 0:00:00.867 *********
ok: [node3]
PLAY RECAP ******************************************************************************************************
node3 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Friday 19 August 2022 10:26:59 +0200 (0:00:00.229) 0:00:01.096 *********
===============================================================================
Gathering Facts ------------------------------------------------------------------------------------------ 0.85s
check_cnx ------------------------------------------------------------------------------------------------ 0
==== 2eme playbook file ====
creation d'un directory avec les droit root, necessité de monté de privilege ( //become// et -K )
=== playbook ===
ans@disi-dellat:~/ansible$ cat 02_playbook_file.yml
---
- name: J_Playbook_File
hosts: node3
become: yes
tasks:
- name: check_cnx
ping:
- name: create_directory
file:
path: "/tmp/ansdir"
state: directory
owner: root
=== execution ===
ans@disi-dellat:~/ansible$ ansible-playbook -i 01_inventory.yml -u ans -K 02_playbook_file.yml
BECOME password:
PLAY [J_Playbook_File] ******************************************************************************************
TASK [Gathering Facts] ******************************************************************************************
Friday 19 August 2022 10:33:13 +0200 (0:00:00.017) 0:00:00.017 *********
ok: [node3]
TASK [check_cnx] ************************************************************************************************
Friday 19 August 2022 10:33:14 +0200 (0:00:00.868) 0:00:00.885 *********
ok: [node3]
TASK [create_directory] *****************************************************************************************
Friday 19 August 2022 10:33:14 +0200 (0:00:00.326) 0:00:01.212 *********
changed: [node3]
PLAY RECAP ******************************************************************************************************
node3 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Friday 19 August 2022 10:33:15 +0200 (0:00:00.252) 0:00:01.464 *********
===============================================================================
Gathering Facts ------------------------------------------------------------------------------------------ 0.87s
check_cnx ------------------------------------------------------------------------------------------------ 0.33s
create_directory ----------------------------------------------------------------------------------------- 0.25s
=== resultat ===
jehan@node3:/tmp$ ls -ld ansdir/
drwxr-xr-x 2 root root 4096 août 19 10:33 ansdir/
==== autres actions ====
=== touch ===
creation de fichier avec touch (file fait un check de presence)
- name: create_file
file:
path: "/tmp/ansdir/file1"
state: touch
owner: root
group: ans
mode: 0755
==== idempotence ====
le premiere fois que je joue un playbook, les actions se fonts , report //"changed"// (creation fichier, lien, repertoire ...) , au 2eme run si c'est deja fait, ansible ne fait rien a part un report //"ok"// => comparer la situation qui est decrite dans le playbook avec la situation d'arrivée .L'indempotence peut-etre jouée manuellement avec //"changed when"// .
autre notion => statefull / stateless
l'idempotence c'est l'existence strictement de l'objet, tout ce qui est decrit doit exister ou ne pas exister, mais doit etre décrit .
Statefull => tout ce qui est decrit doit exister et tout ce qui n'est pas decrit et dont j'ai connaissance qui doit exister ne doit plus exister .
en statefull avec //terraform// par exemple , si je créé une VM , une DB d'etat (state) contient cet etat, et donc si je joue sur des variables de cette VM plus tard, terraform sait qu'il existe cette VM . Avec Ansible il n'y a pas d'état, il ne sais pas que le VM existe, il ne peut tient pas de registre des actions réalisées .
===== ansible module user =====
* https://docs.ansible.com/ansible/latest/collections/ansible/builtin/user_module.html
state present/absent => creation, destruction
=== playbook module user ===
ans@disi-dellat:~/ansible$ cat 03_playbook_user.yml
---
- name: J_Playbook_User
hosts: node3
become: yes
tasks:
- name: create_user_joe
user:
name: joe
state: present
uid: 1041
groups: sudo
password: "{{ 'password' | password_hash('sha512') }}"
=== execution ===
ans@disi-dellat:~/ansible$ ansible-playbook -i 01_inventory.yml -u ans -K 03_playbook_user.yml
BECOME password:
...
Friday 19 August 2022 13:59:41 +0200 (0:00:00.016) 0:00:00.016 *********
ok: [node3]
TASK [create_user_joe] ******************************************************************************************
Friday 19 August 2022 13:59:42 +0200 (0:00:00.846) 0:00:00.863 *********
changed: [node3]
PLAY RECAP ******************************************************************************************************
node3 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Friday 19 August 2022 13:59:43 +0200 (0:00:01.089) 0:00:01.953 *********
===============================================================================
create_user_joe ------------------------------------------------------------------------------------------ 1.09s
Gathering Facts ------------------------------------------------------------------------------------------ 0.85s
=== resultat ===
jehan@node3:/tmp$ id joe
uid=1041(joe) gid=1041(joe) groups=1041(joe),27(sudo)
=== afficher les details ===
pour voir les details systems de ce qui a été fait on ajoute un register de notre user joe avec un debug sur cette variable :
ans@disi-dellat:~/ansible$ cat 03_playbook_user.yml
---
- name: J_Playbook_User
hosts: node3
become: yes
tasks:
- name: create_user_joe
user:
name: joe
state: present
uid: 1041
groups: sudo
password: "{{ 'password' | password_hash('sha512') }}"
register: __user_joe
- name: debug_user
debug:
var: __user_joe
=== resultat ===
ans@disi-dellat:~/ansible$ ansible-playbook -i 01_inventory.yml -u ans -K 03_playbook_user.yml
BECOME password:
...
TASK [create_user_joe] ******************************************************************************************
Friday 19 August 2022 16:13:18 +0200 (0:00:01.530) 0:00:01.547 *********
changed: [node3]
TASK [debug_user] ***********************************************************************************************
Friday 19 August 2022 16:13:19 +0200 (0:00:00.539) 0:00:02.087 *********
ok: [node3] => {
"__user_joe": {
"append": false,
"changed": true,
"comment": "",
"failed": false,
"group": 1041,
"groups": "sudo",
"home": "/home/joe",
"move_home": false,
"name": "joe",
"password": "NOT_LOGGING_PASSWORD",
"shell": "/bin/sh",
"state": "present",
"uid": 1041
}
}
PLAY RECAP ******************************************************************************************************
node3 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Friday 19 August 2022 16:13:19 +0200 (0:00:00.039) 0:00:02.126 *********
===============================================================================
Gathering Facts ------------------------------------------------------------------------------------------ 1.53s
create_user_joe ------------------------------------------------------------------------------------------ 0.54s
debug_user ----------------------------------------------------------------------------------------------- 0.04s
===== ansible stat register =====
si on souhaite afficher des info sur nos actions, on peut utiliser le module stat sur un fichier par exemple, mais l'affichage des "stat" ne donne rien par defaut, il faut faire un register de l'output pour pouvoir le remonter sur notre server-node source du playbook .
=== playbook ===
ans@disi-dellat:~/ansible$ cat 04_playbook_stat_reg.yml
---
- name: J_Playbook_Stat_Reg
hosts: node3
become: yes
tasks:
- name: create_file
file:
path: "/tmp/ansdir/file2"
state: touch
owner: root
group: ans
mode: 0755
- name: stat_file
stat:
path: "/tmp/ansdir/file2"
register: __stat_file2
- name: display
debug:
var: __stat_file2
=== resultat ===
ans@disi-dellat:~/ansible$ ansible-playbook -i 01_inventory.yml -u ans -K 04_playbook_stat_reg.yml
BECOME password:
PLAY [J_Playbook_Stat_Reg] **************************************************************************************
TASK [Gathering Facts] ******************************************************************************************
Saturday 20 August 2022 10:03:05 +0200 (0:00:00.021) 0:00:00.021 *******
ok: [node3]
TASK [create_file] **********************************************************************************************
Saturday 20 August 2022 10:03:07 +0200 (0:00:01.235) 0:00:01.256 *******
changed: [node3]
TASK [stat_file] ************************************************************************************************
Saturday 20 August 2022 10:03:07 +0200 (0:00:00.277) 0:00:01.533 *******
ok: [node3]
TASK [display] **************************************************************************************************
Saturday 20 August 2022 10:03:07 +0200 (0:00:00.278) 0:00:01.812 *******
ok: [node3] => {
"__stat_file2": {
"changed": false,
"failed": false,
"stat": {
"atime": 1660982587.677271,
"attr_flags": "e",
"attributes": [
"extents"
],
"block_size": 4096,
"blocks": 0,
"charset": "binary",
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"ctime": 1660982587.677271,
"dev": 2053,
"device_type": 0,
"executable": true,
"exists": true,
"gid": 1033,
"gr_name": "ans",
"inode": 262175,
"isblk": false,
"ischr": false,
"isdir": false,
"isfifo": false,
"isgid": false,
"islnk": false,
"isreg": true,
"issock": false,
"isuid": false,
"mimetype": "inode/x-empty",
"mode": "0755",
"mtime": 1660982587.677271,
"nlink": 1,
"path": "/tmp/ansdir/file2",
"pw_name": "root",
"readable": true,
"rgrp": true,
"roth": true,
"rusr": true,
"size": 0,
"uid": 0,
"version": "3306389664",
"wgrp": false,
"woth": false,
"writeable": true,
"wusr": true,
"xgrp": true,
"xoth": true,
"xusr": true
}
}
}
PLAY RECAP ******************************************************************************************************
node3 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Saturday 20 August 2022 10:03:07 +0200 (0:00:00.042) 0:00:01.854 *******
===============================================================================
Gathering Facts ------------------------------------------------------------------------------------------ 1.24s
stat_file ------------------------------------------------------------------------------------------------ 0.28s
create_file ---------------------------------------------------------------------------------------------- 0.28s
display -------------------------------------------------------------------------------------------------- 0.04s
=== stat specifique ===
plus specifiquement si on veux filtrer uniquement sur le retour de stat d'existence du fichier , on utilise dans le module debug un msg sur la variable //stat_file2// dans son dictionnaire il y a une clé //stat// qui a elle meme une clée //exists// qui prend la valeur //true// :
- name: display
debug:
msg: "Fichier exist : {{ __stat_file2.stat.exists }}"
=== resultat ===
ans@disi-dellat:~/ansible$ ansible-playbook -i 01_inventory.yml -u ans -K 04_playbook_stat_reg.yml
TASK [display] **************************************************************************************************
Saturday 20 August 2022 10:18:19 +0200 (0:00:00.281) 0:00:01.823 *******
ok: [node3] => {
"msg": "Fichier exist : True"
}
==== condition when ====
avec cette condition d'existence, on peut maintenat faire une autre action sur le base de ce test, exemple ici on créé un directory si (when) la variable valeur exists = true
- name: creation conditionnelle du subDir
file:
path: /tmp/ansdir2
state: directory
when: __stat_file2.stat.exists == True
TASK [display] **************************************************************************************************
Saturday 20 August 2022 10:27:42 +0200 (0:00:00.294) 0:00:01.512 *******
ok: [node3] => {
"msg": "Fichier exist : True"
}
TASK [creation conditionnelle du subDir] ************************************************************************
Saturday 20 August 2022 10:27:42 +0200 (0:00:00.047) 0:00:01.559 *******
changed: [node3]
PLAY RECAP ******************************************************************************************************
node3 : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
==== ansible boucle ====
* https://docs.ansible.com/ansible/latest/collections/ansible/builtin/items_lookup.html
la plus classique avec with_items qui est une liste a base de dictionnaire
=== playbook ===
creation de 3 repertoires
ans@disi-dellat:~/ansible$ cat 021_playbook_dir.yml
---
- name: J_Playbook_File_Dir
hosts: node3
become: yes
tasks:
- name: create_x_dir
file:
path: "/tmp/ansdir/{{ item }}"
state: directory
recurse: yes
owner: root
with_items:
- ansdirA
- ansdirB
- ansdirC
=== execution ===
TASK [create_x_dir] *********************************************************************************************
Saturday 20 August 2022 10:45:11 +0200 (0:00:01.403) 0:00:01.420 *******
changed: [node3] => (item=ansdirA)
changed: [node3] => (item=ansdirB)
changed: [node3] => (item=ansdirC)
=== dictonnaire de valeur ===
on peut aussi utiliser les items sous forme de dictionnaire de valeur
tasks:
- name: create_x_dir
file:
path: "/tmp/ansdir/{{ item.dir }}/{{ item.fichier }}"
state: directory
recurse: yes
owner: root
with_items:
- { dir: ansdirA, fichier: "file1.txt" }
- { dir: ansdirB, fichier: "file1.txt" }
- { dir: ansdirC, fichier: "file1.txt" }
TASK [create_x_dir] *********************************************************************************************
Saturday 20 August 2022 10:52:27 +0200 (0:00:00.901) 0:00:00.918 *******
changed: [node3] => (item={'dir': 'ansdirA', 'fichier': 'file1.txt'})
changed: [node3] => (item={'dir': 'ansdirB', 'fichier': 'file1.txt'})
changed: [node3] => (item={'dir': 'ansdirC', 'fichier': 'file1.txt'})
PLAY RECAP ******************************************************************************************************
node3 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
==== dictionnaire dans group_vars ====
d'un point de vue organisation, il vaut mieux sortir ces variables du playbook pour les mettre dans le group_vars
ans@disi-dellat:~/ansible$ cat group_vars/all/variables.yml
mydict:
- { dir: ansdirA, fichier: "file1.txt" }
- { dir: ansdirB, fichier: "file1.txt" }
- { dir: ansdirC, fichier: "file1.txt" }
avec dans le playbook un appel a ce dictionnaire
with_items:
{{ mydict }}
==== ansible module apt ====
* https://docs.ansible.com/ansible/latest/collections/ansible/builtin/apt_module.html
installer un paquet , plein d'options existe, cf ref ci-dessus .
ans@disi-dellat:~/ansible$ cat 05_playbook_apt.yml
---
- name: J_Playbook_Apt
hosts: node3
become: yes
tasks:
- name: gestion_apt
apt:
name: tree
state: latest
update_cache: yes
cache_valid_time: 300
le //state: present// est moins risqué en terme d'updates involontaires .
=== execution ===
ans@disi-dellat:~/ansible$ ansible-playbook -i 01_inventory.yml -u ans -K 05_playbook_apt.yml
...
TASK [gestion_apt] **********************************************************************************************
Saturday 20 August 2022 11:29:43 +0200 (0:00:01.394) 0:00:01.412 *******
changed: [node3]
PLAY RECAP ******************************************************************************************************
node3 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Saturday 20 August 2022 11:29:58 +0200 (0:00:15.744) 0:00:17.156 *******
===============================================================================
gestion_apt --------------------------------------------------------------------------------------------- 15.74s
Gathering Facts ------------------------------------------------------------------------------------------ 1.39s
=== supression ===
supression totale
- name: gestion_apt
apt:
name: tree
state: absent
purge: yes
autoremove: yes
==== ansible module reboot ====
* https://docs.ansible.com/ansible/latest/collections/ansible/builtin/reboot_module.html
on demande un reboot sur la base de la presence d'un fichier
ans@disi-dellat:~/ansible$ cat 06_playbook_reboot.yml
---
- name: J_Playbook_File_Reboot
hosts: node3
become: yes
tasks:
- name: create_fileR
file:
path: "/tmp/fileR"
state: touch
- name: stat_fileR
stat:
path: "/tmp/fileR"
register: __stat_fileR
- name: reboot_node
reboot:
msg: "Reboot par Ansible"
connect_timeout: 5
reboot_timeout: 300
pre_reboot_delay: 0
post_reboot_delay: 50
test_command: uptime
when: __stat_fileR.stat.exists
- name: reboot_ok
file:
path: "/tmp/rebootOK"
state: touch
=== execution ===
ans@disi-dellat:~/ansible$ ansible-playbook -i 01_inventory.yml -u ans -K 06_playbook_reboot.yml
BECOME password:
PLAY [J_Playbook_File_Reboot] ***********************************************************************
TASK [Gathering Facts] ******************************************************************************
Saturday 20 August 2022 11:54:11 +0200 (0:00:00.017) 0:00:00.017 *******
ok: [node3]
TASK [create_fileR] *********************************************************************************
Saturday 20 August 2022 11:54:12 +0200 (0:00:00.859) 0:00:00.876 *******
changed: [node3]
TASK [stat_fileR] ***********************************************************************************
Saturday 20 August 2022 11:54:12 +0200 (0:00:00.294) 0:00:01.171 *******
ok: [node3]
TASK [reboot_node] **********************************************************************************
Saturday 20 August 2022 11:54:12 +0200 (0:00:00.301) 0:00:01.473 *******
changed: [node3]
TASK [reboot_ok] ************************************************************************************
Saturday 20 August 2022 11:55:25 +0200 (0:01:13.094) 0:01:14.567 *******
changed: [node3]
PLAY RECAP ******************************************************************************************
node3 : ok=5 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Saturday 20 August 2022 11:55:26 +0200 (0:00:00.861) 0:01:15.429 *******
===============================================================================
reboot_node --------------------------------------------------------------------------------- 73.09s
reboot_ok ------------------------------------------------------------------------------------ 0.86s
Gathering Facts ------------------------------------------------------------------------------ 0.86s
stat_fileR ----------------------------------------------------------------------------------- 0.30s
create_fileR --------------------------------------------------------------------------------- 0.29s
==== ansible module ssh ====
* https://docs.ansible.com/ansible/latest/collections/ansible/posix/authorized_key_module.html
* https://docs.ansible.com/ansible/latest/collections/community/crypto/openssh_keypair_module.html
genérer une clée ssh et la deployer
ans@disi-dellat:~/ansible$ cat 07_playbook_ssh_key.yml
---
- name: J_Playbook_sshKey
hosts: node3
become: yes
tasks:
- name: create_sshKey
openssh_keypair:
path: "/tmp/ssh-ans-key"
type: rsa
size: 2048
state: present
force: no
#delegate a localhost pour jouer ça sur notre server-node
delegate_to: localhost
#le faire tourner une seule fois , meme si +sieurs hosts
run_once: yes
=== execution ===
ans@disi-dellat:~/ansible$ ansible-playbook -i 01_inventory.yml -u ans -K 07_playbook_ssh_key.yml
BECOME password:
PLAY [J_Playbook_sshKey] ****************************************************************************
TASK [Gathering Facts] ******************************************************************************
Saturday 20 August 2022 20:45:52 +0200 (0:00:00.017) 0:00:00.017 *******
ok: [node3]
TASK [create_sshKey] ********************************************************************************
Saturday 20 August 2022 20:45:53 +0200 (0:00:00.860) 0:00:00.877 *******
changed: [node3 -> localhost]
PLAY RECAP ******************************************************************************************
node3 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Saturday 20 August 2022 20:45:53 +0200 (0:00:00.208) 0:00:01.085 *******
===============================================================================
Gathering Facts ------------------------------------------------------------------------------ 0.86s
create_sshKey -------------------------------------------------------------------------------- 0.21s
ans@disi-dellat:~/ansible$ ls -ltr /tmp/ssh*
-rw-r--r-- 1 root root 382 août 20 20:45 /tmp/ssh-ans-key.pub
-rw------- 1 root root 1799 août 20 20:45 /tmp/ssh-ans-key
==== deploy ssh-key ====
apres generation locale de la clé (pas besoin d'elevation de privilege (become)) , on crée un user (become necessaire) , l'ajoute dans sudoers et on lui pousse la clé :
ans@disi-dellat:~/ansible$ cat 07_playbook_ssh_key.yml
---
- name: J_Playbook_sshKey
hosts: node3
become: yes
tasks:
- name: create_sshKey
openssh_keypair:
path: "/tmp/ssh-adma-key"
type: rsa
size: 2048
state: present
force: no
#delegate a localhost pour jouer ça sur notre server-node
delegate_to: localhost
#le faire tourner une seule fois , meme si +sieurs hosts
run_once: yes
- name: create_user_adma
user:
name: adma
shell: /bin/bash
groups: sudo
append: yes
password: "{{ '1pAA2022.' | password_hash('sha256') }}"
become: yes
- name: add_adma_sudoers
copy:
dest: "/etc/sudoers.d/sudoers-adma"
content: "adma ALL=(ALL) NOPASSWD: ALL"
become: yes
- name: deploy_sshKey
authorized_key:
user: adma
key: "{{ lookup('file', '/tmp/ssh-adma-key.pub') }}"
state: present
become: yes
=== execution ===
ans@disi-dellat:~/ansible$ ansible-playbook -i 01_inventory.yml -u ans -K 07_playbook_ssh_key.yml
BECOME password:
PLAY [J_Playbook_sshKey] ****************************************************************************
TASK [Gathering Facts] ******************************************************************************
Sunday 21 August 2022 10:47:05 +0200 (0:00:00.017) 0:00:00.017 *********
ok: [node3]
TASK [create_sshKey] ********************************************************************************
Sunday 21 August 2022 10:47:06 +0200 (0:00:01.254) 0:00:01.271 *********
ok: [node3 -> localhost]
TASK [create_user_adma] *****************************************************************************
Sunday 21 August 2022 10:47:06 +0200 (0:00:00.185) 0:00:01.457 *********
changed: [node3]
TASK [add_adma_sudoers] *****************************************************************************
Sunday 21 August 2022 10:47:07 +0200 (0:00:00.496) 0:00:01.953 *********
ok: [node3]
TASK [deploy_sshKey] ********************************************************************************
Sunday 21 August 2022 10:47:07 +0200 (0:00:00.622) 0:00:02.576 *********
changed: [node3]
PLAY RECAP ******************************************************************************************
node3 : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Sunday 21 August 2022 10:47:08 +0200 (0:00:00.660) 0:00:03.236 *********
===============================================================================
Gathering Facts ------------------------------------------------------------------------------ 1.25s
deploy_sshKey -------------------------------------------------------------------------------- 0.66s
add_adma_sudoers ----------------------------------------------------------------------------- 0.62s
create_user_adma ----------------------------------------------------------------------------- 0.50s
create_sshKey -------------------------------------------------------------------------------- 0.19s