วิธีสร้างบทละครและ Playbooks แบบ Ansible - ตอนที่ 5
ใน ส่วนที่ 5 ของซีรีส์ Ansible นี้ เราจะอธิบายวิธีสร้าง Ansible Plays และ Playbooks โดยใช้โมดูล Ansible
Ansible มาพร้อมกับสคริปต์แบบสแตนด์อโลนที่เรียกว่า โมดูล ที่ใช้ใน คู่มือการเล่น สำหรับการดำเนินงานพิเศษบนโหนดระยะไกล
โมดูลมีประโยชน์ในการทำงานอัตโนมัติ เช่น การจัดการแพ็กเกจ การเก็บถาวร และการคัดลอกไฟล์ และอื่นๆ อีกมากมาย ช่วยให้คุณสามารถปรับแต่งไฟล์การกำหนดค่าและจัดการอุปกรณ์ต่างๆ เช่น เราเตอร์ สวิตช์ โหลดบาลานเซอร์ ไฟร์วอลล์ และโฮสต์ของอุปกรณ์อื่นๆ
วัตถุประสงค์ของหัวข้อย่อยนี้คือเพื่อให้คุณเห็นภาพรวมของงานต่างๆ ที่สามารถทำได้โดย โมดูล Ansible:
การจัดการแพ็คเกจใน Linux
การจัดการแพ็คเกจเป็นหนึ่งในงานที่สำคัญที่สุดและบ่อยครั้งที่สุดที่ผู้ดูแลระบบดำเนินการ Ansible มาพร้อมกับโมดูลที่ช่วยให้คุณดำเนินงานการจัดการแพ็คเกจทั้งในระบบที่ใช้ RedHat และ Debian
พวกมันค่อนข้างเดาง่าย มี โมดูล apt สำหรับการจัดการแพ็คเกจ APT สำหรับ Debian, โมดูล yum เก่าสำหรับการจัดการแพ็คเกจ YUM และ โมดูล dnf ที่เกี่ยวข้องกับการกระจาย RHEL ที่ใหม่กว่า .
ด้านล่างนี้เป็นตัวอย่างเล็กๆ น้อยๆ ของวิธีการใช้โมดูลใน Playbook:
ตัวอย่างที่ 1: การติดตั้ง Apache Webserver บน RHEL 8
---
- name: install Apache webserver
hosts: webservers
tasks:
- name: install httpd
dnf:
name: httpd
State: latest
ตัวอย่างที่ 2: การติดตั้ง Apache Webserver บน Debian 10
---
- name: install Apache webserver
hosts: databases
tasks:
- name: install Apache webserver
apt:
name: apache2
State: latest
โมดูลการบริการ
โมดูลบริการช่วยให้ผู้ดูแลระบบสามารถเริ่ม หยุด อัปเดต อัปเกรด และโหลดบริการบนระบบได้
ตัวอย่างที่ 1: การเริ่มต้น Apache Webserver
---
- name: Start service httpd, if not started
service:
name: httpd
state: started
ตัวอย่างที่ 2: การหยุด Apache Webserver
---
- name: Stop service httpd
service:
name: httpd
state: stopped
ตัวอย่างที่ 3: การรีสตาร์ทอินเทอร์เฟซเครือข่าย enp2s0
---
- name: Restart network service for interface eth0
service:
name: network
state: restarted
args: enp2s0
โมดูลการคัดลอก
ตามชื่อที่แนะนำ โมดูลการคัดลอกจะคัดลอกไฟล์จากตำแหน่งหนึ่งบนเครื่องระยะไกลไปยังตำแหน่งอื่นบนเครื่องเดียวกัน
ตัวอย่างที่ 1: การคัดลอกไฟล์จาก Local ไปยัง Remote Linux
---
- name: Copy file with owner and permissions
copy:
src: /etc/files/tecmint.conf
dest: /srv/tecmint.conf
owner: tecmint
group: tecmint
mode: '0644'
Playbook คัดลอกไฟล์กำหนดค่า tecmint.conf จากไดเรกทอรี /etc/files/ ไปยังไดเรกทอรี /srv/ เป็น tecmint ผู้ใช้ที่มีสิทธิ์ 0644
การอนุญาตสามารถแสดงได้โดยใช้การแสดงสัญลักษณ์ตามที่แสดงในบรรทัดสุดท้าย
ตัวอย่างที่ 2: การคัดลอกไฟล์จาก Local ไปยัง Remote Linux
---
- name: Copy file with owner and permissions
copy:
src: /etc/files/tecmint.conf
dest: /srv/tecmint.conf
owner: tecmint
group: tecmint
mode: u=rw, g=r, o=r
สิทธิ์ในตัวอย่างก่อนหน้านี้สามารถแสดงตามที่แสดงในบรรทัดสุดท้าย ผู้ใช้ได้รับสิทธิ์ อ่าน และ เขียน กลุ่มได้รับมอบหมายสิทธิ์ในการเขียน และส่วนที่เหลือของ โลกได้รับมอบหมายสิทธิ์ในการอ่าน
โมดูลไฟล์
โมดูลไฟล์ใช้เพื่อดำเนินการกับไฟล์หลายอย่าง รวมถึงการสร้างไฟล์และไดเร็กทอรี การกำหนดสิทธิ์ของไฟล์ และการตั้งค่าลิงก์สัญลักษณ์
ตัวอย่างที่ 1: ดำเนินการอนุญาตไฟล์ Linux
---
- name: Change file ownership, group, and permissions
file:
path: /etc/tecmint.conf
owner: tecmint
group: tecmint
mode: '0644'
การเล่นข้างต้นจะสร้างไฟล์ชื่อ tecmint.conf ในไดเรกทอรี /etc โดยตั้งค่าสิทธิ์เป็น 0644
ตัวอย่างที่ 2: ลบไฟล์ Linux
---
- name: Remove file (delete file)
file:
path: /etc/tecmint.conf
state: absent
การดำเนินการนี้จะลบหรือลบไฟล์ tecmint.conf
ตัวอย่างที่ 3: สร้างไดเร็กทอรี
---
- name: create a directory if it doesn’t exist
file:
path: /etc/mydirectory
State: directory
mode: '0777'
สิ่งนี้จะสร้างไดเรกทอรีในการตั้งค่าไดเรกทอรี /etc เป็น 0777
ตัวอย่างที่ 4: ลบไดเรกทอรีแบบวนซ้ำ
---
- name: Recursively deleting a directory
file:
path: /etc/tecmint.conf
state: absent
การเล่นข้างต้นจะลบไดเร็กทอรีซ้ำ
โมดูล Lineinfile
โมดูล lineinfile มีประโยชน์เมื่อคุณต้องการเปลี่ยนบรรทัดเดียวในไฟล์ สามารถแทนที่เส้นที่มีอยู่ได้
ตัวอย่างที่ 1: จัดการไฟล์ใน Linux
---
- name: Ensure SELinux is set to enforcing mode
lineinfile:
path: /etc/selinux/config
regexp: '^SELINUX='
line: SELINUX=disabled
การเล่นด้านบนตั้งค่า SELINUX เป็น ปิดใช้งาน
SELINUX=disabled
ตัวอย่างที่ 2: แก้ไขไฟล์ใน Linux
---
- name: Add a line to a file if the file does not exist, without passing regexp
lineinfile:
path: /etc/hosts
line: 10.200.50.51 linux-console.net
create: yes
ซึ่งจะเป็นการเพิ่มรายการ 10.200.50.51 linux-console.net ไปยังไฟล์ /etc/hosts
โมดูลเอกสารเก่า
โมดูล ไฟล์เก็บถาวร ใช้สำหรับการสร้างไฟล์เก็บถาวรแบบบีบอัดของไฟล์เดียวหรือหลายไฟล์ โดยถือว่าแหล่งที่มาของการบีบอัดนั้นมีอยู่บนปลายทางเป้าหมาย หลังจากเก็บถาวร ไฟล์ต้นฉบับสามารถลบหรือลบออกได้ในภายหลังโดยใช้คำสั่ง remove=True
ตัวอย่างที่ 1: สร้างไฟล์เก็บถาวร
- name: Compress directory /path/to/tecmint_dir/ into /path/to/tecmint.tgz
archive:
path: /path/to/tecmint_dir
dest: /path/to/tecmint.tgz
This compresses the /path/to/tecmint_dir directory to /path/to/tecmint.tgz
ตัวอย่างที่ 2: สร้างไฟล์เก็บถาวรและลบออก
- name: Compress regular file /path/to/tecmint into /path/to/foo.gz and remove it
archive:
path: /path/to/tecmint
dest: /path/to/tecmint.tgz
remove: yes
ในการเล่นข้างต้น ไฟล์ต้นฉบับ /path/to/tecmint จะถูกลบหลังจากการเก็บถาวรเสร็จสมบูรณ์
ตัวอย่างที่ 3: สร้างไฟล์เก็บถาวร
- name: Create a bz2 archive of /path/to/tecmint
archive:
path: /path/to/tecmint
format: bz2
ซึ่งจะสร้างไฟล์บีบอัดในรูปแบบ bz2 จากไฟล์ /path/to/tecmint
โมดูล Git
โมดูลจะจัดการการชำระเงิน git ของที่เก็บซอฟต์แวร์
ตัวอย่างที่ 1: ตรวจสอบที่เก็บ Git
- git:
repo: 'https://foosball.example.org/path/to/repo.git'
dest: /srv/checkout
version: release-0.22
โมดูลคำสั่ง
โมดูล command หนึ่งในโมดูลที่ใช้บ่อยที่สุด ใช้ชื่อคำสั่งและตามด้วยรายการอาร์กิวเมนต์ในภายหลัง คำสั่งนี้เป็นการส่งผ่านแบบเดียวกับที่คุณพิมพ์ในเชลล์ Linux
ตัวอย่างที่ 1: เรียกใช้คำสั่ง
- name: Executing a command using the command module
command: cat helloworld.txt
ตัวอย่างที่ 2: ตรวจสอบเวลาทำงานของ Remote Linux
---
- name: Check the remote host uptime
hosts: servers
tasks:
- name: Execute the Uptime command over Command module
register: uptimeoutput
command: "uptime"
- debug:
var: uptimeoutput.stdout_lines
โมดูลคำสั่งดึงข้อมูลสถานะการออนไลน์ของเซิร์ฟเวอร์ระยะไกล
ตัวแปรเพื่อดึงผลลัพธ์ของการรันคำสั่ง
โดยปกติแล้ว Playbooks Ansible ใช้เพื่อดำเนินงานบนโฮสต์ที่ได้รับการจัดการโดยไม่แสดงเอาต์พุตบนบรรทัดคำสั่ง อย่างไรก็ตาม มีบางกรณีที่คุณอาจต้องจับภาพผลลัพธ์หรือผลลัพธ์ ในส่วนนี้ เราจะอธิบายวิธีการบันทึกผลลัพธ์ของ Playbook ในตัวแปรและแสดงในภายหลัง
รีจิสเตอร์แบบ ansible ใช้สำหรับจับเอาต์พุตของงานและบันทึกเป็นตัวแปร หลังจากนั้นตัวแปรจะมี stdout ของงาน
ตัวอย่างเช่น สมมติว่าคุณต้องการตรวจสอบการใช้งานดิสก์ของโหนดที่ได้รับการจัดการในไดเรกทอรีรากที่เกี่ยวข้องโดยใช้คำสั่ง df -Th /
คุณจะใช้โมดูล 'command'
เพื่อกำหนดคำสั่งและ 'register'
เพื่อบันทึกเอาต์พุต std ในตัวแปร
ในการแสดงคำสั่ง คุณจะใช้โมดูล 'debug'
ควบคู่ไปกับค่าส่งคืน stdout
---
- hosts: all
become: yes
tasks:
- name: Execute /boot usage on Hosts
command: 'df -Th /'
register: df
- debug: var=df.stdout
ตอนนี้เรามาเริ่ม Playbook กันดีกว่า ในกรณีนี้ เราได้ตั้งชื่อ Playbook ของเราว่า check_disk_space.yml
ansible-playbook check_disk_space.yml
อย่างที่คุณเห็น ผลลัพธ์ที่ได้จะสับสนวุ่นวายและทำให้ยากต่อการติดตาม
หากต้องการจัดแนวเอาต์พุตและทำให้อ่านง่ายขึ้น ให้แทนที่ค่าที่ส่งคืน stdout ด้วย stdout_lines
---
- hosts: all
become: yes
tasks:
- name: Execute /boot usage on Hosts
command: 'df -Th /'
register: df
- debug: var=df.stdout_lines
ใช้เงื่อนไขเพื่อควบคุมการดำเนินการเล่น
เช่นเดียวกับในภาษาการเขียนโปรแกรม คำสั่งแบบมีเงื่อนไข จะถูกใช้เมื่อผลลัพธ์ที่เป็นไปได้มากกว่าหนึ่งรายการ มาดูคำสั่งเงื่อนไขที่ใช้กันทั่วไปบางส่วนใน Playbooks ของ Ansible กัน
เมื่อมีคำสั่ง
บางครั้งคุณอาจต้องการทำงานบนโหนดใดโหนดหนึ่ง ไม่ใช่โหนดอื่น คำสั่งแบบมีเงื่อนไข 'when'
นั้นค่อนข้างง่ายต่อการใช้งานและนำไปใช้ใน Playbook เมื่อใช้ส่วนคำสั่ง 'when'
เพียงประกาศเงื่อนไขที่อยู่ติดกับส่วนคำสั่งดังที่แสดง:
when: condition
เมื่อตรงตามเงื่อนไข งานจะถูกดำเนินการบนระบบรีโมต
ลองดูตัวอย่างบางส่วน:
ตัวอย่างที่ 1: การใช้ When Operator
---
- hosts: all
tasks:
- name: Install Nginx on Debian
apt: name=nginx state=present
when: ansible_os_family == “Debian”
การเล่นข้างต้นจะติดตั้งเว็บเซิร์ฟเวอร์ Nginx บนโฮสต์ที่ใช้ตระกูล Distros ของ Debian
คุณยังสามารถใช้ตัวดำเนินการ OR
และ AND
ควบคู่ไปกับคำสั่ง when แบบมีเงื่อนไข
ตัวอย่างที่ 2: การใช้ AND Operator กับ When
---
- hosts: all
tasks:
- name: Install Nginx on Debian
apt: name=nginx state=present
when: ansible_os_family == “Debian” and
ansible_distribution_version == “18.04”
เมื่อใช้ตัวดำเนินการ AND
จะต้องตอบสนองทั้งสองคำสั่งจึงจะสามารถดำเนินการได้
การเล่นด้านบนจะติดตั้ง Nginx บนโหนดที่ใช้ระบบปฏิบัติการตระกูล Debian ซึ่งเป็นเวอร์ชัน 18.04 แน่นอนว่านี่คือ Ubuntu 18.04
ตัวอย่างที่ 3: การใช้หรือตัวดำเนินการกับเมื่อใด
ด้วยตัวดำเนินการ OR
งานจะถูกดำเนินการหากตรงตามเงื่อนไขข้อใดข้อหนึ่ง
---
- hosts: all
tasks:
- name: Install Nginx on Debian
apt: name=nginx state=present
when: ansible_os_family == “Debian” or
Ansible_os_family == “SUSE”
การเล่นด้านบนจะติดตั้งเว็บเซิร์ฟเวอร์ Nginx บนระบบปฏิบัติการตระกูล Debian หรือ SUSE หรือทั้งสองอย่าง
หมายเหตุ: ตรวจสอบให้แน่ใจว่าใช้เครื่องหมายเท่ากับคู่ ==
เมื่อทดสอบเงื่อนไข
เงื่อนไขในลูป
Conditionals ยังสามารถนำมาใช้ในการวนซ้ำได้ สมมติว่าคุณมีรายการแพ็คเกจหลายรายการที่ต้องติดตั้งบนโหนดระยะไกล
ใน Playbook ด้านล่าง เรามีอาร์เรย์ชื่อ แพ็คเกจ ซึ่งมีรายการแพ็คเกจที่ต้องติดตั้ง งานเหล่านี้จะดำเนินการทีละงานหากตั้งค่าส่วนคำสั่ง required เป็น True
---
- name: Install Software packages
hosts: all
vars:
packages:
• name: nginx
required: True
• name: mysql
required: True
• name: apache
required: False
tasks:
• name: Install “{{ item.name }}”on Debian
apt:
name: “{{ item.name }}”
state: present
When: item.required == True
loop: “{{ packages }}”
กำหนดค่าการจัดการข้อผิดพลาด
บางครั้ง งานล้มเหลวเมื่อเรียกใช้ playbooks สมมติว่าคุณกำลังใช้งาน 5 งานบนเซิร์ฟเวอร์ 3 เครื่องดังที่แสดงใน Playbook ด้านล่าง หากเกิดข้อผิดพลาดกับงานที่ 3 (การเริ่มต้น MySQL) บนเซิร์ฟเวอร์ 2 Ansible จะหยุดดำเนินงานที่เหลือบนเซิร์ฟเวอร์ 2 และพยายามทำงานที่เหลือให้เสร็จสิ้นบนเซิร์ฟเวอร์ที่เหลือ
---
- name: Install Software packages
hosts: server1, server2, server3
tasks:
- name: Install dependencies
<< some code >>
- name: Install MySQL database
<< some code >>
- name: Start MySQL
<< some code >>
- name: Install Nginx
<< some code >>
- name: Start Nginx
<< some code >>
หากคุณต้องการความสอดคล้องในการดำเนินการ Playbook เช่น หยุดการดำเนินการ Playbook หากเซิร์ฟเวอร์ตัวใดตัวหนึ่งล้มเหลว ให้เพิ่มตัวเลือก
---
- name: Install Software packages
hosts: server1, server2, server3
any_errors_fatal: true
tasks:
ด้วยวิธีนี้ หากงานหนึ่งล้มเหลวบนเซิร์ฟเวอร์เดียว Ansible จะหยุดการดำเนินการ Playbook ทั้งหมดบนเซิร์ฟเวอร์ทั้งหมดและออก
หากคุณต้องการให้ Playbook ละเว้นข้อผิดพลาดและดำเนินการชุดงานที่เหลือต่อไป ให้ใช้ตัวเลือก ignore_errors: True
---
- name: Install Software packages
hosts: server1, server2, server3
tasks:
- name: Install dependencies
<< some code >>
ignore_errors: True
สร้าง Playbooks เพื่อกำหนดค่าระบบให้เป็นสถานะที่ระบุ
ในส่วนนี้ เราจะดูตัวเลือกเพิ่มเติมบางอย่างที่พร้อมใช้งานเมื่อเรียกใช้ Playbook
เริ่มต้นด้วยโหมด ตรวจสอบ หรือตัวเลือก ทดลองรัน ตัวเลือกการทดลองรันหรือโหมดตรวจสอบจะใช้เมื่อเรียกใช้ Playbook เพื่อตรวจสอบว่าจะพบข้อผิดพลาดใดๆ หรือไม่ และจะมีการเปลี่ยนแปลงใดๆ ในโฮสต์ที่ได้รับการจัดการหรือไม่ อย่างไรก็ตาม มันไม่ได้ทำการเปลี่ยนแปลงใด ๆ กับโหนดระยะไกล
ตัวอย่างเช่น หากต้องการเรียกใช้ Playbook ชื่อ httpd.yml
ที่จะติดตั้งและเริ่มเรียกใช้เว็บเซิร์ฟเวอร์ Apache:
ansible-playbook httpd.yml --check
ตัวเลือกอื่นที่เราต้องดูคือตัวเลือก --start-at-task
ใช้เมื่อระบุชื่อของงานที่ Playbook ควรเริ่มต้นหรือเริ่มต้น
ยกตัวอย่าง: Playbook ด้านล่างระบุ 2 งาน: การเล่นครั้งแรกจะติดตั้งเว็บเซิร์ฟเวอร์ Apache และครั้งที่สองจะติดตั้งยูทิลิตี้ htop
---
- name: Install httpd
hosts: all
tasks:
yum:
name: httpd
state: Installed
- name: Install htop
yum:
name: htop
state: started
หากคุณต้องการข้ามการติดตั้งเว็บเซิร์ฟเวอร์ Apache และติดตั้งยูทิลิตี้ htop แทน:
ansible-playbook playbook.yml --start-at-task “Install htop”
สุดท้ายนี้ คุณสามารถแท็กงานหรือการเล่นของคุณได้โดยเพิ่มตัวเลือก แท็ก ลงใน Playbook ของคุณตามที่แสดง สิ่งนี้มีประโยชน์เมื่อคุณมี Playbook ที่ค่อนข้างใหญ่ และคุณต้องการรันงานเฉพาะจาก Playbook ทั้งหมด
---
- name: Install httpd
tags: Install and start
hosts: all
tasks:
yum:
name: httpd
state: Installed
tags: Install
• service:
name: httpd
state: started
ansible-playbook playbook.yml -tags "Install"
หากต้องการละเว้นแท็ก ให้ใช้ตัวเลือก --skip-tags
ตามที่แสดง
ansible-playbook playbook.yml --skip-tags "Install"
บทสรุป
ในหัวข้อนี้ เราได้นำคุณผ่านโมดูลที่ใช้กันทั่วไปใน Ansible วิธีดึงข้อมูล stdout จากการดำเนินการ Playbook เพื่อการวิเคราะห์ การใช้เงื่อนไขใน Playbook และวิธีการจัดการข้อผิดพลาดที่อาจเกิดขึ้นเมื่อทำงาน งาน สุดท้ายนี้ เราได้สรุปการกำหนดค่า Playbooks และวิธีที่คุณสามารถใช้ตัวเลือกเพิ่มเติมเพื่อตัดสินใจว่าจะทำงานใด หากคุณไม่ต้องการเรียกใช้ Playbook ทั้งหมด