- Tác giả

- Name
- Nguyễn Đức Xinh
- Ngày xuất bản
- Ngày xuất bản
Ansible Playbooks Phần 3: Conditionals, Loops và Tags
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
Tags
Tags giúp chạy selective tasks.
Basic tags
tasks:
- name: Install nginx
apt:
name: nginx
state: present
tags:
- install
- nginx
- packages
- name: Configure nginx
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
tags:
- configure
- nginx
- name: Start nginx
service:
name: nginx
state: started
tags:
- service
- nginx
Running with tags
# Chỉ chạy tasks có tag 'install'
ansible-playbook site.yml --tags install
# Chỉ chạy tasks có tag 'nginx'
ansible-playbook site.yml --tags nginx
# Chạy nhiều tags
ansible-playbook site.yml --tags "install,configure"
# Skip tasks có tag 'service'
ansible-playbook site.yml --skip-tags service
# List available tags
ansible-playbook site.yml --list-tags
Special tags
tasks:
- name: Always run this
debug:
msg: "This task always runs"
tags: always
- name: Never run this automatically
debug:
msg: "This only runs with --tags never"
tags: never
- name: Tagged task
debug:
msg: "Normal tagged task"
tags: custom
# Task với tag 'always' sẽ chạy
ansible-playbook site.yml --tags install
# Skip task có tag 'always'
ansible-playbook site.yml --skip-tags always
# Chỉ chạy task có tag 'never'
ansible-playbook site.yml --tags never
Play-level tags
- name: Install packages
hosts: web
tags: install
tasks:
- name: Install nginx
apt:
name: nginx
- name: Install git
apt:
name: git
- name: Configure services
hosts: web
tags: configure
tasks:
- name: Configure nginx
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
Block with tags
- name: Installation block
block:
- name: Update apt cache
apt:
update_cache: yes
- name: Install packages
apt:
name: "{{ item }}"
state: present
loop:
- nginx
- git
tags: install
- name: Configuration block
block:
- name: Copy configs
template:
src: "{{ item }}.j2"
dest: "/etc/{{ item }}"
loop:
- nginx.conf
- app.conf
tags: configure
💡 Key Takeaways
- Conditionals (
when) control task execution dựa trên điều kiện - Loops iterate qua lists hoặc dictionaries
- Tags cho phép chạy selective tasks
- Blocks group tasks và provide error handling
- Combine conditionals + loops + tags để tạo playbooks mạnh mẽ
🎯 Thực hành
- Viết playbook với conditionals cho different OS families
- Sử dụng loops để tạo multiple users và directories
- Tag tasks theo categories (install, configure, deploy)
- Implement error handling với block/rescue/always
