读前请预习: Ansible基本用法
剧本playbook的使用
当需要执行的任务有多个时,需要一条一条编辑ansible命令,然后执行,而且当需要重复执行时,又要重新编辑执行,这样效率不高,因此ansible就可以利用playbook来完成将任务写到一个YAML格式的文件中,然后利用ansible-playbook进行调用该文件,从而实现了多条语句,可重复执行的效果,类似shell脚本的效果,ansible的playbook要借助YAML文件来实现,YAML文件扩展名通常为.yaml或.yml
playbook的基础组件:
- hosts:运行指定任务的而目标主机,多个主机用:冒号分隔
- remote_user:在远程主机上执行任务的用户;可以全局指定,也可以单个 * 任务指定
- sudo_user:表示以sudo方式运行任务时,切换为哪个用户身份运行
- tasks: 任务列表
- Handlers: 在发生改变时执行的操作
- vars:变量的使用。一种为用户自己定义的变量;一种为facts获取的变量(即ansible crazyting2 -m setup查到的变量)
一个playbook小示例:
- 编写playbook文件
[root@crazyting1 ~]# cat playbooktest.yml
- hosts: crazyting2 # 主机
remote_user: root # 远程用户
tasks: # 任务
- name: add group
group: name=new state=present # 组资源
- name: add user
user: name={{item}} group=new # 用户资源
with_items: # 循环 with_items with_nested with_dict with_random_choice
- new1
- new2
- new3
- hosts: crazyting2 # 主机
remote_user: root # 远程用户
vars: # 定义变量
- var1: "hello world!"
tasks: # 任务
- name: file
file: src=/root/install.log dest=/tmp/install.log state=link owner=nobody group=nobody # file组件
notify: # 通知触发handlers
- log
- log2
handlers:
- name: log
shell: echo "{{var1}} `date`" >> /tmp/install.log
- name: log2
shell: echo "{{ansible_nodename}} `date`" >> /tmp/install.log # 通过facts获取的系统的变量
when: ansible_nodename == "crazyting2" # 条件判断
- 测试playbook脚本
[root@crazyting1 ~]# ansible-playbook --check playbooktest.yml
PLAY [crazyting2] ****************************************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************************************
ok: [crazyting2]
TASK [add group] *****************************************************************************************************************************************
changed: [crazyting2]
TASK [add user] ******************************************************************************************************************************************
changed: [crazyting2] => (item=new1)
changed: [crazyting2] => (item=new2)
changed: [crazyting2] => (item=new3)
PLAY [crazyting2] ****************************************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************************************
ok: [crazyting2]
TASK [file] **********************************************************************************************************************************************
changed: [crazyting2]
RUNNING HANDLER [log] ************************************************************************************************************************************
skipping: [crazyting2]
RUNNING HANDLER [log2] ***********************************************************************************************************************************
skipping: [crazyting2]
PLAY RECAP ***********************************************************************************************************************************************
crazyting2 : ok=5 changed=3 unreachable=0 failed=0
- 运行playbook
[root@crazyting1 ~]# ansible-playbook playbooktest.yml
PLAY [crazyting2] ****************************************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************************************
ok: [crazyting2]
TASK [add group] *****************************************************************************************************************************************
changed: [crazyting2]
TASK [add user] ******************************************************************************************************************************************
changed: [crazyting2] => (item=new1)
changed: [crazyting2] => (item=new2)
changed: [crazyting2] => (item=new3)
PLAY [crazyting2] ****************************************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************************************
ok: [crazyting2]
TASK [file] **********************************************************************************************************************************************
changed: [crazyting2]
RUNNING HANDLER [log] ************************************************************************************************************************************
changed: [crazyting2]
RUNNING HANDLER [log2] ***********************************************************************************************************************************
changed: [crazyting2]
PLAY RECAP ***********************************************************************************************************************************************
crazyting2 : ok=7 changed=5 unreachable=0 failed=0
- 到crazyting2检查一下
[root@crazyting2 ~]# tail -2 /tmp/install.log
*** FINISHED INSTALLING PACKAGES ***hello world! Tue Feb 11 22:58:43 CST 2020
crazyting2 Tue Feb 11 22:58:43 CST 2020
[root@crazyting2 ~]# cat /etc/group |grep new
new:x:500:
[root@crazyting2 ~]# grep new /etc/shadow
new1:!!:18303:0:99999:7:::
new2:!!:18303:0:99999:7:::
new3:!!:18303:0:99999:7:::
Ansible角色
角色是一种官方提供开发标准和规范。按照该目录结构搭建ansible playbook,从而达到各组件的分离和解耦。使用role组织playbook是官方提供的最佳实践。
完整项目的结构如下:
production # 关于生产环境服务器的清单文件
stage # 关于 stage 环境的清单文件
group_vars/
group1 # 这里我们给特定的组赋值
group2 # ""
host_vars/
hostname1 # 如果系统需要特定的变量,把它们放置在这里.
hostname2 # ""
library/ # 如果有自定义的模块,放在这里(可选)
filter_plugins/ # 如果有自定义的过滤插件,放在这里(可选)
site.yml # master playbook 主 playbook
webservers.yml # playbook for webserver tier Web 服务器的 playbook
fooservers.yml # playbook for dbserver tier 数据库服务器的 playbook
roles/
common/
files/ # 存放文件和脚本,copy模块文件搜索路径
templates/ # 模版存放路径
tasks/ # 存放playbooks路径
handlers/ # notify调用部分playbook存放路径
vars/ # roles内变量存放路径
defaults/ # 默认寻找路径
meta/ # 存放元数据,如作者信息,角色信息等
webservers/
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
编写一个nginx自动安装示例:
[root@crazyting1 ~]# mkdir -p ~/ansible/roles/nginx/{defaults,files,handlers,meta,tasks,templates,vars}
[root@crazyting1 ansible]# cat beta
[crazyting]
crazyting2
[root@crazyting1 ansible]# cat roles/nginx/templates/nginx.conf.j2 | head
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes {{ansible_processor_vcpus*2}};
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
[root@crazyting1 ansible]# cat roles/nginx/tasks/group.yml
- name: create group
group: name=nginx
[root@crazyting1 ansible]# cat roles/nginx/tasks/user.yml
- name: create user
user: name=nginx group=nginx system=yes shell=/sbin/nologin
[root@crazyting1 ansible]# cat roles/nginx/tasks/yum.yml
- name: install nginx
yum: name=nginx
[root@crazyting1 ansible]# cat roles/nginx/tasks/templ.yml
- name: copy conf
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
[root@crazyting1 ansible]# cat roles/nginx/tasks/start.yml
- name: start
service: name=nginx state=started enabled=yes
[root@crazyting1 ansible]# cat roles/nginx/tasks/main.yml
- include: group.yml
- include: user.yml
- include: yum.yml
- include: templ.yml
- include: start.yml
[root@crazyting1 ansible]# cat sit.yml
- hosts: crazyting
remote_user: root
roles:
- role: nginx #制定role角色名,就是roles下的目录
[root@crazyting1 ~]# tree ansible/
ansible/
├── beta
├── roles
│ └── nginx
│ ├── defaults
│ ├── files
│ ├── handlers
│ ├── meta
│ ├── tasks
│ │ ├── group.yml
│ │ ├── main.yml
│ │ ├── restart.yml
│ │ ├── start.yml
│ │ ├── templ.yml
│ │ ├── user.yml
│ │ └── yum.yml
│ ├── templates
│ │ └── nginx.conf.j2
│ └── vars
└── sit.yml
[root@crazyting1 ansible]# ansible-playbook -i beta -C sit.yml
PLAY [crazyting] ***************************************************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************************************************
ok: [crazyting2]
TASK [nginx : create group] ****************************************************************************************************************************************************************
changed: [crazyting2]
TASK [nginx : create user] *****************************************************************************************************************************************************************
changed: [crazyting2]
TASK [nginx : install nginx] ***************************************************************************************************************************************************************
changed: [crazyting2]
TASK [nginx : copy conf] *******************************************************************************************************************************************************************
changed: [crazyting2]
TASK [nginx : start] ***********************************************************************************************************************************************************************
changed: [crazyting2]
PLAY RECAP *********************************************************************************************************************************************************************************
crazyting2 : ok=6 changed=5 unreachable=0 failed=0
执行并检查
[root@crazyting1 ansible]# ansible crazyting2 -m setup | grep vcpus
"ansible_processor_vcpus": 2,
[root@crazyting1 ansible]# ansible-playbook -i beta sit.yml
PLAY [crazyting] ***************************************************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************************************************
ok: [crazyting2]
TASK [nginx : create group] ****************************************************************************************************************************************************************
changed: [crazyting2]
TASK [nginx : create user] *****************************************************************************************************************************************************************
changed: [crazyting2]
TASK [nginx : install nginx] ***************************************************************************************************************************************************************
changed: [crazyting2]
TASK [nginx : copy conf] *******************************************************************************************************************************************************************
changed: [crazyting2]
TASK [nginx : start] ***********************************************************************************************************************************************************************
changed: [crazyting2]
PLAY RECAP *********************************************************************************************************************************************************************************
crazyting2 : ok=6 changed=5 unreachable=0 failed=0
[root@crazyting2 ~]# service nginx status
nginx: unrecognized service
[root@crazyting2 ~]# service nginx status
nginx (pid 26134) is running...
[root@crazyting2 ~]# grep nginx /etc/shadow
nginx:!!:18304::::::
[root@crazyting2 ~]# grep nginx /etc/group
nginx:x:501:
[root@crazyting2 ~]# head /etc/nginx/nginx.conf
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes 4;
参考资料:
Ansible之Playbook详解、案例
Ansible角色详解
Ansible中文权威指南(建议看下playbook最佳实践)
Ansible 自动化运维工具简单入门