Ansible for the Absolute Beginner
Table of contents
Ansible Inventory
Để làm việc với nhiều máy chủ, Ansible cần thiết lập kết nối với các máy chủ đó. Điều này được thực hiện bằng SSH đối với Linux và PowerShell Remoting đối với Windows. Đây chính là lý do khiến Ansible được gọi là Agentless. Agentless có nghĩa là bạn không cần cài đặt thêm bất kỳ phần mềm nào trên các máy đích để có thể làm việc với Ansible. Một kết nối SSH đơn giản là đủ để đáp ứng yêu cầu của Ansible.
Một trong những nhược điểm lớn của hầu hết các công cụ orchestration khác là bạn phải cấu hình một agent trên các hệ thống đích trước khi có thể thực hiện bất kỳ loại tự động hóa nào. Trong khi đó, thông tin về các hệ thống đích này được lưu trữ trong một inventory file. Nếu bạn không tạo một inventory file mới, Ansible sẽ sử dụng inventory file mặc định nằm tại vị trí /etc/ansible/hosts
. Hãy cùng xem qua một ví dụ về inventory file.
# Format INI
server1.company.com
server2.company.com
Nó đơn giản chỉ là danh sách các máy chủ, được liệt kê lần lượt. Bạn cũng có thể nhóm các máy chủ khác nhau lại với nhau bằng cách định nghĩa chúng như sau dưới một tên nhóm.
# Format INI
server1.company.com
server2.company.com
[mail_servers]
server3.company.com
server4.company.com
Tuy nhiên, tôi muốn gọi các máy chủ này trong Ansible bằng một bí danh như web server hoặc database server. Tôi có thể làm điều này bằng cách thêm một bí danh cho từng máy chủ.
# Format INI
web ansible_host=server1.company.com
db ansible_host=server2.company.com
Ansible_connection là thuộc tính xác định cách Ansible kết nối đến máy chủ đích.
# Format INI
web ansible_host=server1.company.com ansible_connection=ssh
db ansible_host=server2.company.com ansible_connection=winrm
Bạn cũng có thể đặt nó là localhost để chỉ rằng chúng ta muốn làm việc với máy chủ cục bộ và không kết nối đến bất kỳ máy chủ từ xa nào. Nếu bạn không có nhiều máy chủ để làm việc, bạn có thể đơn giản bắt đầu với localhost trong inventory file của mình.
# Format INI
web ansible_host=server1.company.com ansible_connection=ssh
db ansible_host=server2.company.com ansible_connection=winrm
localhost ansible_connection=localhost
Ansible_port xác định cổng mà Ansible sẽ kết nối tới. Mặc định, nó được thiết lập là cổng 22 cho SSH, nhưng nếu bạn cần thay đổi, bạn có thể thiết lập cổng khác bằng cách sử dụng tham số ansible_port.
# Format INI
web ansible_host=server1.company.com ansible_connection=ssh ansible_port=22
db ansible_host=server2.company.com ansible_connection=winrm ansible_port=22
localhost ansible_connection=localhost
Ansible_user xác định người dùng được sử dụng để thực hiện kết nối từ xa. Mặc định, tham số này được thiết lập là root cho các máy Linux.
# Format INI
web ansible_host=server1.company.com ansible_connection=ssh ansible_port=22 \
ansible_user=root
db ansible_host=server2.company.com ansible_connection=winrm ansible_port=22 \
ansible_user=admin
localhost ansible_connection=localhost
Ansible_ssh_pass xác định mật khẩu SSH cho Linux. Lưu ý rằng việc lưu trữ mật khẩu ở dạng văn bản thuần (plain text) như thế này có thể không phải là cách lý tưởng. Thực tiễn tốt nhất là thiết lập xác thực không mật khẩu dựa trên SSH key giữa các máy chủ, và bạn chắc chắn nên áp dụng điều này trong môi trường sản xuất hoặc môi trường doanh nghiệp.
# Format INI
web ansible_host=server1.company.com ansible_connection=ssh ansible_port=22 \
ansible_user=root ansible_ssh_pass=P@ssw0rd
db ansible_host=server2.company.com ansible_connection=winrm ansible_port=22 \
ansible_user=admin ansible_password=P@ssw0rd
localhost ansible_connection=localhost
Inventory Formats
Hãy lấy ví dụ về hai công ty:
Công ty đầu tiên là một startup nhỏ với một vài dịch vụ đảm nhận các chức năng cơ bản như web hosting và database management.
Công ty thứ hai là một tập đoàn đa quốc gia với hàng trăm máy chủ phân bố trên toàn cầu, đảm nhận nhiều chức năng đa dạng như e-commerce, customer support, data analysis, và nhiều chức năng khác.
Đối với startup nhỏ, một inventory ở định dạng INI đơn giản là đủ. Nó giống như một sơ đồ tổ chức cơ bản với chỉ vài phòng ban. Tuy nhiên, đối với một tập đoàn đa quốc gia, cần một inventory chi tiết và có cấu trúc hơn. Đây chính là lúc định dạng YAML trở nên hữu ích.
Ansible hỗ trợ hai loại định dạng inventory chính: INI và YAML.
Định dạng INI là đơn giản nhất và dễ hiểu nhất. Nó giống như một sơ đồ tổ chức cơ bản dành cho một startup nhỏ.
[webservers]
web1.example.com
web2.example.com
[dbservers]
db1.example.com
db2.example.com
Định dạng YAML có cấu trúc và linh hoạt hơn so với định dạng INI. Nó giống như một sơ đồ tổ chức phức tạp dành cho một tập đoàn đa quốc gia.
all:
children:
webservers:
hosts:
web1.example.com
web2.example.com
dbservers:
hosts:
db1.example.com
db2.example.com
Grouping and Parent-Child Relationships
Là một IT administrator trong một tổ chức lớn với cơ sở hạ tầng IT phức tạp, bạn sẽ có lợi khi sử dụng định dạng YAML cho inventory. Định dạng này sẽ cho phép bạn tổ chức các máy chủ thành các nhóm dựa trên vai trò của chúng (ví dụ: web servers, database servers, application servers) và vị trí địa lý (ví dụ: các máy chủ tại New York, London, Singapore). Nó cũng cung cấp khả năng mở rộng tốt hơn khi cơ sở hạ tầng của bạn phát triển và trở nên phức tạp hơn.
Quản lý từng máy chủ một cách riêng lẻ có thể là một nhiệm vụ đầy thử thách.Nếu bạn cần cập nhật các web servers, bạn sẽ phải chỉ định thủ công từng máy chủ web. Điều này không chỉ tốn thời gian mà còn dễ mắc phải lỗi.
Với tính năng grouping của Ansible, chúng ta có thể tạo ra các nhãn hoặc nhóm chung để quản lý và vận hành một tập hợp các máy chủ một cách hiệu quả. Giờ đây, khi bạn cần cập nhật các web servers, bạn chỉ cần nhắm đến nhóm web servers và Ansible sẽ áp dụng các thay đổi cho tất cả các máy chủ trong nhóm đó.
Bạn có thể tạo các nhóm riêng biệt cho web servers tại mỗi vị trí, nhưng điều này sẽ dẫn đến việc phải lặp lại nhiều cấu hình chung. Đây là lúc mối quan hệ parent-to-child trong Ansible phát huy tác dụng. Bạn có thể tạo một nhóm cha gọi là web servers và các nhóm con cho mỗi vị trí, ví dụ như web servers US, web servers EU, v.v. Bạn có thể định nghĩa các cấu hình chung ở mức nhóm cha và các cấu hình riêng biệt cho từng vị trí ở mức nhóm con.
Theo cách này, bạn có thể quản lý các máy chủ của mình một cách hiệu quả hơn và tránh việc lặp lại cấu hình. Trong định dạng INI, các nhóm được định nghĩa bằng cách sử dụng dấu ngoặc vuông, và các máy chủ được liệt kê dưới các nhóm tương ứng. Mối quan hệ parent-child được định nghĩa bằng cách sử dụng hậu tố :children.
# Format INI
[webservers:children]
webservers_us
webservers_eu
[webservers_us]
server1_us.com ansible_host=192.168.8.101
server2_us.com ansible_host=192.168.8.102
[webservers_eu]
server1_eu.com ansible_host=10.12.0.101
server2_eu.com ansible_host=10.12.0.102
all:
children:
webservers:
children:
webservers_us:
hosts:
server1_us.com:
ansible_host=192.168.8.101
server2_us.com:
ansible_host=192.168.8.102
webservers_eu:
hosts:
server1_eu.com:
ansible_host=10.12.0.101
server2_eu.com:
ansible_host=10.12.0.102
Ansible Variables
Cũng giống như bất kỳ ngôn ngữ lập trình hoặc kịch bản nào khác, biến được sử dụng để lưu trữ các giá trị thay đổi theo từng đối tượng khác nhau. Ví dụ, giả sử chúng ta đang thực hiện cùng một thao tác áp dụng bản vá cho hàng trăm máy chủ, chúng ta chỉ cần một playbook duy nhất cho tất cả các máy chủ đó. Tuy nhiên, chính các biến sẽ lưu trữ thông tin về các tên host, tên người dùng hoặc mật khẩu khác nhau cho từng máy chủ.
Chúng ta cũng có thể định nghĩa các biến trực tiếp trong playbook.
-
name: Add DNS server to resolv.conf
hosts: localhost
vars:
dns_server: 10.1.250.10
tasks:
- lineinfile:
path: /etc/resolv.conf
line: 'nameserver {{ dns_server }}'
Chúng ta cũng có thể định nghĩa các biến trong một tệp riêng biệt chuyên dành cho các biến.
variable1: value1
varibale2: value2
Variable Types
Các biến chuỗi (String variables) trong Ansible là các dãy ký tự. Chúng có thể được định nghĩa trong một playbook, trong inventory, hoặc được truyền vào dưới dạng tham số dòng lệnh (command line arguments).
username: "admin"
Các biến số (Number variables) trong Ansible có thể chứa giá trị số nguyên (integer) hoặc số thực (floating-point). Chúng có thể được sử dụng trong các phép toán số học (mathematical operations).
max_connections: 100
Các biến Boolean trong Ansible có thể chứa giá trị true hoặc false. Chúng thường được sử dụng trong các câu lệnh điều kiện (conditional statements).
debug_mode: true
Chúng ta sử dụng các biến danh sách (list variables) trong Ansible để chứa một tập hợp các giá trị có thứ tự. Các giá trị này có thể thuộc bất kỳ kiểu dữ liệu nào.
packages:
- nginx
- postgresql
- git
# "{{ packages[0] }}"
Chúng ta cũng có các biến từ điển (dictionary variables) trong Ansible, dùng để chứa một tập hợp các cặp khóa-giá trị (key-value pairs). Các khóa và giá trị có thể thuộc bất kỳ kiểu dữ liệu nào.
user:
name: "admin"
password: "secret"
# "{{ user.name }}"
Variable Scoping
Trong file inventory đơn giản này, chúng ta đã chỉ định một máy chủ DNS (DNS server) cho host web2.
web1 ansible_host=172.20.1.100
web2 ansible_host=172.20.1.101 dns_server=10.5.5.4
web3 ansible_host=172.20.1.102
---
- name: Print dns server
hosts: all
tasks:
- debug:
msg: "{{ dns_server }}"
Không, vì phạm vi (scope) của biến đó chỉ giới hạn trong host web2.
TASK[debug]***************************
ok:[web1] => {
"dns_server": "VARIABLE IS NOT DEFINED"
}
ok:[web2] => {
"dns_server": "10.5.5.4"
}
ok:[web3] => {
"dns_server": "VARIABLE IS NOT DEFINED"
}
Phạm vi (scope) xác định khả năng truy cập hoặc khả năng hiển thị của một biến. Giống như trong các ngôn ngữ lập trình, một biến có thể truy cập được tùy thuộc vào cách và nơi nó được định nghĩa.
ở đây tôi có một playbook đơn giản, trong đó thiết lập một giá trị cho máy chủ NTP (NTP server) và in nó ra màn hình.
---
- name: Play1
hosts: web1
vars:
ntp_server: 10.1.1.1
tasks:
- debug:
var: ntp_server
- name: Play2
hosts: web1
tasks:
- debug:
var: ntp_server
Giá trị cho máy chủ NTP chỉ được định nghĩa trong play1 vì vậy nó sẽ được in thành công trong play1.
TASK[debug]*************************
ok:[web1] => {
"ntp_server": "10.1.1.1"
}
Tuy nhiên, biến đó không thể truy cập được trong play2 vì phạm vi của biến chỉ giới hạn trong play1.
TASK[debug]*************************
ok:[web1] => {
"ntp_server": "VARIABLE IS NOT DEFINED"
}
Cuối cùng, có những biến toàn cục (global variables), là những biến có thể truy cập ở mọi nơi trong suốt quá trình thực thi playbook. Chúng ta đã thấy điều này trước đó, ví dụ như việc truyền một biến dưới dạng biến bổ sung (extra variable) qua dòng lệnh, như sau.
$ ansible-playbook playbook.yml --extra-vars "ntp_server=10.1.1.1"
Magic Variables
Trước đó, chúng ta đã thảo luận về phạm vi (scope) của một biến. Chúng ta đã học rằng các biến của host được liên kết với từng host riêng biệt.
web1 ansible_host=172.20.1.100
web2 ansible_host=172.20.1.101 dns_server=10.5.5.4
web3 ansible_host=172.20.1.102
Magic variables gọi là hostvars có thể được sử dụng để lấy các biến được định nghĩa trên một host khác.
---
- name: Print dns server
hosts: all
tasks:
- debug:
msg: "{{ hostvars['web2'].dns_server }}"
Trong trường hợp này, hostvars['web2'].dns_server sẽ lấy giá trị của máy chủ DNS được định nghĩa trên node web2.
TASK[debug]***************************
ok:[web1] => {
"dns_server": "10.5.5.4"
}
ok:[web2] => {
"dns_server": "10.5.5.4"
}
ok:[web3] => {
"dns_server": "10.5.5.4"
}
Bạn có thể lấy bất kỳ thông tin nào về các host khác theo cách này. Để lấy tên host hoặc địa chỉ IP của host khác, hãy sử dụng tham số ansible_host.
---
- name: Print dns server
hosts: all
tasks:
- debug:
msg: "{{ hostvars['web2'].ansible_host }}"
Một magic variables khác gọi là groups.
web1 ansible_host=172.20.1.100
web2 ansible_host=172.20.1.101
web3 ansible_host=172.20.1.102
[web_servers]
web1
web2
web3
[americas]
web1
web2
[asia]
web3
Groups trả về tất cả các host thuộc một nhóm cụ thể.
msg: "{{ groups['americas'] }}"
web1
web2
Group names là một magic variables khác. Nó trả về tất cả các nhóm mà host hiện tại thuộc về.
msg: "{{ group_names }}" # web1
web_servers
americas
Inventory_hostname là một magic variable, điều đó sẽ cung cấp cho bạn tên được cấu hình cho host trong file inventory, chứ không phải tên host hay FQDN (Fully Qualified Domain Name).
msg: "{{ inventory_hostname }}"
web1
Ansible Facts
Khi bạn chạy một playbook và Ansible kết nối đến máy đích, trước tiên nó sẽ thu thập thông tin về máy đó, chẳng hạn như thông tin cơ bản về hệ thống, bao gồm kiến trúc hệ thống, phiên bản hệ điều hành, chi tiết bộ vi xử lý, thông tin bộ nhớ, số serial, và nhiều thông tin khác.
Nó thu thập thông tin về khả năng kết nối mạng của máy chủ, bao gồm các giao diện mạng, địa chỉ IP, FQDN, địa chỉ MAC, v.v., cũng như thông tin về thiết bị như các ổ đĩa, phân vùng, điểm gắn kết (mounts) và dung lượng còn trống. Ngoài ra, nó còn ghi nhận ngày giờ trên các hệ thống đó và các cấu hình khác.
Những thông tin này được gọi là facts trong Ansible. Ansible thu thập tất cả các facts này thông qua module setup. Module setup được Ansible tự động chạy để thu thập facts về các máy chủ khi bạn chạy một playbook, ngay cả khi bạn không sử dụng module này trong playbook của mình.
Ví dụ:
Trong playbook mẫu này, nơi chúng ta in ra một thông báo "hello", chúng ta chỉ có một tác vụ duy nhất. Tác vụ này sử dụng module debug để in thông báo.
---
- name: Print hello message
hosts: all
tasks:
- debug:
msg: Hello from Ansible!
Tuy nhiên, trong kết quả đầu ra, bạn sẽ thấy rằng thực tế có hai tác vụ được thực thi.
Tác vụ đầu tiên thực hiện việc thu thập facts.
TASK [Gathering Facts]**********************************
ok:[web1]
ok:[web2]
Tác vụ thứ hai in ra thông báo.
TASK [debug]************************************
ok:[web1] => {
"msg": "Hello from Ansible!
}
ok:[web2] => {
"msg": "Hello from Ansible!
}
Tác vụ đầu tiên là nơi Ansible tự động chạy module setup và thu thập các facts từ các máy chủ.
Tất cả các facts được Ansible thu thập đều được lưu trữ trong một biến có tên là ansible_facts.
---
- name: Print hello message
hosts: all
tasks:
- debug:
var: ansible_facts
TASK [debug] *******************************************************
ok: [web1] => {
"ansible_facts": {
"all_ipv4_addresses": [
"172.20.1.100"
],
"architecture": "x86_64",
"date_time": {
"date": "2019-09-07",
},
"distribution": "Ubuntu",
"distribution_file_variety": "Debian",
"distribution_major_version": "16",
"distribution_release": "xenial",
"distribution_version": "16.04",
"dns": {
"nameservers": [
"127.0.0.11"
],
},
"fqdn": "web1",
"hostname": "web1",
"interfaces": [
"lo",
"eth0"
],
"machine": "x86_64",
"memfree_mb": 72,
"memory_mb": {
"real": {
"free": 72,
"total": 985,
"used": 913
},
}
Sử dụng tùy chọn var trong module debug và chỉ định biến ansible_facts. Kết quả đầu ra sẽ hiển thị rất nhiều thông tin về các địa chỉ IP của máy chủ, hệ thống là 64 bit hay 32 bit, thông tin về phiên bản, cấu hình DNS server, FQDN, các giao diện mạng, chi tiết bộ nhớ, thông tin thiết bị, chi tiết bộ vi xử lý, v.v.
Chẳng hạn, nếu playbook của bạn không phụ thuộc vào bất kỳ thông tin nào được thu thập từ facts, bạn có thể muốn tắt việc thu thập facts. Bạn có thể làm điều này bằng cách thêm tùy chọn gather_facts: no vào play như sau:
---
- name: Print hello message
hosts: all
gather_facts: no
tasks:
- debug:
var: ansible_facts
TASK [debug]********************************
ok:[web1] => {
"ansible_facts": {}
}
ok:[web2] => {
"ansible_facts": {}
}
Sau đó, bạn chỉ thấy một tác vụ duy nhất và không có thông tin về các facts đã được thu thập. Hành vi thu thập facts này cũng được điều khiển bởi một thiết lập trong tệp cấu hình Ansible gọi là Gathering.
# /etc/ansible/ansible.cfg
gathering = implicit
Mặc định, giá trị của nó được thiết lập là implicit, có nghĩa là Ansible sẽ tự động thu thập facts dù bạn có chỉ định hay không. Explicit là ngược lại, trong đó Ansible sẽ không thu thập facts mặc định, nhưng bạn có thể bật tính năng này bằng cách đặt gather_facts: true trong playbook.
Cài đặt trong playbook luôn có ưu tiên hơn cài đặt trong tệp cấu hình.
Ansible Playbooks
Ansible Playbooks là ngôn ngữ điều phối của Ansible. Playbooks là nơi chúng ta định nghĩa những gì muốn Ansible thực hiện. Đây là tập hợp các hướng dẫn mà bạn cung cấp cho Ansible để thực thi các tác vụ một cách tự động.
Ví dụ:
Playbooks có thể đơn giản như thực thi một loạt lệnh trên các máy chủ khác nhau theo trình tự, và khởi động lại các máy chủ đó theo một thứ tự cụ thể.
Triển khai hàng trăm máy ảo (VM) trong hạ tầng đám mây công cộng và riêng.
Cung cấp tài nguyên lưu trữ cho các VM.
Thiết lập cấu hình mạng và cụm cho chúng.
Cấu hình các ứng dụng như máy chủ web hoặc máy chủ cơ sở dữ liệu.
Thiết lập cân bằng tải, thiết lập các thành phần giám sát.
Cài đặt và cấu hình các ứng dụng sao lưu, và cập nhật cơ sở dữ liệu cấu hình với thông tin về các VM mới, v.v.
Playbook là một tệp YAML đơn chứa một tập hợp các play.
Một play định nghĩa một tập hợp các hoạt động sẽ được thực thi trên một hoặc một nhóm máy chủ (hosts).
Một task là một hành động đơn lẻ được thực hiện trên một máy chủ. Một số ví dụ về task bao gồm:
Thực thi một lệnh hoặc một script trên máy chủ.
Cài đặt một gói phần mềm trên máy chủ.
Thực hiện thao tác tắt hoặc khởi động lại máy chủ.
-
name: Play 1
hosts: localhost
tasks:
- name: Execute command 'date'
command: date
- name: Execute script on server
script: test_script.sh
- name: Install httpd service
yum:
name: httpd
state: present
- name: Start web server
service:
name: httpd
state: started
Verifying Playbooks
Khi triển khai một bản cập nhật phần mềm quan trọng trên hàng trăm máy chủ trong tổ chức của bạn. Bạn viết một Ansible Playbook để tự động hóa nhiệm vụ này và, tự tin với công việc của mình, bạn quyết định chạy nó ngay lập tức trong môi trường production.
Tuy nhiên, do một lỗi không được phát hiện trong playbook, thay vì cập nhật phần mềm nó vô tình tắt dịch vụ trên tất cả các máy chủ, dẫn đến thời gian ngừng hoạt động nghiêm trọng. Kịch bản này nhấn mạnh tầm quan trọng của một bước quan trọng trong quá trình phát triển playbook, đó là xác minh (verification).
Việc xác minh playbook trước khi thực thi trong môi trường production là một thực hành vô cùng quan trọng. Nó giống như một buổi diễn tập trước khi biểu diễn chính thức, cho phép bạn phát hiện và sửa chữa các lỗi hoặc hành vi không mong muốn trong một môi trường được kiểm soát. Nếu bỏ qua bước xác minh này, bạn có nguy cơ đưa ra các vấn đề không lường trước vào hệ thống của mình, như đã minh họa trong kịch bản nêu trên.
Những vấn đề này có thể dẫn đến thời gian ngừng hệ thống, mất dữ liệu hoặc các hậu quả nghiêm trọng khác, và thường khó khắc phục hơn nhiều so với vấn đề ban đầu mà playbook được thiết kế để giải quyết. Bằng cách xác minh playbook, bạn có thể tự tin rằng playbook sẽ hoạt động chính xác như mong đợi khi chạy trong môi trường production. Điều này không chỉ giúp duy trì sự ổn định và độ tin cậy của hệ thống mà còn giúp bạn tránh được những rắc rối tiềm ẩn trong tương lai.
Ansible cung cấp nhiều chế độ để xác minh playbook, trong đó check mode và diff mode là hai chế độ chính.
Check mode là chế độ chạy thử (dry run) trong đó Ansible thực thi playbook mà không thực hiện bất kỳ thay đổi thực tế nào trên các máy chủ (hosts). Chế độ này cho phép bạn xem những thay đổi mà playbook sẽ thực hiện mà không áp dụng chúng. Để chạy playbook trong check mode, sử dụng tùy chọn --check
.
Giả sử bạn có một Ansible playbook đơn giản được lưu dưới dạng install_nginx.yml
, nhiệm vụ của nó là cài đặt máy chủ web nginx trên một máy chủ.
---
- hosts: webservers
tasks:
- name: Ensure nginx is installed
apt:
name: nginx
state: present
become: yes
Để chạy playbook này trong check mode, bạn sẽ sử dụng tùy chọn --check
. Trong check mode, Ansible sẽ không thực sự cài đặt nginx trên các máy chủ. Thay vào đó, nó sẽ cho bạn biết những gì nó sẽ thực hiện nếu chạy playbook một cách thực tế.
$ ansible-playbook install_nginx.yml --check
- PLAY [webservers]***************************
TASK [Gathering Facts]**********************
ok: [webserver1]
TASK [Ensure nginx is installed]************
changed: [webserver1]
PLAY RECAP
- ********************************************
webserver1: ok=2 changed=1 unreachable=0 failed=0 skipped=0 ignored=0
Một chế độ khác để xác minh playbook là diff mode. Diff mode, khi được sử dụng cùng với check mode, hiển thị sự khác biệt giữa trạng thái hiện tại và trạng thái sau khi playbook được thực thi. Nó cung cấp một sự so sánh trước và sau, giúp bạn hiểu rõ hơn về những thay đổi mà playbook sẽ thực hiện. Để chạy playbook trong diff mode, bạn sử dụng tùy chọn --diff
.
Dưới đây là một ví dụ về playbook Ansible đảm bảo rằng một dòng cụ thể có mặt trong một tệp cấu hình:
---
- hosts: webservers
tasks:
- name: Ensure the line is present in the file
lineinfile:
path: /etc/nginx/nginx.conf
line: "client_max_body_size 100M"
become: yes
Để chạy playbook này trong check mode và diff mode, bạn sẽ sử dụng các tùy chọn --check
và --diff
như sau:
$ ansible-playbook configure_nginx.yml --check --diff
- PLAY [webservers] ****************************************
TASK [Gathering Facts] ***********************************
ok: [webserver1]
TASK [Ensure the configuration line is present] **********
--- before: /etc/nginx/nginx.conf (content)
+++ after: /etc/nginx/nginx.conf (content)
@@ -20,3 +20,4 @@
+client_max_body_size 100M;
changed: [webserver1]
PLAY RECAP
- ************************************************************
webserver1: ok=2 changed=1 unreachable=0 failed=0 skipped=0 ignored=0