30 Ansible für ff@home aufsetzen.page 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  1. ---
  2. format: markdown
  3. title: Ansible ff@home aufsetzen
  4. toc: yes
  5. ...
  6. # Software
  7. - Debian 12 (bookworm) oder Ubuntu 22.04
  8. - python3 und ansible
  9. ***** Es empfiehlt sich, eine python virtuelle Umgebung zu verwenden *****
  10. Nur für die folgende Paketinstallation sind root-Rechte erforderlich,alle weiteren Terminaleingaben erfolgen als normaler user.
  11. Die folgenden Pakete installieren:
  12. $ sudo apt install python3-pip python3-venv
  13. Dann in das Basisverzeichnis gehen (bei mir /datadisk) und die virtuelle Umgebung anlegen
  14. $ python3 -m venv ffhome
  15. In dem Verzeichnis ffhome die Umgebung aktivieren
  16. $ source bin/activate
  17. Dadurch ändert sich der prompt, je nach Einstellung $ oder 0]:
  18. (ffhome) 18:16:41[frankb@berglap /datadisk/ffhome 0]
  19. Zum Verlassen der Umgebung:
  20. $ deactivate oder Terminal Fenster schliessen
  21. Jetzt kann ansible in der ffhome Umgebung installiert werden:
  22. $ pip3 install ansible
  23. 18:11:20[frankb@berglap /datadisk/ffhome 0]
  24. Die Verzeichnistruktur der Testumgebung
  25. $ tree -L 4 /datadisk/ffhome
  26. /datadisk/ffhome
  27. ├── ansible.cfg
  28. ├── bin
  29. │   ├── activate
  30. │   ├── activate.csh
  31. │   ├── activate.fish
  32. │   ├── Activate.ps1
  33. │   ├── ansible
  34. │   ├── ansible-community
  35. ...
  36. │   └── yamllint
  37. ├── include
  38. ├── inventory
  39. │   ├── hosts.yaml
  40. │   └── host_vars
  41. |    ├── bergdesk
  42. │      │   ├── vars
  43. │      │   ├── vars.01.bak
  44. │      │   ├── vars.02.bak
  45. │      │   └── vault
  46. │      ├── berghofen
  47. │      │   ├── vars
  48. │      │   ├── vars.01.bak
  49. │      │   ├── vars.bak
  50. │      │   └── vault
  51. │      ├── berglap
  52. │      │   ├── vars
  53. │      │   ├── vars.01.bak
  54. │      │   ├── vars.bak
  55. │      │   └── vault
  56. │      └── luna
  57. │      ├── vars
  58. │      └── vault
  59. ├── lib
  60. │   └── python3.10
  61. ├── lib64 -> lib
  62. ...
  63. ├── playbooks
  64. │   ├── resources
  65. │   │   └── host
  66. │   │   ├── tincbergdesk.gz
  67. │   │   └── tincberghofen.gz
  68. │   ├── templates
  69. │   │   ├── tinc-up.lan.j2
  70. │   │   └── tinc-up.wan.j2
  71. │   ├── tincbuild.yaml
  72. │   └── update.yaml
  73. └── pyvenv.cfg
  74. Bei den ... sind Zeilen der Übersichtlichkeit halber weggelassen.
  75. Die verwendete ansible.cfg:
  76. [defaults]
  77. inventory=./inventory/
  78. roles_path=./roles
  79. playbook_dir=./playbooks/
  80. interpreter_python=auto_silent
  81. #vault_password_file=~/.vault-password
  82. log_path=/tmp/ansible_ffhome.log
  83. cow_selection=random
  84. nocows=True
  85. stdout_callback=yaml
  86. display_args_to_stdout=True
  87. [privilege_escalation]
  88. become=True
  89. [ssh_connection]
  90. pipelining=True
  91. Datei mit den beteiligten Hosts inventory/hosts.yaml
  92. ---
  93. all:
  94. vars:
  95. ansible_port: 24
  96. ansible_user: frankb
  97. ansible_become: true
  98. apus:
  99. hosts:
  100. berghofen:
  101. ansible_host: 192.168.178.51
  102. ansible_user: fb
  103. ansible_become_password: "{{ berghofen_password }}"
  104. desktops:
  105. hosts:
  106. bergdesk:
  107. ansible_host: 192.168.178.201
  108. ansible_become_pass: '{{ bergdesk_password }}'
  109. berglap:
  110. ansible_host: 192.168.178.52
  111. ansible_become_pass: '{{ berglap_password }}'
  112. luna:
  113. ansible_host: 192.168.178.224
  114. ansible_become_pass: '{{ luna_password }}'
  115. altlast:
  116. hosts:
  117. hoerde:
  118. ansible_host: 193.43.220.136
  119. ansible_become: true
  120. ansible_become_method: su
  121. supernodes:
  122. hosts:
  123. 31.172.33.20:
  124. ansible_port: 22
  125. snng-dus01.ffdo.de:
  126. ansible_port: 22
  127. snng-dtm01.ffdo.de:
  128. ansible_port: 22
  129. Die Gruppen apus und desktops enthalten die testhosts, die Gruppen altlast und supernodes sind nicht komplett einbezogen.
  130. Im Verzeichnis inventory/host_vars sind Variablen für die einzelnen hosts, u.a. die passwords, in vars unverschlüsselt, in vault aes256 geschützt. Weiter sind Parameter für tinc enthalten, nur in vars, unverschlüsselt.
  131. Beispielhaft für berghofen
  132. $ cat berghofen/vars
  133. ---
  134. berghofen_password: "{{ vault_berghofen_password }}"
  135. tinc_bindto: 192.168.178.51
  136. wan_broadcast_ip: 193.43.220.191
  137. wan_ip: 193.43.220.162/27
  138. lan_broadcast_ip: 192.168.34.255
  139. lan_ip: 192.168.34.1/24
  140. $ cat berghofen/vault
  141. $ANSIBLE_VAULT;1.2;AES256;xx
  142. 35656536383233636434636533613830303439316263636436363932333636626462616461636537
  143. 3838626266396332363236643361626134393238636133640a646333333866643161356333626564
  144. 32373735343033633666353763376230646137663639373438393537663031643562376365396337
  145. 3161646534666236350a303366373433373833373066353030363766616166666361376637393464
  146. 30613139313661643932373239333865616338653132613530393161656466326561633537383535
  147. 3631356664643139383037636565346630643036353364333866
  148. In der vault Datei (hier Klartext)
  149. ---
  150. vault_berghofen_password: hier das echte PW eintragen
  151. dann die vault Datei verschlüsseln mit
  152. $ ansible-vault encrypt vault --vault-id xxxxx@prompt
  153. anzeigen kann man die Datei mit
  154. $ ansible-vault view vault
  155. und wieder entschlüsseln mit
  156. $ ansible-vault decrypt vault
  157. Es gibt z.Zt. zwei playbooks: update.yaml und tincbuild.yaml
  158. $ cat playbooks/update.yaml
  159. ---
  160. # name: update yaml
  161. - hosts: [desktops,apus,altlast]
  162. tasks:
  163. - name: Testausgabe
  164. debug: msg="Hallo von {{ ansible_hostname }} Ansible managed!"
  165. - name: df -h Aufruf
  166. command: df -h /
  167. changed_when: false
  168. register: df_cmd
  169. - debug:
  170. msg: '{{df_cmd.stdout_lines}} {{ansible_distribution }}'
  171. - name: ping meine hosts
  172. ansible.builtin.ping:
  173. changed_when: false
  174. # - name: Warte auf enter Taste
  175. # ansible.builtin.pause:
  176. - name: Ist flatpak installiert
  177. stat:
  178. path: /usr/bin/flatpak
  179. register: flatpak_file
  180. when: ansible_os_family == "Debian"
  181. - name: Update flatpak Pakete falls snap vh
  182. command: /usr/bin/flatpak update
  183. when: ansible_os_family == "Debian" and flatpak_file.stat.exists
  184. - name: Ist snap installiert
  185. stat:
  186. path: /usr/bin/snap
  187. register: snap_file
  188. when: ansible_os_family == "Debian"
  189. - name: Update snap Pakete falls snap vh
  190. command: /usr/bin/snap refresh
  191. when: ansible_os_family == "Debian" and snap_file.stat.exists
  192. - name: apt update mit upgrade und autoremove
  193. ansible.builtin.apt:
  194. update_cache: yes
  195. cache_valid_time: 3600
  196. autoremove: yes
  197. upgrade: 'yes'
  198. when: ansible_os_family == "Debian"
  199. - stat:
  200. path: /var/run/needrestart
  201. register: needrestart_file
  202. - name: reboot falls erforderlich
  203. ansible.builtin.reboot:
  204. when:
  205. - ansible_os_family == "Debian" and
  206. ( needrestart_file.stat.exists or
  207. rebootreq_file.stat.exists
  208. )
  209. - name: playbook hier beenden bei ! debian
  210. meta: end_play
  211. when: ansible_os_family != "Debian"
  212. $ cat playbooks/tincbuild.yaml
  213. ---
  214. # name: tincbuild yaml
  215. - hosts: [desktops, apus, altlast]
  216. vars:
  217. TINC_VERSION: 1.1pre18
  218. tinc_dev: /dev/net/tun
  219. tinc_mode: switch
  220. tinc_adr_family: ipv4
  221. tinc_max_timeout: 30
  222. tinc_port:
  223. lan: 10001
  224. wan: 661
  225. tasks:
  226. # - name: Show facts available on the system
  227. # ansible.builtin.debug:
  228. # var: ansible_facts
  229. # das folgende klappt leider nicht {{tinc_port.{{ item }}}} syntaxfehler
  230. # geschachtelte variablen gehen nicht.
  231. # - name: willi
  232. # debug: msg="var {{ tinc_port.{{lan}}}}"
  233. - name: Testausgabe
  234. debug: msg="Hallo von {{ ansible_hostname }} Ansible managed!"
  235. - name: df -h Aufruf
  236. command: df -h /
  237. changed_when: false
  238. register: df_cmd
  239. - debug:
  240. msg: '{{df_cmd.stdout_lines}} {{ansible_distribution }}'
  241. # - name: ping meine hosts
  242. # ansible.builtin.ping:
  243. # changed_when: false
  244. # - name: Warte auf enter Taste
  245. # ansible.builtin.pause:
  246. - name: playbook hier beenden bei ! debian
  247. meta: end_play
  248. when: ansible_os_family != "Debian"
  249. - name: Ist tinc Konfigurationsverzeichnis vorhanden
  250. stat:
  251. path: /etc/tinc
  252. register: tinckonf
  253. - name: Gibt es Sicherung von tinc Konfiguration
  254. # ueberlebt keinen reboot
  255. stat:
  256. path: /tmp/tinc{{ ansible_hostname }}.gz
  257. register: tincgz
  258. - name: Konfiguration packen wenn noetig
  259. community.general.archive:
  260. path: /etc/tinc
  261. dest: /tmp/tinc{{ ansible_hostname }}.gz
  262. when: tinckonf.stat.exists
  263. - name: Gesicherte Konfiguration auf Controlnode kopieren
  264. ansible.builtin.fetch:
  265. src: /tmp/tinc{{ ansible_hostname }}.gz
  266. dest: resources/host/
  267. flat: true
  268. when: tinckonf.stat.exists
  269. # - name: Gesicherte Konfiguration auf targetnode loeschen
  270. # file:
  271. # name: /tmp/tinc{{ ansible_hostname }}.gz
  272. # state: absent
  273. # when: tincgz.stat.exists
  274. - name: Abhängigkeiten fuer tinc installieren
  275. apt:
  276. pkg: "{{ item }}"
  277. state: present
  278. with_items:
  279. - build-essential
  280. - libncurses-dev
  281. - libreadline-dev
  282. - pkg-config
  283. - zlib1g-dev
  284. - liblzo2-dev
  285. - libssl-dev
  286. - texinfo
  287. - name: create directory for tinc
  288. file:
  289. name: /opt/tinc
  290. state: directory
  291. - name: Download tinc source
  292. get_url:
  293. url: "https://www.tinc-vpn.org/packages/tinc-{{TINC_VERSION}}.tar.gz"
  294. dest: /opt/tinc/tinc-{{TINC_VERSION}}.tar.gz
  295. register: gettinc
  296. - name: tinc-Quellen entpacken
  297. unarchive:
  298. src: /opt/tinc/tinc-{{TINC_VERSION}}.tar.gz
  299. dest: /usr/src
  300. remote_src: true
  301. when:
  302. - gettinc.changed
  303. - name: Pruefen tinc programm vh
  304. stat:
  305. path: /usr/sbin/tinc
  306. register: tinc_bin
  307. - name: tinc kompilieren und installieren
  308. shell: "cd /usr/src/tinc-{{TINC_VERSION}}
  309. && ./configure --prefix=/usr --sysconfdir=/etc --runstatedir=/run
  310. --localstatedir=/var --with-systemd
  311. && make
  312. && make install"
  313. when:
  314. - tinc_bin.stat.exists == False or gettinc.changed
  315. - name: Gibt es schon eine (alte) tinc Konfiguration
  316. stat:
  317. path: /etc/tinc
  318. register: tinc_etc
  319. - name: tinc Konfigurationsreste beseitigen
  320. file:
  321. path: /etc/tinc
  322. state: absent
  323. when:
  324. - tinc_etc.stat.exists
  325. - name: tinc lan/wan vorkonfigurieren in mehreren Schritten
  326. shell: "tinc --net={{ item }} init {{ansible_hostname}}"
  327. with_items:
  328. - lan
  329. - wan
  330. # when:
  331. # - tinc_bin.stat.exists == False or gettinc.changed
  332. - name: 2048er priv und pub keys löschen
  333. shell: "rm /etc/tinc/{{ item }}/*.priv
  334. && rm /etc/tinc/{{ item }}/hosts/*"
  335. with_items:
  336. - lan
  337. - wan
  338. # when:
  339. # - tinc_bin.stat.exists == False or gettinc.changed
  340. - name: 4096er keys generieren
  341. shell: "tinc --net={{ item }} -b generate-keys 4096"
  342. with_items:
  343. - lan
  344. - wan
  345. # when:
  346. # - tinc_bin.stat.exists == False or gettinc.changed
  347. - name: tinc.conf einrichten
  348. shell: "tinc --net={{ item }} set Device {{tinc_dev}}
  349. && tinc --net={{ item }} set Mode {{tinc_mode}}
  350. && tinc --net={{ item }} set AddressFamily {{tinc_adr_family}}
  351. && tinc --net={{ item }} set MaxTimeout {{tinc_max_timeout}}
  352. && tinc --net={{ item }} set BindToAddress {{tinc_bindto}}"
  353. with_items:
  354. - lan
  355. - wan
  356. # when:
  357. # - tinc_bin.stat.exists == False or gettinc.changed
  358. - name: lan/wan ports setzen
  359. # das geht leider nicht in loop, da Variablen nicht geschachtelt
  360. shell: "tinc --net=lan set Port {{ tinc_port.lan }}
  361. && tinc --net=wan set Port {{ tinc_port.wan }}"
  362. - name: tinc-up anpassen
  363. ansible.builtin.template:
  364. src: templates/tinc-up.{{ item }}.j2
  365. dest: /etc/tinc/{{ item }}/tinc-up
  366. with_items:
  367. - lan
  368. - wan
  369. # when:
  370. # - tinc_bin.stat.exists == False or gettinc.changed
  371. - meta: end_play
  372. Für tinc-up werden folgende templates verwendet
  373. $ cat playbooks/templates/tinc-up.lan.j2
  374. #!/bin/sh
  375. ip addr add {{ lan_ip }} brd {{ lan_broadcast_ip }} dev $INTERFACE
  376. ip link set $INTERFACE mtu 1504 up
  377. $ cat playbooks/templates/tinc-up.wan.j2
  378. #!/bin/sh
  379. ip addr add {{ wan_ip }} brd {{ wan_broadcast_ip }} dev $INTERFACE
  380. ip link set $INTERFACE mtu 1504 up
  381. Aufruf der beiden playbooks mit
  382. $ ansible-playbook -b playbooks/update.yaml -i inventory/hosts.yaml --ask-vault-pass
  383. $ ansible-playbook -b playbooks/tincbuild.yaml -i inventory/hosts.yaml --ask-vault-pass
  384. Gekürzte Ausgabe:
  385. (ffhome) 20:55:59[frankb@berglap /datadisk/ffhome 4] ansible-playbook -b playbooks/update.yaml -i inventory/hosts.yaml --ask-vault-pass
  386. Vault password:
  387. PLAY [desktops,apus,altlast] ***************************************************************
  388. TASK [Gathering Facts] *********************************************************************
  389. [WARNING]: Platform linux on host berglap is using the discovered Python interpreter at
  390. /usr/bin/python3.10, but future installation of another Python interpreter could change the
  391. meaning of that path. See https://docs.ansible.com/ansible-
  392. core/2.17/reference_appendices/interpreter_discovery.html for more information.
  393. ok: [berglap]
  394. [WARNING]: Platform linux on host bergdesk is using the discovered Python interpreter at
  395. /usr/bin/python3.11, but future installation of another Python interpreter could change the
  396. meaning of that path. See https://docs.ansible.com/ansible-
  397. core/2.17/reference_appendices/interpreter_discovery.html for more information.
  398. ok: [bergdesk]
  399. fatal: [luna]: UNREACHABLE! => changed=false
  400. msg: 'Failed to connect to the host via ssh: ssh: connect to host 192.168.178.224 port 24: No route to host'
  401. unreachable: true
  402. [WARNING]: Platform linux on host berghofen is using the discovered Python interpreter at
  403. /usr/bin/python3.11, but future installation of another Python interpreter could change the
  404. meaning of that path. See https://docs.ansible.com/ansible-
  405. core/2.17/reference_appendices/interpreter_discovery.html for more information.
  406. ok: [berghofen]
  407. [WARNING]: Platform freebsd on host hoerde is using the discovered Python interpreter at
  408. /usr/local/bin/python3.9, but future installation of another Python interpreter could
  409. change the meaning of that path. See https://docs.ansible.com/ansible-
  410. core/2.17/reference_appendices/interpreter_discovery.html for more information.
  411. ok: [hoerde]
  412. TASK [Testausgabe] *************************************************************************
  413. ok: [bergdesk] =>
  414. msg: Hallo von bergdesk Ansible managed!
  415. ok: [berglap] =>
  416. msg: Hallo von berglap Ansible managed!
  417. ok: [berghofen] =>
  418. msg: Hallo von berghofen Ansible managed!
  419. ok: [hoerde] =>
  420. msg: Hallo von hoerde Ansible managed!
  421. TASK [df -h Aufruf] ************************************************************************
  422. ok: [berglap]
  423. ok: [bergdesk]
  424. ok: [berghofen]
  425. ok: [hoerde]
  426. TASK [debug] *******************************************************************************
  427. ok: [bergdesk] =>
  428. msg: '[''Dateisystem Größe Benutzt Verf. Verw% Eingehängt auf'', ''/dev/sdb1 439G 98G 319G 24% /''] Debian'
  429. ok: [berglap] =>
  430. msg: '[''Dateisystem Größe Benutzt Verf. Verw% Eingehängt auf'', ''/dev/mapper/system-root 444G 298G 124G 71% /''] Ubuntu'
  431. ok: [berghofen] =>
  432. msg: '[''Dateisystem Größe Benutzt Verf. Verw% Eingehängt auf'', ''/dev/sda6 18G 5,1G 12G 30% /''] Debian'
  433. ok: [hoerde] =>
  434. msg: '[''Filesystem Size Used Avail Capacity Mounted on'', ''s3pool25/jail/hoerde.ffdo.net 3.9G 891M 3.0G 22% /''] FreeBSD'
  435. TASK [ping meine hosts] ********************************************************************
  436. ok: [berglap]
  437. ok: [bergdesk]
  438. ok: [berghofen]
  439. ok: [hoerde]
  440. ...
  441. PLAY RECAP *********************************************************************************
  442. bergdesk : ok=6 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
  443. berghofen : ok=6 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
  444. berglap : ok=6 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
  445. hoerde : ok=5 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
  446. luna : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0