Ansible-playbook-编写技巧

用 blockinfile 模块向文件追加内容

这里的 create: true 在文件不存在时创建文件.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
- name: K8S setup
hosts: k8s_nodes
vars:
master_ip: 192.168.177.1
master_name: "k8s-master"
tasks:
- name: Stop and disable firewalld
ignore_errors: true
service:
name: firewalld
state: stopped
- name: Stop selinux
ignore_errors: true
replace:
path: /etc/selinux/config
regexp: "enforcing"
replace: "disabled"
- name: Change hostname
ignore_errors: true
command: "hostnamectl set-hostname {{ hostname }}"
- name: Add domain name resolv
ignore_errors: true
blockinfile:
path: /etc/hosts
create: true
block: |
192.168.177.1 k8s-master
192.168.177.20 k8s-node1
192.168.177.25 k8s-node2
- name: Enable kernal parameters
ignore_errors: true
blockinfile:
path: /etc/sysctl.d/k8s.conf
create: true
block: |
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
- name: Add repo
ignore_errors: true
blockinfile:
path: /etc/yum.repo.d/kubernetes.repo
create: true
block: |
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
- name: Install kublet kubeadm kubectl
command: "yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes"
- name: Enable kublet
command: "systemctl enable --now kubelet"

是 YAML 的语法, 表示后跟多行字符串.

notify 执行 handler 的条件

需要 notify 所处 task 任务报告 changed 之后, 才会执行 handlers 的处理程序.

when 条件语句

一般结合 register 使用.

如检查 firewalld 服务的运行状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
---
- name: Test when
hosts: WebServer
tasks:
- name: Install Web Server
yum:
name: httpd
state: present
- name: Get firewall server status
commnd: "systemctl is-active firewalld.service"
register: result
- name: Restart http service
service:
name: httpd
state: restarted
when: result.rc == 0
...

Loop 循环

1
2
3
4
5
6
7
8
9
- name: Test loop
hosts: WebServer
tasks:
- name: Print var
debug:
msg: "{{ item }}"
loop:
- "Hello var1"
- "world var2"

也可以结合 vars:

1
2
3
4
5
6
7
8
9
10
11
- name: Test loop
hosts: WebServer
vars:
service_list:
- chronyd
- firewalld
tasks:
- name: Print var
debug:
msg: "{{ item }}"
loop: "{{ service_list }}"

with_items 循环

和 loop 用法几乎相同:

1
2
3
4
5
6
7
8
9
- name: config hosts
lineinfile:
path: /etc/hosts
line: "{{ item }}"
state: present
with_items:
- '10.0.0.21 Gluster-01'
- '10.0.0.22 Gluster-02'
- '10.0.0.23 Gluster-03'

这里 lineinfile 部分共执行三次, 分别使用 with_items 中定义的一个字符串.

打印调试信息

打印自定义消息

1
2
3
4
5
- hosts: all
tasks:
- name: Print a custom message
debug:
msg: "Debug mode is enabled"

打印变量值

1
2
3
4
5
6
7
8
# playbook.yml
- hosts: all
vars:
my_variable: "Hello, Ansible!"
tasks:
- name: Print the value of my_variable
debug:
var: my_variable

打印多个变量值

1
2
3
4
5
6
7
8
9
10
11
# playbook.yml
- hosts: all
vars:
var1: "Value 1"
var2: "Value 2"
tasks:
- name: Print multiple variables
debug:
msg:
- "var1: {{ var1 }}"
- "var2: {{ var2 }}"

有条件打印调试信息

1
2
3
4
5
6
7
8
9
# playbook.yml
- hosts: all
vars:
debug_mode: true
tasks:
- name: Print debug information if debug_mode is true
debug:
msg: "Debug mode is enabled"
when: debug_mode

以 root 用户运行 playbook

1
2
3
4
5
6
- hosts: all
become: true
tasks:
- name: ...
...
...

Playbook 创建变量的四种方法

在命令行运行是创建

Playbook 为:

1
2
3
4
5
6
7
8
9
10
11
12
13
---
- hosts: Nginx
remote_user: root
gather_facts: no

tasks:
- name: create group
group:
name={{ group }}
- name: create user
user:
name={{ user_name }}
...

执行 ansible-playbook 时定义:

1
ansible-playbook -e group_name=nginx -e user_name=nginx var.yaml

在 playbook 文件中定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
---
- hosts: Nginx
remote_user: root
gather_facts: no
vars:
- group_name: nginx
- user_name: nginx

tasks:
- name: create group
group:
name={{ group }}
- name: create user
user:
name={{ user_name }}
...

用额外的 yaml 文件定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
---
- hosts: Nginx
remote_user: root
gather_facts: no
vars_files:
- vars.yaml

tasks:
- name: create group
group:
name={{ group }}
- name: create user
user:
name={{ user_name }}
...

vars.yml 文件的内容为:

1
2
3
4
---
group_name: nginx
user_name: Nginx
...

在 Inventory 中定义

Inventory 若为:

1
2
3
4
5
6
7
8
9
10
11
12
# inventory.yml
all:
hosts:
web1:
ansible_host: 192.168.1.10
http_port: 8080
children:
webservers:
hosts:
web1:
vars:
http_port: 80

则在编写 playbook 时可以直接使用:

1
2
3
4
5
6
# playbook.yml
- hosts: webservers
tasks:
- name: Print HTTP port
debug:
msg: "HTTP Port is {{ http_port }}"

Playbook 忽略某个任务的错误并继续执行后续任务

使用 ignore_errors 选项:

1
2
3
4
5
6
7
8
9
- name: A playbook example
hosts: all
tasks:
- name: This task might fail but we want to ignore the error
command: /bin/false
ignore_errors: yes

- name: This task will still run even if the previous task fails
command: echo "This will run"

YAML 文件的开始和结束标记

  • 开始标记: ---
  • 结束标记: ...

如:

1
2
3
4
5
6
7
---
name: John Doe
age: 30
address:
street: 123 Main St
city: Anytown
...

Ansible-playbook-编写技巧
http://example.com/2024/03/22/Ansible-playbook-编写技巧/
作者
Jie
发布于
2024年3月22日
许可协议