Ansible之playbook剧本
YAML语法
-
yaml文件以---开头,表明这是一个yaml文件。但即使没有使用---开头,也不会有什么影响。
-
yaml中使用"#"作为注释符,可以注释整行,也可以注释行内从"#"开始的内容。
-
yaml中的字符串通常不用加任何引号,即使它包含了某些特殊字符。但有些情况下,必须加引号,最常见的是在引用变量的时候。
-
关于布尔值的书写格式,即true/false的表达式。playbook中的布尔值非常灵活:模块的参数: 这时布尔值作为字符串被ansible解析。接受yes/on/1/true/no/off/0/false;**非模块的参数:**这时布尔值被yaml解释器解析,完全遵循yaml语法。接受不区分大小写的true/yes/on/y/false/no/off/n。建议遵循ansible的官⽅规范,模块的布尔参数采⽤yes/no,⾮模块的布尔参数采⽤True/False。
playbook语法
每个play都包含一个hosts和一个tasks,hosts定义的是inventory中带控制的主机,tasks下定义的是一系列task任务列表,比如调用各个模块。这些task按顺序一次执行一个,直到所有被筛选出来的主机都执行了这个task之后才会移动到下一个task上进行同样的操作。 需要注意的是,虽然只有被筛选出来的主机会执行对应的task,但是所有主机(此处的所有主机表示的是,hosts选项所指定的那些主机)都会收到相同的task指令,所有主机收到指令后,ansible主控端会筛选某些主机,并通过ssh在远程执行任务。
YAML字典
YAML中使用key/value对也称为字典、散列或关联数组。
在key/value对中,键与值通过由冒号和空格组成的分隔符隔开。
# 例如
name: ldh
port: 80/tcp
YAML列表
在YAML中,列表类似于其他编程语言中的数组,为表示一组列表项,使用一个短划线加一个空格作为每个列表项的前缀。
# 例如
hosts:
- server1
- server2
列表也可使用内嵌块表示,其中多个列表项用方括号括起来并由逗号和空格隔开。
# 例如
hosts: [server1, server2]
playbook的使用
ansible-playbook用于运行剧本;-C测试运行结果,并不是真的执行任务。
示例1
# 1、安装httpd,在node1执行
# 2、开机自启
# 3、给/var/www/html目录创建软链接/www
# 4、从http://ansible.example.com/index.html下载至/www
# 5、能够访问该web站点
---
- name: webstation
hosts: node1
tasks:
- name: repo_baseos
yum_repository:
file: server
name: aa
description: aa1
baseurl: http://ansible.example.com/rhel9/BaseOS
enabled: yes
gpgcheck: no
- name: repo_appstream
yum_repository:
file: server
name: cc
description: cc1
baseurl: http://ansible.example.com/rhel9/AppStream
enabled: yes
gpgcheck: no
- name: install httpd
yum:
name: httpd
state: present
- name: set firewalld
firewalld:
service: http
state: enabled
permanent: yes
immediate: yes
- name: create link
file:
src: /var/www/html
dest: /www
state: link
- name: get file index
get_url:
url: http://ansible.example.com/index.html
dest: /www/
setype: httpd_sys_content_t
- name: restart httpd
service:
name: httpd
state: restarted
enabled: yes
示例2
notify handlers用法(当完成......任务时,则进行......任务)
# 对主机node1执行,当创建user2用户后,创建/tmp/ldh文件
---
- name: this is a test playbook
hosts: node1
tasks:
- name: create user1
user:
name: user1
state: present
- name: create user2
user:
name: user2
state: present
notify:
- file3
handlers:
- name: file3
file:
path: /tmp/ldh
state: touch
示例3
tags用法:给任务打标签,一个任务可以有多个标签,使用-t选项来指定需要指定的任务标签。
ansible预置了5个特殊的tag:
-
**always:**如果添加此标签,不管是否指定该任务,都执行。
-
**never:**不执行标签,只有-t选项指定nerver标签时才会执行。
-
**tagged:**只执行带有标签的任务,nerver标签的任务不会执行。
-
**untagged:**只执行不带标签的任务,always标签的任务也会执行。
-
**all:**所有任务都执行,默认标签。
可以同时使用多个标签,需要用逗号隔开。
# 语法 tags: - always
# 查看tag的标签类型 ansible-playbook --list-tags
--- - name: test playbook hosts: node1 tasks: - name: create user3 user: name: user3 state: present tags: - l1 - l2 - name: create user4 user: name: user4 state: present tags: - l2 - l3 - name: create user5 user: name: user5 state: present tags: - l3 - l4
ansible-playbook --skip-tags l1 该剧本的名称# 跳过l1,执行其他任务,除了nerver ansible-playbook --tags always ~ # 只执行always标签 ansible-playbook --tags tagged ~ # 执行带有标签的任务,除了nerver标签 ansible-playbook --tags untagged ~ # 执行不带标签的任务,但是带有always标签的任务仍然会执行 ansible-playbook --tags nerver ~ # 执行带有nerver标签的任务,带有always标签的任务仍然会执行
练习
使用ansible的playbook完成以下操作 node1 属于 test01 主机组 node2 属于 test02 主机组 node3 和 node4 属于 web 主机组 node5 属于 test05 主机组 web 组属于 webtest 主机组
[student@master ansible]$ vim inventory
[test01]
node1
[test02]
node2
[web]
node3
node4
[test05]
node5
[webtest:children]
web
练习1
对node1主机操作,安装httpd服务,网页存放在/www目录中,能够通过curl http://node1访问到网页内容为welcome to luoqi
[student@master ansible]$ vim node1.yml
---
- name: web
hosts: node1
tasks:
- name: repo_baseos
yum_repository:
file: server
name: aa
description: aa1
baseurl: http://ansible.example.com/rhel9/BaseOS
enabled: yes
gpgcheck: no
- name: repo_appstream
yum_repository:
file: server
name: cc
description: cc1
baseurl: http://ansible.example.com/rhel9/AppStream
enabled: yes
gpgcheck: no
- name: install httpd
yum:
name: httpd
state: present
- name: mkdir /www
file:
path: /www
state: directory
setype: httpd_sys_content_t
- name: touch /www/index.html
copy:
content: "welcome to luoqi\n"
dest: /www/index.html
setype: httpd_sys_content_t
- name: replace /etc/httpd/conf/httpd.conf:/var/www/html
replace:
path: /etc/httpd/conf/httpd.conf
regexp: /var/www/html
replace: /www
backup: yes
- name: replace /etc/httpd/conf/httpd.conf:/var/www
replace:
path: /etc/httpd/conf/httpd.conf
regexp: /var/www
replace: /www
- name: restart httpd
service:
name: httpd
state: restarted
enabled: yes
- name: set firewalld for httpd
firewalld:
port: 80/tcp
state: enabled
permanent: yes
immediate: yes
# 验证
[student@master ansible]$ ansible-playbook node1.yml
[student@master ansible]$ curl http://node1

练习2
对node2主机操作,创建一个1000MiB的分区,格式化成ext4的文件系统,并挂载到/testdir目录下。使用ansible node2 -m shell -a 'df -Th'验证。
[student@master ansible]$ vim node2.yml
---
- name: parted
hosts: node2
tasks:
- name: mkpart
parted:
device: /dev/vdb
number: 1
part_type: primary
part_start: 10MiB
part_end: 1010MiB
state: present
- name: filesystem
filesystem:
dev: /dev/vdb1
fstype: ext4
- name: mkdir /testdir
file:
path: /testdir
state: directory
- name: mount
mount:
src: /dev/vdb1
path: /testdir
fstype: ext4
state: mounted
# 验证
[student@master ansible]$ ansible-playbook node2.yml
[student@master ansible]$ ansible node2 -m shell -a 'df -Th'

练习3
对node3主机操作创建卷组datastorage,逻辑卷database,大小为800M,格式化为xfs的文件系统,并挂载到/lv目录下,使用ansible node3 -m shell -a 'df -Th'验证。
[student@master ansible]$ vim node3.yml
---
- name: lv
hosts: node3
tasks:
- name: repo_baseos
yum_repository:
file: server
name: aa
description: aa1
baseurl: http://ansible.example.com/rhel9/BaseOS
enabled: yes
gpgcheck: no
- name: repo_appstream
yum_repository:
file: server
name: cc
description: cc1
baseurl: http://ansible.example.com/rhel9/AppStream
enabled: yes
gpgcheck: no
- name: install lvm2
yum:
name: lvm2
state: present
- name: mkpart
parted:
device: /dev/vdb
number: 1
part_type: primary
part_start: 10MiB
part_end: 2010MiB
state: present
- name: create vg
lvg:
pvs: /dev/vdb1
vg: datastorage
state: present
- name: create lv
lvol:
lv: database
size: 800M
vg: datastorage
state: present
- name: filesystem
filesystem:
dev: /dev/datastorage/database
fstype: xfs
- name: mkdir /lv
file:
path: /lv
state: directory
- name: mount
mount:
src: /dev/datastorage/database
path: /lv
fstype: xfs
state: mounted
# 验证
[student@master ansible]$ ansible-playbook node3.yml
[student@master ansible]$ ansible node3 -m shell -a 'df -Th'

练习4
创建名为/home/student/ansible/tools.yml 的 playbook,能够实现以下目的:
-
将 php 和 tftp 软件包安装到 test01、test02 和 web 主机组中的主机上
-
将 RPM Development Tools 软件包组安装到 test01 主机组中的主机上
-
将 test01 主机组中的主机上所有软件包升级到最新版本
[student@master ansible]$ vim tools.yml
---
- name: lv
hosts:
test01
test02
web
tasks:
- name: repo_baseos
yum_repository:
file: server
name: aa
description: aa1
baseurl: http://ansible.example.com/rhel9/BaseOS
enabled: yes
gpgcheck: no
- name: repo_appstream
yum_repository:
file: server
name: cc
description: cc1
baseurl: http://ansible.example.com/rhel9/AppStream
enabled: yes
gpgcheck: no
- name: install php tftp
yum:
name: php
state: present
- name: install php tftp
yum:
name: tftp
state: present
- name: install RPM Development Tools
hosts: test01
tasks:
- name: install RPM Development Tools
yum:
name: "@Development tools"
state: present
- name: latest
hosts: test01
tasks:
- name: latest
yum:
name: "*"
state: latest
练习5
编写剧本/home/student/ansible/jihua.yml
-
在 test02 组中的被管理主机运行
-
为用户 student 创建计划任务: student 用户每隔 5 分钟执行 echo "hello tarena"
[student@master ansible]$ vim jihua.yml
---
- name: cron
hosts: test02
tasks:
- name: cron
cron:
name: a job
user: student
job: echo "hello tarena"
minute: "*/5"
state: present
# 验证
[student@master ansible]$ ansible-playbook jihua.yml
[student@master ansible]$ ansible test02 -m shell -a 'crontab -u student -l'

练习6
创建剧本/home/student/ansible/webdev.yml,满足下列要求:
-
在 test01 主机组运行
-
创建目录/webdev,属于 webdev 组,权限为 rwxrwxr-x,具有 SetGID 特殊权限
-
使用符号链接/var/www/html/webdev(链接目录) 链接到/webdev (源目录)目录
-
创建文件/webdev/index.html,内容是 It's works!
-
查看 test01 主机组的 web 页面 http://node1/webdev/将显示 It's works!
[student@master ansible]$ vim webdev.yml
# 练习1中已经安装过httpd了
---
- name: web
hosts: test01
tasks:
- name: create webdev
user:
name: webdev
state: present
- name: mkdir /webdev
file:
path: /webdev
group: webdev
mode: '2775'
setype: httpd_sys_content_t
state: directory
- name: create link
file:
src: /webdev
dest: /var/www/html/webdev
setype: httpd_sys_content_t
state: link
- name: touch /webdev/index.html
copy:
content: "It's works!\n"
dest: /webdev/index.html
setype: httpd_sys_content_t
- name: replace
replace:
path: /etc/httpd/conf/httpd.conf
regexp: DocumentRoot "/www"
replace: DocumentRoot "/var/www/html"
backup: yes
- name: replace
replace:
path: /etc/httpd/conf/httpd.conf
regexp: <Directory "/www">
replace: <Directory "/var/www">
backup: yes
- name: restart httpd
service:
name: httpd
state: restarted
enabled: yes
# 验证
[student@master ansible]$ ansible-playbook webdev.yml
[student@master ansible]$ curl http://node1/webdev/
