Belakangan ini, saya sedang mempelajari automation tool Ansible. Selama mempelajari Ansible bisa dibilang cara menggunakannya cukup mudah. Saya pribadi sudah mulai menggunakan Ansible ini untuk pekerjaan sehari-hari dan bisa dibilang perbedaannya cukup terasa ya jika dibandingkan dengan cara manual. Dengan Ansible saya bisa melakukan konfigurasi yang serupa pada beberapa host sekaligus tanpa harus remote server target satu persatu, sehingga lebih menghemat waktu saya.
Salah satu hal yang kerap saya lakukan menggunakan Ansible adalah melakukan instalasi beberapa package di beberapa server Linux. Untuk instalasi package sekaligus di beberapa server Linux mungkin terlihat mudah, karena sebenarnya kita bisa saja menggunakan perintah looping seperti contoh dibawah ini.
for i in`list-server.txt`
; do ssh root@$i -t "command; apt install package -y" for i in`list-server.txt`
; do ssh root@$i -t "command; yum install package -y"
Namun tidak akan semudah itu jika kumpulan server Linux terdiri dari beberapa distribusi yang berbeda. Karena seperti yang kita ketahui beberapa package Linux tertentu memiliki nama yang berbeda di masing-masing distribusi OS, contohnya package-package berikut.
- Salah satu package web server
- Jika di Centos atau Redhat, nama package nya adalah httpd
- Jika di Debian atau Ubuntu, nama package nya adalah apache2
- Salah satu package DNS server
- Jika di Centos atau Redhat, nama package nya adalah bind & bind-utils
- Jika di Debian atau Ubuntu, nama package nya adalah bind9 & bind9utils
Maka dari itu, saya beralih ke Ansible untuk melakukan hal tersebut. Dengan Ansible saya bisa melakukan instalasi package sejenis secara bersamaan ke beberapa server Linux dengan distribusi yang berbeda-beda, walaupun nama packagenya tidak sama. Pada simulasi kali ini saya menggunakan 3 server dengan IP address sebagai berikut
- Server Master (Centos 7) : 10.10.10.4/24
- Server Target 1 (Ubuntu 16) : 10.10.10.5/24
- Server Target 2 (Centos 7) : 10.10.10.6/24
Berikut adalah langkah-langkah yang dilakukan untuk install package menggunakan ansible.
- Instalasi ansible pada server master dengan perintah berikut (Cukup dilakukan di sisi server master saja, karena Ansible merupakan tools yang agentless atau dalam kata lain tidak membutuhkan agent di sisi server child yang hendak dikonfigurasi)
-
# yum install ansible -y
- Edit file /etc/ansible/hosts lalu tambahkan baris berikut
-
target1 ansible_host=10.10.10.5 target2 ansible_host=10.10.10.6
- Dari server master, pastikan bisa SSH 6e server target 1 & 2 menggunakan user root
- Jika server master belum memiliki SSH key maka rekan-rekan bisa generate dengan perintah berikut. Namun jika SSH key sudah ada, maka langkah ini bisa di skip
-
# ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): (enter) Enter passphrase (empty for no passphrase): (enter) Enter same passphrase again: Your identification has been saved in /root/.ssh/key. Your public key has been saved in /root/.ssh/key.pub. The key fingerprint is: SHA256:2sz22XyFny/3ICUsxUEk6P/f4ThJf9w8yUA//SMn6pM root@mail.bawaslu.go.id The key's randomart image is: ........
- Konfigurasi SSH less pass dari master ke akun root server target 1 & 2 dengan perintah berikut
-
# ssh-copy-id root@10.10.10.5 # ssh-copy-id root@10.10.10.6
- Jalankan perintah berikut untuk memastikan server ansible master bisa SSH ke target 1 & 2 menggunakan user root
-
# ansible all -m ping --user root target1 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } target2 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" }
- Membuat dan masuk ke direktori baru khusus ansible dengan perintah berikut. Pada bagian ini sebenarnya bebas mau dilakukan atau tidak, namun saya pribadi biasanya memisahkan file-file ansible ke dalam 1 direktori khusus supaya lebih rapih
-
# mkdir ansible # cd ansible
- Membuat & edit file ansible untuk instalasi package di multiple Linux distribution. Ekstensi file yang digunakan adalah .yml, disini saya menggunakan nama install-packages.yml
- Menambahkan teks berikut pada file tersebut
-
- name: Install Packages Multiple OS hosts: all vars: packages_ubuntu: - name: apache2 - name: bind9 - name: bind9utils packages_centos: - name: epel-release - name: httpd - name: bind - name: bind-utils tasks: - name: Install Packages Ubuntu apt: name: "{{ item.name }}" state: present when: ansible_os_family == "Debian" loop: "{{ packages_ubuntu }}" - name: Install Packages Centos yum: name: "{{ item.name }}" state: present when: ansible_os_family == "RedHat" loop: "{{ packages_centos }}"
- File diatas saya isi dengan variable packages_ubuntu & packages_centos yang berisi nama-nama package pada sistem operasi Ubuntu & Centos
- Pada bagian parameter when saya isi sesuai dengan atribut OS family server-server target ansible. Atribut tersebut dapat didapatkan dengan perintah ansible berikut.
-
# ansible all -i inventory -m setup | grep ansible_os_family "ansible_os_family": "Debian", "ansible_os_family": "RedHat",
- Setelah membuat file konfigurasi ansible tersebut, instalasi package di server-server target bisa dilakukan secara sekaligus dari server ansible master dengan perintah berikut
-
# ansible-playbook install-packages.yml PLAY [Install Packages Multiple OS] ******************************* TASK [Gathering Facts] ******************************************** ok: [target1] ok: [target2] TASK [Install Packages Ubuntu] ************************************ changed: [target1] => (item={u'name': u'apache2'}) changed: [target1] => (item={u'name': u'bind9'}) changed: [target1] => (item={u'name': u'bind9utils'}) changed: [target2] => (item={u'name': u'apache2'}) changed: [target2] => (item={u'name': u'bind9'}) changed: [target2] => (item={u'name': u'bind9utils'}) TASK [Install Packages Centos] ************************************ changed: [target1] => (item={u'name': u'epel-release'}) changed: [target2] => (item={u'name': u'epel-release'}) changed: [target2] => (item={u'name': u'httpd'}) changed: [target1] => (item={u'name': u'httpd'}) changed: [target1] => (item={u'name': u'bind'}) changed: [target2] => (item={u'name': u'bind'}) changed: [target1] => (item={u'name': u'bind-utils'}) changed: [target2] => (item={u'name': u'bind-utils'}) PLAY RECAP ******************************************************* target1 : ok=2 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 target2 : ok=2 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
- Coba jalankan ulang perintah tersebut dan pastikan hasil pada bagian PLAY RECAP nya, ok=2, changed=0 & skipped=2
-
# ansible-playbook install-packages.yml PLAY RECAP ******************************************************* target1 : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 target2 : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0