介绍
playbook 是用 yaml的文件形式写的
yaml 是一个可读性高,用来表达数据序列化的格式。YAML参考了其他多种语言,包括:C语言、Python、Perl,并从XML、电子邮件的数据格式(RFC 2822)中获得灵感。Clark Evans在2001年首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者。当前已经有数种编程语言或脚本语言支持(或者说解析)这种语言。
YAML是"YAML Ain't a Markup Language"(YAML不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:"Yet Another Markup Language"(仍是一种标记语言),但为了强调这种语言以数据做为中心,而不是以标记语言为重点,而用反向缩略语重命名。
yaml 的写法参考
https://yaml.org
spouse
playbook的 变量
playbook的 组成结构:
Inventory
Modules
Ad hum commands
Playbooks:
Tasks: 任务 即将调用的模块操作
Variables: 变量
Templates: 模板
Handlers: 处理器, 由有时间触发的执行操作
Roles: 角色
基本结构
- host: webservs
remote_user:
tasks:
- take1
module_name: module_args
- task2
写个简单的playbook
[root@localhost yaml]# cat createuser.yaml
- hosts: web
remote_user: root
tasks:
- name: create hahaha group # 任务名称 没有实际执行意义
group: name=hahaha system=yes gid=655 # 执行内容 调用了 group模块
- name: create hahaha user # 任务名称
user: name=hahaha uid=655 system=yes group=hahaha # 创建用户,使用了user 模块
然后使用指令进行操作
ansible-playbook createuser.yaml
进行查看。完成
192.168.144.171 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.144.172 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ok 这里的ok只是表示有执行数据类型,并不能代表结果
changed 这里的changed表示相关数据发生变化
当我们再执行一遍的时候 changed就不会发生变化了,因为已经执行过一次了。 所以相关的数据内容都不会发生改变。
安装httpd 的 palybook
以下文件
[root@localhost yaml]# cat httpd.yaml
- hosts: web
remote_user: root
tasks:
- name : install httpd service # 第一个任务 安装httpds
yum : name=httpd state=latest # 使用yum模块,使用最新版本
- name : Edit configuration for httpd # 修改配置文件 copy : src=/home/project/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf # 使用了copy模块。可以将本地复制到远程.本地配置文件已经已经过修改 。 - name : start httpd service # 启动服务
service : name=httpd state=started # 使用了service模块 如果需要开机启动 可以加 enabled=true
查看本地的配置文件,将监听的端口 ,改为8008.
然后执行
ansible-playbook httpd.yaml
查看执行结果,执行完成。
验证,程序安装完成。程序也启动起来了。 端口是经过修改的 8008。
完成。
handlers
相当于当资源发生变化是,采取一定的操作。
比如:修改配置文件,程序进行重启
需要写一个 notify 来触发这个 handler
看以下
[root@localhost conf]# cat /etc/ansible/yaml/httpd.yaml
- hosts: web
remote_user: root
tasks:
- name : install httpd service
yum : name=httpd state=latest
- name : Edit configuration for httpd
copy : src=/home/project/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: # 这边定义一个notify,只要配置文件有修改,就触发那个handlers。
- restart htttpd # 这边是定义handler的名字的
- name : start httpd service
service : name=httpd state=started
handlers: # 使用handlers 和tasks 是同级的
- name: restart htttpd # 这边使用名字 必须和上面 notify 里面的定义的名字 一样
service: name=httpd state=restarted # 这边其实就是在写个service 重启下。
这边修改下 httpd conf的配置。 修改下监听端口为8088
再次执行yaml文件。
ansible-playbook httpd.yaml
查看以下, 修改配置的task 和 handler 都执行了
再次查看。发现监听的端口,已经改了。 所以只要配置文件发生变化。就会触发handler。配置文件没变化。bandler就不会执行。
vars
ansible支持变量
- hosts: web
remote_user: root
vars: ## 定义变量
- packages: httpd ## 变量名是 packages
- soft: httpd ## 变量名是 soft
tasks:
- name : install httpd service
yum : name= {{ packages }} state=latest ## 使用变量
- name : Edit configuration for httpd
copy : src=/home/project/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify:
- restart htttpd
- name : start httpd service
service : name= {{ soft }} state=started ## 使用变量
handlers:
- name: restart htttpd
service: name= {{ soft }} state=restarted ## 使用变量
然后我们还可以使用ansible本生的变量
使用setup 模块。 可以看到有许多ansible的 变量
ansible 192.168.249.152 -m setup
我们可以看到本机的ip在ansible里面可以用以下变量名。
ansible_all_ipv4_addresses
看以下
[root@master yaml]# cat var1.yaml
- hosts: webser
remote_user: root
tasks:
- name: write file
shell: 'echo {{ ansible_all_ipv4_addresses }} >> /tmp/anip.txt' # 使用 shell模块。使用ansible本身的变量, 就是将本机ip写到一个文件里面
执行完成
进行查看。已经写进去了。 前面的u 是 unicode的意思。
我们也可以将变量写在 inventory 的 hosts文件中,也可以使用ansible直接调
看以下。我们在hosts文件中写变量 。
[root@master ansible]# cat /etc/ansible/hosts
[webser]
192.168.249.152 vartest="249.152" # 变量名一样, 值不一样
192.168.249.153 vattest="249.153" # 变量名一样, 值不一样
[daser]
192.168.249.154
修改 yaml文件
[root@master yaml]# cat var1.yaml
- hosts: webser
remote_user: root
tasks:
- name: write file
shell: 'echo -e "{{ ansible_all_ipv4_addresses }} \n {{vartest}}" > /tmp/anip.txt' # 直接调用在hosts里面写的变量vartest
执行完成
查看结果, 可以看到新的变量生效了。同样的变量名。值不一样。因为执行的机器不一样 。
条件测试
使用when,就是当触发了某些条件之后,才执行某些模块。
注意 这个和 hanler不一样 。 handler是当模块发生变化之后,才会触发。 when是有触发条件的。
看以下
我们写一个palybook。 条件触发时,在某一台机器才创建某个用户。
事先在hosts文件中定义变量
[root@master ansible]# cat hosts
[webser]
192.168.249.152 vartest="249.152" var="hahaha"
192.168.249.153 vartest="249.153" var="yayaya"
[daser]
192.168.249.154
写playbook,就是在192.168.249.153 的机器上面创建 tes153
[root@master ansible]# cat yaml/condition.yaml
- hosts: webser
remote_user: root
vars: # 使用变量
- username: tes153
tasks: # 创建task
- name: create {{ username }} user
user: name={{ username }}
when: var == "yayaya" # 触发条件。 但是这边的条件貌似只能是字母。 ip的好像不能触发。
执行。 我们看到只有153 执行了。
验证一下。我们看到 152 是空值。 153才有这个用户。
迭代循环
当需要有重复执行的任务时, 可以使用迭代机制。使其内容格式将为需要迭代的内容定义为item变量引用。 并通过with_item语句在指明迭代的元素列表即可。
就是类似于 循环执行
[root@master yaml]# cat items.yaml
- hosts: webser
remote_user: root
tasks:
- name: create user and use items
user: name="{{ item }}" state=present ## 等号后面不能有空格,
with_items: ## 循环创建2个用户。
- wheel1
- wheel2
执行结果
验证,这样2个用户就都创建了。
Templates
当同一组机器中,需要使用不同的变量时。我们可以使用tomplates 模块。 然后在hosts和 有区别的配置中使用变量。
这边有1台webservice。 现在我们webserer需要启动不同的端口。
我们进行以下操作。
准备配置文件 ,我们将模板使用httpd的配置文件的监听端口进行修改成变量
cat /home/template/httpd.conf.ansible # 这个是本机的httpd 配置模板文件。 路径自定义。
然后我们把这个变量写到ansible的hosts里面
[root@master yaml]# cat /etc/ansible/hosts
[webser]
192.168.249.152 httpd_port=8008
192.168.249.153 httpd_port=8009
[daser]
192.168.249.154
然后我们写playbook,使用template模块。其他的和之前的那个差不多 。
[root@master template]# cat /etc/ansible/yaml/httpd.yaml
- hosts: webser
remote_user: root
tasks:
- name : install httpd service
yum : name=httpd state=latest
- name : Edit configuration for httpd
template: src=/home/template/httpd.conf.ansible dest=/etc/httpd/conf/httpd.conf # 注意这边使用了template模块。而不是之前的copy模块
notify:
- restart htttpd
- name : start httpd service
service : name=httpd state=started
handlers:
- name: restart htttpd
service: name=httpd state=restarted
执行完成
查看验证,2台主机使用了不一样的监听端口。
tags
可以给你要运行的任务打上tag。这样 有的任务就不会重复执行了。
看下面的playbook。 我们只运行修改配置文件的tasks(这个tasks包含重启的 handler)。 其他的都不运行。
[root@localhost yaml]# cat httpd.yaml
- hosts: web
remote_user: root
vars:
- packages: httpd
- soft: httpd
tasks:
- name : install httpd service
yum : name={{ packages }} state=latest
- name : Edit configuration for httpd
copy : src=/home/project/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify:
- restart htttpd
tags: ## 使用tags
- conf ## 这个是tags的名字
- name : start httpd service
service : name={{ soft }} state=started
handlers:
- name: restart htttpd
service: name={{ soft }} state=restarted
修改/home/project/conf/httpd.conf 这个http的 模块配置文件。 修改他的监听端口
运行playbook
ansible-playbook httpd.yaml --tags='conf'
## 指令tag。 这个tag的名字是我们在playbook中定义好的
执行,我们看到只有修改配置文件的tasks 运行了。 其他的tasks没有运行。
验证一下,就完成了。
roles
Playbook 同样可以使用 include 引用其他 playbook 文件中的 play。这时被引用的 play 会被插入到当前的 playbook 中,当前的 playbook 中就有了一个更长的的 play 列表。
我们使用一些目录在规范playbooks里面的参数
创建相关目录
mkdir -pv /home/ansible_playbook/roles/{webser,dbser}/{defaults,tasks,files,templates,meta,handlers,vars}
[root@localhost ansible_playbook]# tree /home/ansible_playbook/roles/
/home/ansible_playbook/roles/
├── dbser ## 角色 1
│ ├── defaults ## 放静态文件的。比如config文件
│ ├── files ## ansible中unarchive、copy等模块会自动来这里找文件,从而我们不必写绝对路径,只需写文件名
│ ├── handlers ## 存放tasks中的notify指定的内容
│ ├── meta ## 定义各种依赖关系等信息。
│ ├── tasks ## 存放playbook的目录,其中main.yml是主入口文件,在main.yml中导入其他yml文件,要采用import_tasks关键字,include要弃用了
│ ├── templates ## 存放模板文件。template模块会将模板文件中的变量替换为实际值,然后覆盖到客户机指定路径上
│ └── vars ## 存放变量的
└── webser ## 角色 2
├── defaults
├── files
├── handlers
├── meta
├── tasks
├── templates
└── vars
我们写一个简单的roles
准备本地的配置文件
cp -rp /etc/httpd/conf/httpd.conf ansible_playbook/roles/webser/files/ # 将httpd的配置当做本地文件使用,ansible里面的copy会自动在file目录下找文件
写tasks,单独写playbook的 tasks就可以 。
[root@localhost ansible_playbook]# cat /home/ansible_playbook/roles/webser/tasks/main.yml
- name: install httpd package ## 安装http
yum: name=httpd
- name: install configuration file ## 修改文件
copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf
tags: ## 定义tag
- conf
notify: ## 定义 notify
- restart httpd
- name: start httpd ## 重启
service: name=httpd state=started
因为写了notify,所以要写 handler
[root@localhost ansible_playbook]# cat /home/ansible_playbook/roles/webser/handlers/main.yml
- name: restart httpd
service: name=httpd state=started
然后写主要的 playbook文件
[root@localhost ansible_playbook]# cat /home/ansible_playbook/site.yml ## 注意 这里的路径,一定是在ansible_playbook 这个下面。
- hosts: web ## 这里hosts 是 ansible的hosts定义的文件
remote_user: root
roles:
- webser ## 这里的 role名字 是我们role 目录结构中定义的角色目录的名字
至此,我们就可以运行了
[root@localhost ansible_playbook]# pwd
/home/ansible_playbook
[root@localhost ansible_playbook]# ansible-playbook site.yml
查看结果。 完成。
然后我们写一个多role的 playbook
之前我们有分webser和 dbser的role。 可以写到一起执行
sudo cp -rp /etc/my.cnf /home/ansible_playbook/roles/dbser/files/ ## 配置配置文件,到相关目录下
写task文件,就是web的类似。 安装mysql。 修改配置,重启服务
[root@localhost yum.repos.d]# cat /home/ansible_playbook/roles/dbser/tasks/main.yml
- name: install mysql-server
yum: name=mysql-community-server state=present
- name: install configuration file
copy: src=my.cnf dest=/etc/my.cnf
tags:
- myconf
notify: ## 需要notify
- restart mysqld
- name: start mysqld service
service: name=mysqld state=started
写handler文件
[root@localhost yum.repos.d]# cat /home/ansible_playbook/roles/dbser/handlers/main.yml
- name: restart mysqld
service: name=mysqld state=restarted
然后写site文件
[root@localhost yum.repos.d]# cat /home/ansible_playbook/site.yml
- hosts: web ## 第一个 host web用户
remote_user: root
roles: ## 使用webser的role
- webser
- hosts: 192.168.144.173 ## 第二个 可以直接写ip
remote_user: root
roles: ## 可以使用 多个role。 这样这个ip 就拥有多个role的角色了。
- dbser
- webser
然后执行
ansible-playbook site.yml
查看结果,完成。
在Centos7 中 ,默认是没有mysql,是madiaDB。 如果要装mysql的话。 需要手动下载repo文件。
cd /etc/yum.repos.d
wget 'https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm'
rpm -Uvh mysql57-community-release-el7-11.noarch.rpm
yum install -y mysql-community-server
rpm -qa | grep mysql
然后我们的db的tasks可以这个写 。
[root@localhost tasks]# cat /home/ansible_playbook/roles/dbser/tasks/main.yml
- name: download rpm package ## 手动下载rpm文件
shell: wget -P /etc/yum.repos.d/ 'https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm'
- name: install rpm ## 安装这个rpm。 安装完后,就有了mysql的repo文件。 就能yum了。
shell: rpm -ivh /etc/yum.repos.d/mysql57-community-release-el7-11.noarch.rpm
- name: install mysql-server
yum: name=mysql-community-server state=present
- name: install configuration file
copy: src=my.cnf dest=/etc/my.cnf
tags:
- myconf
notify:
- restart mysqld
- name: start mysqld service
service: name=mysqld state=started