initiation ansible

references

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

  1. ANSIBLE_CONFIG : variable d'env qui contient la location du fichier
  2. fichier ansible.cfg dans le repertoire du repertoire du playbook en cours
  3. ~/.ansible/ansible.cfg
  4. /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

  1. creation fichier python
  2. creation directory
  3. envoie du fichier python via sftp
  4. run python distant
  5. recuperation stdout

avec pipelining

  1. creation fichier python
  2. envoie du contenu sur node distant dans l'interpreteur python via stdin
  3. 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

ansible variables

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:- 

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

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

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

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

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

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

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

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
docpublic/systemes/ansible_init.txt · Last modified: 2022/08/21 08:49 by adminjp
CC Attribution-Noncommercial-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0