Ansible Playbooks Phần 3: Conditionals, Loops và Tags
5:00 read
Phần 3 tập trung vào control flow với Conditionals, Loops và Tags để tạo playbooks linh hoạt và mạnh mẽ.
Phần 3: Conditionals, Loops và Tags:
- Conditionals (when) cho control flow
- Loops: simple, dictionaries, nested
- Loop với conditionals và register
- Tags cho selective execution
- Blocks và error handling (block/rescue/always)
- Ví dụ multi-tier deployment
Conditionals (Điều kiện)
Chạy task chỉ khi điều kiện thỏa mãn sử dụng when.
Basic conditionals
tasks:
- name: Install Apache on Debian/Ubuntu
apt:
name: apache2
state: present
when: ansible_os_family == "Debian"
- name: Install Apache on RedHat/CentOS
yum:
name: httpd
state: present
when: ansible_os_family == "RedHat"
- name: Start service only on production
service:
name: nginx
state: started
when: env == "production"
Multiple conditions với and
tasks:
- name: Install package on Ubuntu 20.04
apt:
name: nginx
state: present
when:
- ansible_distribution == "Ubuntu"
- ansible_distribution_version == "20.04"
# Hoặc viết trên một dòng
- name: Same as above
apt:
name: nginx
state: present
when: ansible_distribution == "Ubuntu" and ansible_distribution_version == "20.04"
Multiple conditions với or
tasks:
- name: Install on Debian or Ubuntu
apt:
name: nginx
state: present
when: ansible_distribution == "Debian" or ansible_distribution == "Ubuntu"
# Hoặc dùng list
- name: Install on Debian family
apt:
name: nginx
state: present
when: ansible_distribution in ["Debian", "Ubuntu"]
Conditions với registered variables
tasks:
- name: Check if nginx is installed
command: which nginx
register: nginx_check
ignore_errors: yes
- name: Install nginx if not present
apt:
name: nginx
state: present
when: nginx_check.rc != 0
- name: Check disk usage
shell: df -h / | awk 'NR==2 {print $5}' | sed 's/%//'
register: disk_usage
- name: Warning if disk > 80%
debug:
msg: "WARNING: Disk usage is {{ disk_usage.stdout }}%"
when: disk_usage.stdout|int > 80
Conditions với facts
tasks:
- name: Install specific version on old Ubuntu
apt:
name: nginx=1.18.0-0ubuntu1
state: present
when:
- ansible_distribution == "Ubuntu"
- ansible_distribution_major_version|int < 22
- name: Set timezone on physical machines
timezone:
name: Asia/Ho_Chi_Minh
when: ansible_virtualization_role != "guest"
Conditions với file checks
tasks:
- name: Check if config exists
stat:
path: /etc/nginx/nginx.conf
register: config_file
- name: Backup config if exists
copy:
src: /etc/nginx/nginx.conf
dest: /etc/nginx/nginx.conf.backup
remote_src: yes
when: config_file.stat.exists
- name: Create config if not exists
copy:
src: templates/nginx.conf
dest: /etc/nginx/nginx.conf
when: not config_file.stat.exists
Conditions với boolean
vars:
install_monitoring: true
enable_ssl: false
tasks:
- name: Install monitoring agent
apt:
name: node-exporter
state: present
when: install_monitoring
- name: Configure SSL
template:
src: ssl.conf.j2
dest: /etc/nginx/ssl.conf
when: enable_ssl | bool
Loops
Lặp qua danh sách items để thực thi task nhiều lần.
Simple loop
- name: Install multiple packages
apt:
name: "{{ item }}"
state: present
loop:
- nginx
- git
- vim
- htop
- curl
Loop với dictionaries
- name: Create multiple users
user:
name: "{{ item.name }}"
state: present
groups: "{{ item.groups }}"
shell: "{{ item.shell }}"
loop:
- { name: 'john', groups: 'developers', shell: '/bin/bash' }
- { name: 'jane', groups: 'admins', shell: '/bin/bash' }
- { name: 'bob', groups: 'developers', shell: '/bin/zsh' }
- name: Create directories with permissions
file:
path: "{{ item.path }}"
state: directory
owner: "{{ item.owner }}"
mode: "{{ item.mode }}"
loop:
- { path: '/opt/app', owner: 'appuser', mode: '0755' }
- { path: '/var/log/app', owner: 'appuser', mode: '0755' }
- { path: '/etc/app', owner: 'root', mode: '0644' }
Loop với variables
vars:
packages:
- nginx
- postgresql
- redis
users:
- alice
- bob
- charlie
tasks:
- name: Install packages
apt:
name: "{{ item }}"
state: present
loop: "{{ packages }}"
- name: Create users
user:
name: "{{ item }}"
state: present
loop: "{{ users }}"
Loop với conditionals
- name: Install packages only on Ubuntu
apt:
name: "{{ item }}"
state: present
loop:
- nginx
- apache2
- mysql-server
when: ansible_distribution == "Ubuntu"
- name: Create users only in production
user:
name: "{{ item }}"
state: present
loop:
- produser1
- produser2
when: env == "production"
Loop với register
- name: Check multiple services
systemd:
name: "{{ item }}"
register: service_status
loop:
- nginx
- mysql
- redis
- name: Display service status
debug:
msg: "{{ item.item }} is {{ item.status.ActiveState }}"
loop: "{{ service_status.results }}"
Nested loops
- name: Create files in multiple directories
file:
path: "{{ item.0 }}/{{ item.1 }}"
state: touch
loop: "{{ directories | product(files) | list }}"
vars:
directories:
- /tmp/dir1
- /tmp/dir2
files:
- file1.txt
- file2.txt
Loop control
- name: Install packages with index
apt:
name: "{{ item }}"
state: present
loop:
- nginx
- git
- vim
loop_control:
index_var: idx
label: "Installing {{ item }}"
- name: Process with pause between iterations
command: process_item.sh {{ item }}
loop:
- item1
- item2
- item3
loop_control:
pause: 5 # Pause 5 seconds between iterations
Loop until
- name: Wait for service to be ready
uri:
url: http://localhost:8080/health
status_code: 200
register: health_check
until: health_check.status == 200
retries: 10
delay: 5 # Wait 5 seconds between retries
Yêu cầu đăng nhập
Vui lòng đăng nhập để truy cập nội dung này
Additional Resources
Course Guide
Comprehensive PDF guide with examples
GitHub Repository
Example code for all lessons
Discussion
Have a question about this lesson? Post it here and get answers from instructors and peers.
