mengenal dan belajar ansible pada linux

0
1169

halo sobat sekolahlinux, kali ini saya akan sedikit membahas tentang ansible, sebelum lebih jauh kita harus tau apa itu ansible, dan apa bedanya ansible dengan terraform, pada dasarnya kedua tool tersebut tidak dapat kita bandingkan karena beda peruntukan
ansible sendiri saat ini lebih banyak digunakan sebagai sebuah configuration management yang tujuannya untuk provisioning sebuah instance atau banyak instance agar instance tersebut dapat langsung digunakan dan berjalan tanpa kita harus config os dan applikasinya secara manual
sedangkan untuk terraform saya lebih suka menyebutnya sebagai service provisioner and infrastructure orchestrator, seperti membuat instance/vm loadbalaner, firewall, security group dll didalam sebuah provider cloud seperti aws, gcp dll
ok kembali ke judul dan mari kita langsung uji coba, pertama berikut ini gambaran layout file dari script ansible,

inventories/
|__production/
   |__hosts
   |__group_vars/
      |__group1.yml
      |__group2/
         |__main.yml
   |__host_vars/
      |__hostname1.yml
      |__hostname2/
         |__main.yml
|__staging/
   |__hosts
   |__group_vars/
      |__group1.yml
      |__group2/
         |__main.yml
   |__host_vars/
      |__stagehost1.yml
      |__stagehost2/
         |__main.yml

webserver.yml
dbserver.yml
fileserver.yml

roles/
|__common/
   |__tasks/
      |__main.yml
   |__handlers/
      |__main.yml
   |__templates/
      |__ntp.conf.j2
   |__files/
      |__bar.txt
      |__foo.sh
   |__vars/
      |__main.yml
|__nginx_webserver/
   |__tasks/
      |__main.yml
   |__handlers/
      |__main.yml
   |__templates/
      |__ntp.conf.j2
   |__files/
      |__bar.txt
      |__foo.sh
   |__vars/
      |__main.yml

didalam ansible kita akan mengenal namanya inventories, playbook, roles, tasks, variable, files, templates, handlers, tags, ansible-vault

inventories:

adalah sekumpulan host-host yang dikategorikan kedalam environment, misal host yang ada di environment production & staging, nah didalam masing-masing environment tersebut juga ada variable masing-masing yaitu group_vars dan host_vars

playbook:

berisi bahasa orchestration ansible yang didalamnya terdapat rule-rule seperti host, role, variable dan task, playbook adalah penyatuan dari sekumpulkan role, host, variable dll yang akan di eksekusi untuk provisioning suatu instance/vm

roles:

berisi sekumpulan task-task yang nantinya digunakan/dipanggil didalam sebuah ansible playbook

tasks:

berisi perintah-perintah untuk provisioning suatu vm, misal task install nginx, task mengganti hostname dll

variable:

sebuah kata yang memiliki arti berbeda dan juga nilai berbeda & bervariasi, tergantung dari seseorang mau memberikan value apa didalam variable tersebut

files:

folder files biasanya berisi file-file yang biasanya nanti akan di transfer ke vm/instance tujuan, misal file-config dll

templates:

folder templates biasanya berisi file-file yang mirip seperti di folder files, cuman bedanya di folder templates setiap file berekstensi .j2 atau disebut jinja template, didalam file j2 ini bisa kita sisipi dengan variable-variable sehingga lebih flexible juga

handlers:

berisi sekumpulan task, bukan task utama tapi task notify yang digunakan untuk melakukan perintah start, restart ataupun stop pada suatu service

tags:

adalah sebuah code/tanda untuk setiap task, misal task1 akan diberi tag web, tags digunakan untuk menjalankan spesifik task yang ada didalam sebuah playbook, jadi tidak semua task dijalankan

ansible-vault:

ansible vault adalah sebuah feature untuk mengencrypt value sebuah variable yang bersifat sensitif, contohnya seperti password, username ataupun hal-hal sensitif lainnyaani

Memulai Ansible

siapkan 3 buah vm, detailnya seperti dibawah (pastikan pubkey dari privkey ansible server sudah tertanam di semua server ansible target)

  • 192.168.10.1   = ansible server
  • 192.168.10.10 = ansible target1
  • 192.168.10.20 = ansible target2

pada tutorial kali ini susunan atau layout filenya saya rubah menjadi sederhana seperti dibawah ini

|-- inventories
|   `-- production
|       |-- group_vars
|       |   |-- all.yml
|       |   `-- nginx.yml
|       `-- hosts
|-- roles
|   |-- common
|   |   `-- tasks
|   |       `-- main.yml
|   `-- web-server
|       |-- handlers
|       |   `-- main.yml
|       `-- tasks
|           `-- main.yml
|-- templates
|   `-- default.j2
|-- vault_pass.txt
|-- vault_vars.yml
`-- webserver.yml

pada layout diatas saya mempunyai playbook file ./webserver.yml yang isinya seperti dibawah ini

---
- name: install web server nginx
  hosts: nginx
  become: yes
  vars_files:
    - vault_vars.yml
  roles:
    - common
    - web-server

lalu pada file ./vault_pass.txt isinya seperti dibawah ini

12345

lalu pada file ./vault_vars.txt sebelum di encrypt isinya seperti dibawah ini

server_name:
  default: sekolahlinux.com

lalu pada file ./templates/default.j2 isinya seperti dibawah ini

server {
	listen {{ nginx_port }} ;
	listen [::]:{{ nginx_port }} ;
	server_name {{ server_name.default }};

	root {{ web_dir }};
	index index.html index.htm index.nginx-debian.html;

	location / {
		try_files $uri $uri/ =404;
	}
}

lalu pada file ./roles/common/tasks/main.yml isinya seperti dibawah ini

---
- name: hostname set
  hostname: name={{ inventory_hostname }}
  tags: 'hostname'

- name: generate /etc/hosts from inventory
  lineinfile:
    dest: /etc/hosts
    regexp: '.*{{ item }}$'
    line: '{{ hostvars[item].ansible_host }}  {{ hostvars[item].inventory_hostname }}'
    state: present
  when: hostvars[item].inventory_hostname is defined
  with_items: '{{ groups.nginx }}'
  tags: 'hosts'

- name: Make sure we have a 'wheel' group
  group:
    name: wheel
    state: present
  when: ansible_os_family == "RedHat"

- name: make sure we have a "sudo" group
  group:
    name: sudo
    state: present
  when: ansible_os_family == "Debian"

- name: Allow 'wheel' group to have passwordless sudo
  lineinfile:
    dest: /etc/sudoers
    state: present
    regexp: '^%wheel'
    line: '%wheel ALL=(ALL) NOPASSWD: ALL'
    validate: 'visudo -cf %s'
  when: ansible_os_family == "RedHat"

- name: allow "sudo" group to have passwordless sudo
  lineinfile:
    dest: /etc/sudoers
    state: present
    regexp: "^%sudo"
    line: "%sudo ALL=(ALL) NOPASSWD: ALL"
    validate: "visudo -cf %s"
  when: ansible_os_family == "Debian"

- name: adduser for redhat family
  user:
    name: "{{ item }}"
    groups: wheel
    shell: /bin/bash
    append: yes
  with_items:
    - akbar
    - alam
    - abil
  when: ansible_os_family == "RedHat"
  tags: ["add_user"]

- name: adduser for debian family
  user:
    name: "{{ item }}"
    groups: sudo
    shell: /bin/bash
    append: yes
  with_items:
    - akbar
    - alam
    - abil
  when: ansible_os_family == "Debian"
  tags: ["add_user"]

- name: set authorized key for user
  authorized_key:
    user: "{{ item.name }}"
    state: present
    key: "{{ item.pubkey }}"
  with_items:
    - {name: akbar, pubkey: ssh-rsa AAAAB3NzaC1yc2EBBAADAQABAAABAQCqbcDBdpmWc25lZtCTdUGJJY7t7DDgauFLarx3G0S1DqvaVeRSqo74GA5SPwSd8TVrY6Vf59KsLXe+BkzNSU2o1KWmV9YBXq1Vy/fRkj9uTm33iNtKbHzSO48atstPLOf+DjPKJY+65n7YmK4b0bl55vTuGg1WfOAyyfKqD2YPHXdI27aYB+0oieyxm+GGRHYvXv/dv9wpZ+z+BPFOcLaMYaWrfLprNltJ+9jWt/FPheWajACPzi8BRrF5egmSQPgWZvDqqXBGMcklp3NC5DepjF5D5CBBV/wlvbCTyRTxx+Vm1YCDi/4wjA/2rrAI2hF8FwFZAPp6xVz9p4ZXfY5X root@ubuntu}
    - {name: alam, pubkey: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqbcDBdpmWc25lZtCTdUGJJY7t7DDgauFLarx3G0S1DqvaVeRSqo74GA5SPwSd8TVrY6Vf59KsLXe+BkzNSU2o1KWmV9YBXq1Vy/fRkj9uTm33iNtKbHzSO48atstPLOf+DjPKJY+65n7YmK4b0bl55vTuGg1WfOAyyfKqD2YPHXdI27aYB+0oieyxm+GGRHYvXv/dv9wpZ+z+BPFOcLaMYaWrfLprNltJ+9jWt/FPheWajACPzi8BRrF5egmSQPgWZvDqqXBGMcklp3NC5DepjF5D5CBBV/wlvbCTyRTxx+Vm1YCDi/4wjA/2rrAI2hF8FwFZAPp6xVz9p4ZXfY5X root@ubuntu}
    - {name: abil, pubkey: ssh-rsa AAAAB3NzaC1yc2ECCAADAQABAAABAQCqbcDBdpmWc25lZtCTdUGJJY7t7DDgauFLarx3G0S1DqvaVeRSqo74GA5SPwSd8TVrY6Vf59KsLXe+BkzNSU2o1KWmV9YBXq1Vy/fRkj9uTm33iNtKbHzSO48atstPLOf+DjPKJY+65n7YmK4b0bl55vTuGg1WfOAyyfKqD2YPHXdI27aYB+0oieyxm+GGRHYvXv/dv9wpZ+z+BPFOcLaMYaWrfLprNltJ+9jWt/FPheWajACPzi8BRrF5egmSQPgWZvDqqXBGMcklp3NC5DepjF5D5CBBV/wlvbCTyRTxx+Vm1YCDi/4wjA/2rrAI2hF8FwFZAPp6xVz9p4ZXfY5X root@ubuntu}
  tags: ["add_pubkey"]

lalu pada file ./roles/web-server/tasks/main.yml isinya seperti dibawah ini

---
- name: install nginx ubuntu
  apt:
    name: nginx
    state: present
    update_cache: yes
  tags: install_nginx

- name: change config nginx
  template:
    src: default.j2
    dest: /etc/nginx/sites-available/default
  tags: config_nginx
  notify: "restart nginx"

lalu pada file ./roles/web-server/handlers/main.yml isinya seperti dibawah ini

- name: restart nginx
  service: name=nginx state=restarted

lalu pada file ./inventories/production/hosts isinya seperti dibawah ini

[webserver:vars]
ansible_ssh_private_key_file=/root/.ssh/id_rsa
ansible_user=root
ansible_port=22

[webserver:children]
nginx

[nginx]
nginx-server1 ansible_host=192.168.10.10
nginx-server2 ansible_host=192.168.10.20

lalu pada file ./inventories/production/group_vars/all.yml isinya seperti dibawah ini

---
nginx_port: 9090

lalu pada file ./inventories/production/group_vars/nginx.yml isinya seperti dibawah ini

---
web_dir: /var/www/html

pertama kita harus mengencrypt file vault_vars.yml dengan perintah dibawah ini tujuannya adalah untuk encrypt value-value sensitif pada ansible

ansible-vault encrypt --vault-password-file vault_pass.txt vault_vars.yml

lalu untuk menjalankannya bisa dengan perintah dibawah ini

ansible-playbook -i inventories/production/hosts --vault-password-file vault_pass.txt webserver.yml

dan outputnya akan seperti dibawah ini (beberapa task untuk akan diskip karena host tujuan adalah ubuntu/debian)

root@ubuntu:~/ansible# ansible-playbook -i inventories/production/hosts --vault-password-file vault_pass.txt webserver.yml

PLAY [install web server nginx] ************************************************

TASK [setup] *******************************************************************
ok: [nginx-server2]
ok: [nginx-server1]

TASK [common : hostname set] ***************************************************
ok: [nginx-server1]
ok: [nginx-server2]

TASK [common : generate /etc/hosts from inventory] *****************************
ok: [nginx-server2] => (item=nginx-server1)
ok: [nginx-server2] => (item=nginx-server2)
ok: [nginx-server1] => (item=nginx-server1)
ok: [nginx-server1] => (item=nginx-server2)

TASK [common : Make sure we have a 'wheel' group] ******************************
skipping: [nginx-server1]
skipping: [nginx-server2]

TASK [common : make sure we have a "sudo" group] *******************************
ok: [nginx-server2]
ok: [nginx-server1]

TASK [common : Allow 'wheel' group to have passwordless sudo] ******************
skipping: [nginx-server2]
skipping: [nginx-server1]

TASK [common : allow "sudo" group to have passwordless sudo] *******************
ok: [nginx-server2]
ok: [nginx-server1]

TASK [common : adduser for redhat family] **************************************
skipping: [nginx-server1] => (item=akbar)
skipping: [nginx-server1] => (item=alam)
skipping: [nginx-server1] => (item=abil)
skipping: [nginx-server2] => (item=akbar)
skipping: [nginx-server2] => (item=alam)
skipping: [nginx-server2] => (item=abil)

TASK [common : adduser for debian family] **************************************
ok: [nginx-server2] => (item=akbar)
ok: [nginx-server2] => (item=alam)
ok: [nginx-server2] => (item=abil)
ok: [nginx-server1] => (item=akbar)
ok: [nginx-server1] => (item=alam)
ok: [nginx-server1] => (item=abil)

TASK [common : set authorized key for user] ************************************
ok: [nginx-server2] => (item={u'pubkey': u'ssh-rsa AAAAB3NzaC1yc2EBBAADAQABAAABAQCqbcDBdpmWc25lZtCTdUGJJY7t7DDgauFLarx3G0S1DqvaVeRSqo74GA5SPwSd8TVrY6Vf59KsLXe+BkzNSU2o1KWmV9YBXq1Vy/fRkj9uTm33iNtKbHzSO48atstPLOf+DjPKJY+65n7YmK4b0bl55vTuGg1WfOAyyfKqD2YPHXdI27aYB+0oieyxm+GGRHYvXv/dv9wpZ+z+BPFOcLaMYaWrfLprNltJ+9jWt/FPheWajACPzi8BRrF5egmSQPgWZvDqqXBGMcklp3NC5DepjF5D5CBBV/wlvbCTyRTxx+Vm1YCDi/4wjA/2rrAI2hF8FwFZAPp6xVz9p4ZXfY5X root@ubuntu', u'name': u'akbar'})
ok: [nginx-server2] => (item={u'pubkey': u'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqbcDBdpmWc25lZtCTdUGJJY7t7DDgauFLarx3G0S1DqvaVeRSqo74GA5SPwSd8TVrY6Vf59KsLXe+BkzNSU2o1KWmV9YBXq1Vy/fRkj9uTm33iNtKbHzSO48atstPLOf+DjPKJY+65n7YmK4b0bl55vTuGg1WfOAyyfKqD2YPHXdI27aYB+0oieyxm+GGRHYvXv/dv9wpZ+z+BPFOcLaMYaWrfLprNltJ+9jWt/FPheWajACPzi8BRrF5egmSQPgWZvDqqXBGMcklp3NC5DepjF5D5CBBV/wlvbCTyRTxx+Vm1YCDi/4wjA/2rrAI2hF8FwFZAPp6xVz9p4ZXfY5X root@ubuntu', u'name': u'alam'})
ok: [nginx-server2] => (item={u'pubkey': u'ssh-rsa AAAAB3NzaC1yc2ECCAADAQABAAABAQCqbcDBdpmWc25lZtCTdUGJJY7t7DDgauFLarx3G0S1DqvaVeRSqo74GA5SPwSd8TVrY6Vf59KsLXe+BkzNSU2o1KWmV9YBXq1Vy/fRkj9uTm33iNtKbHzSO48atstPLOf+DjPKJY+65n7YmK4b0bl55vTuGg1WfOAyyfKqD2YPHXdI27aYB+0oieyxm+GGRHYvXv/dv9wpZ+z+BPFOcLaMYaWrfLprNltJ+9jWt/FPheWajACPzi8BRrF5egmSQPgWZvDqqXBGMcklp3NC5DepjF5D5CBBV/wlvbCTyRTxx+Vm1YCDi/4wjA/2rrAI2hF8FwFZAPp6xVz9p4ZXfY5X root@ubuntu', u'name': u'abil'})
ok: [nginx-server1] => (item={u'pubkey': u'ssh-rsa AAAAB3NzaC1yc2EBBAADAQABAAABAQCqbcDBdpmWc25lZtCTdUGJJY7t7DDgauFLarx3G0S1DqvaVeRSqo74GA5SPwSd8TVrY6Vf59KsLXe+BkzNSU2o1KWmV9YBXq1Vy/fRkj9uTm33iNtKbHzSO48atstPLOf+DjPKJY+65n7YmK4b0bl55vTuGg1WfOAyyfKqD2YPHXdI27aYB+0oieyxm+GGRHYvXv/dv9wpZ+z+BPFOcLaMYaWrfLprNltJ+9jWt/FPheWajACPzi8BRrF5egmSQPgWZvDqqXBGMcklp3NC5DepjF5D5CBBV/wlvbCTyRTxx+Vm1YCDi/4wjA/2rrAI2hF8FwFZAPp6xVz9p4ZXfY5X root@ubuntu', u'name': u'akbar'})
ok: [nginx-server1] => (item={u'pubkey': u'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqbcDBdpmWc25lZtCTdUGJJY7t7DDgauFLarx3G0S1DqvaVeRSqo74GA5SPwSd8TVrY6Vf59KsLXe+BkzNSU2o1KWmV9YBXq1Vy/fRkj9uTm33iNtKbHzSO48atstPLOf+DjPKJY+65n7YmK4b0bl55vTuGg1WfOAyyfKqD2YPHXdI27aYB+0oieyxm+GGRHYvXv/dv9wpZ+z+BPFOcLaMYaWrfLprNltJ+9jWt/FPheWajACPzi8BRrF5egmSQPgWZvDqqXBGMcklp3NC5DepjF5D5CBBV/wlvbCTyRTxx+Vm1YCDi/4wjA/2rrAI2hF8FwFZAPp6xVz9p4ZXfY5X root@ubuntu', u'name': u'alam'})
ok: [nginx-server1] => (item={u'pubkey': u'ssh-rsa AAAAB3NzaC1yc2ECCAADAQABAAABAQCqbcDBdpmWc25lZtCTdUGJJY7t7DDgauFLarx3G0S1DqvaVeRSqo74GA5SPwSd8TVrY6Vf59KsLXe+BkzNSU2o1KWmV9YBXq1Vy/fRkj9uTm33iNtKbHzSO48atstPLOf+DjPKJY+65n7YmK4b0bl55vTuGg1WfOAyyfKqD2YPHXdI27aYB+0oieyxm+GGRHYvXv/dv9wpZ+z+BPFOcLaMYaWrfLprNltJ+9jWt/FPheWajACPzi8BRrF5egmSQPgWZvDqqXBGMcklp3NC5DepjF5D5CBBV/wlvbCTyRTxx+Vm1YCDi/4wjA/2rrAI2hF8FwFZAPp6xVz9p4ZXfY5X root@ubuntu', u'name': u'abil'})

TASK [web-server : install nginx ubuntu] ***************************************
ok: [nginx-server2]
ok: [nginx-server1]

TASK [web-server : change config nginx] ****************************************
ok: [nginx-server1]
ok: [nginx-server2]

PLAY RECAP *********************************************************************
nginx-server1              : ok=9    changed=0    unreachable=0    failed=0
nginx-server2              : ok=9    changed=0    unreachable=0    failed=0

pada beberapa case diperlukan password ketika akan melakukan sudo dikarenakan os yang terinstall belum menerapkan passwordless pada sudo/wheel di sudoers mereka, maka jangan lupa tambahkan variable ini pada saat melakukan perintah ansible-playbook, tidak disarankan meletakan password sebagai plain text, jangan lupa di encrypt mengunakan ansible vault

ansible-playbook webserver.yml -i inventories/production/hosts --vault-password-file vault_pass.txt --extra-vars "ansible_become_pass=YourSudoPassword"

sekian tutorial ansible kali ini semoga bermanfaat, jika ada penjelasan yang kurang detail silahkan tanyakan langsung dikolom komentar ya 🙂