Misalkan pelanggan meminta Anda untuk membantu dengan migrasi skrip untuk menyebarkan file sudoers terpusat pada server RHEL dan AIX.

Nah, ini adalah skenario yang cukup umum, dan dengan contohnya Anda dapat menunjukkan penggunaan fitur lanjutan dari Ansible, serta bagaimana pendekatannya berubah - dari skrip yang melakukan tugas tertentu, hingga deskripsi idempoten (tanpa membuat perubahan) dan memantau kepatuhan dengan keadaan instance.
Ambil skripnya:
Ada 212 baris kode, tanpa kontrol versi di file sudoers. Pelanggan sudah memiliki proses yang berjalan seminggu sekali dan memeriksa checksum file untuk memastikan keamanan. Meskipun skrip berisi referensi ke Solaris, untuk pelanggan ini kami tidak harus mentransfer persyaratan ini.
Mari kita mulai dengan membuat peran dan meletakkan file sudoers di Git untuk kontrol versi. Antara lain, ini akan memungkinkan kita untuk menyingkirkan kebutuhan untuk me-mount volume NFS.
Dengan parameter validasi dan cadangan untuk modul
salin dan
templat , kita dapat menghilangkan kebutuhan untuk menulis kode untuk membuat cadangan dan memulihkan file. Dalam hal ini, validasi dilakukan sebelum file ditempatkan di titik tujuan, dan jika validasi gagal, modul melempar kesalahan.
Untuk setiap peran, kita perlu menentukan tugas, templat, dan variabel. Berikut adalah struktur file yang sesuai:

File skrip peran (playbook),
sudoers.yml , memiliki struktur sederhana:
---
##
# Role playbook
##
- hosts: all
roles:
- sudoers
...
Variabel peran terletak di file
vars / main.yml . File ini berisi file checksum dan termasuk / tidak termasuk arahan yang akan digunakan untuk membuat logika khusus untuk melewati host Lawson dan menyertakan file sudoers.d hanya di host hd.
Berikut ini isi dari file
vars / main.yml :
---
MD5FILE: /root/.sudoer.md5
EXCLUDE: la
INCLUDE: hd
...
Jika kita menggunakan
modul copy dan
lineinfile , maka perannya tidak akan idempoten. Modul copy akan menginstal file dasar, dan lineinfile akan memasukkan kembali setiap kali dimulai. Karena peran ini akan diluncurkan di
Ansible Tower , idempotensi adalah suatu keharusan. Kami akan mengonversi file ke templat jinja2.
Di baris pertama, kami menambahkan perintah berikut untuk
mengontrol spasi dan indentasi :
#jinja2: lstrip_blocks: True, trim_blocks: True
Perhatikan bahwa versi yang lebih baru dari modul
template menyertakan parameter untuk
trim_blocks (ditambahkan pada Ansible 2.4).
Berikut adalah kode yang menyisipkan baris
sertakan di akhir file:
{% if ansible_hostname[0:2] == INCLUDE %}
#includedir /etc/sudoers.d
{% endif %}
Kami menggunakan konstruksi kondisional ({% if%}, {% endif%}) untuk perintah shell yang menyisipkan baris untuk host yang namanya dimulai dengan karakter "hd". Kami menggunakan Fakta yang mungkin dan filter [0: 2] untuk mengurai nama host.
Sekarang mari kita beralih ke tugas. Pertama, Anda perlu menetapkan fakta untuk parsing nama host. Kami akan menggunakan fakta "parhost" dalam konstruk bersyarat.
---
##
# Parse hostnames to grab 1st 2 characters
##
- name: "Parse hostname's 1st 2 characters"
set_fact: parhost={{ ansible_hostname[0:2] }}
Tidak ada parameter
csum di server stok RHEL. Jika perlu, kita bisa menggunakan fakta lain untuk menunjukkan secara kondisional nama file biner dengan checksum. Harap dicatat bahwa kode tambahan mungkin diperlukan jika fitur-fitur ini berbeda pada AIX, Solaris, dan Linux.
Selain itu, kami harus menyelesaikan masalah dengan perbedaan dalam grup root pada AIX dan RHEL.
##
# Conditionally set name of checksum binary
##
- name: "set checksum binary"
set_fact:
csbin: "{{ 'cksum' if (ansible_distribution == 'RedHat') else 'csum' }}"
##
# Conditionally set name of root group
##
- name: "set system group"
set_fact:
sysgroup: "{{ 'root' if (ansible_distribution == 'RedHat') else 'sys' }}"
Menggunakan blok memungkinkan kita untuk mengatur kondisi untuk seluruh tugas. Kami akan menggunakan kondisi di akhir blok untuk mengecualikan host "la".
##
# Enclose in block so we can use parhost to exclude hosts
##
- block:
Modul template memvalidasi dan menginstal file. Kami memperbaiki hasilnya sehingga kami dapat menentukan apakah tugas telah berubah. Menggunakan parameter validasi dalam modul ini memungkinkan Anda memverifikasi keabsahan file sudoer baru sebelum menempatkannya di host.
##
# Validate will prevent bad files, no need to revert
# Jinja2 template will add include line
##
- name: Ensure sudoers file
template:
src: sudoers.j2
dest: /etc/sudoers
owner: root
group: "{{ sysgroup }}"
mode: 0440
backup: yes
validate: /usr/sbin/visudo -cf %s
register: sudochg
Jika templat baru telah diinstal, jalankan skrip shell untuk menghasilkan file checksum. Konstruk bersyarat memperbarui file checksum ketika menginstal templat sudoers, atau jika file checksum hilang. Karena proses yang berjalan juga memantau file lain, kami menggunakan kode shell yang disediakan dalam skrip sumber:
- name: sudoers checksum
shell: "grep -v '/etc/sudoers' {{ MD5FILE }} > {{ MD5FILE }}.tmp ; {{ csbin }} /etc/sudoers >> {{ MD5FILE }} ; mv {{ MD5FILE }}.tmp {{ MD5FILE }}"
when: sudochg.changed or MD5STAT.exists == false
Modul file memverifikasi pemasangan izin yang diperlukan:
- name: Ensure MD5FILE permissions
file:
path: "{{ MD5FILE }}"
owner: root
group: "{{ sysgroup }}"
mode: 0600
state: file
Karena parameter cadangan tidak menyediakan opsi apa pun untuk memproses cadangan sebelumnya, kami harus mengurus sendiri pembuatan kode yang sesuai. Dalam contoh di bawah ini, kami menggunakan parameter "register" dan bidang "stdout_lines" untuk ini.
##
# List and clean up backup files. Retain 3 copies.
##
- name: List /etc/sudoers.*~ files
shell: "ls -t /etc/sudoers*~ |tail -n +4"
register: LIST_SUDOERS
changed_when: false
- name: Cleanup /etc/sudoers.*~ files
file:
path: "{{ item }}"
state: absent
loop: "{{ LIST_SUDOERS.stdout_lines }}"
when: LIST_SUDOERS.stdout_lines != ""
Penyelesaian Blok:
##
# This conditional restricts what hosts this block runs on
##
when: parhost != EXCLUDE
...
Kasing yang dimaksudkan adalah memainkan peran ini di Ansible Tower. Peringatan Menara yang Mungkin Dikonfigurasi sehingga jika terjadi kegagalan dalam pelaksanaan pekerjaan, peringatan akan dikirim ke email, ke Slack, atau dengan cara lain. Peran ini berjalan di Ansible, Ansible Engine, atau Ansible Tower.
Sebagai hasilnya, kami menghapus semua yang tidak perlu dari skrip dan menciptakan peran yang benar-benar idempoten yang dapat memberikan keadaan yang diinginkan dari file sudoers. Menggunakan SCM memungkinkan kontrol versi, memberikan manajemen perubahan dan transparansi yang lebih efisien. CI / CD dengan Jenkins atau alat lain memungkinkan Anda mengatur pengujian otomatis atas kode yang mungkin untuk perubahan di masa mendatang. Peran Auditor di Ansible Tower memungkinkan Anda untuk memantau dan menegakkan persyaratan organisasi.
Kode untuk bekerja dengan checksum dapat dihapus dari skrip, tetapi untuk ini pelanggan harus terlebih dahulu berkonsultasi dengan layanan keamanannya. Jika perlu, pola sudoers dapat dilindungi dengan Vault Ansible. Akhirnya, menggunakan grup menghindari menulis logika menggunakan include dan exclude.
→ Anda dapat mengunduh peran dari GitHub di
tautan ini