接(上篇)自动化运维工具:ansible(一)
13、ansible系列命令
1>ansible-galaxy
连接https://galaxy.ansible.com下载相应的roles(角色)
列出所有已安装的galaxy
- ansible-galaxy list
安装galaxy
- ansible-galaxy install geerlingguy.redis
删除galaxy
- ansible-galaxy remove geerlingguy.redis
2>ansible-pull 推送命令至远程,效率无限提升,对运维要求较高
3>Ansible-playbook
(1)playbook是由一个或多个 "play" 组成的列表,采用YAML语言编写。 play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色。从根本上来讲,所谓task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让它们联同起来按事先编排的机制同唱一台大戏。
(2)YAML是一个个可读性高的用来表达资料序列的格式。YAML参考了其他多种语言,包括:XML、C语言、Python、 Perl以及电子邮件格式RFC2822等。 YAML Ain't Markup Language,即YAML不是XML。不过,在开发的这种语言时,YAML的意思其实是:"Yet Another Markup Language" (仍是一种标记语言)
特性:
- YAML的可读性好
- YAML和脚本语言的交互性好
- YAML使用实现语言的数据类型
- YAML有一个一致的信息模型
- YAML易于实现
- YAML可以基于流来处理
- YAML表达能力强,扩展性好
更多的内容及规范参见http://www.yaml.org
(3)在单一档案中,可用连续三个连字号(一)区分多个档案。另外,还有选择性的连续三个点号(...)用来表示档案结尾次行开始正常写Playbook的内容,一般建议写明该Playbook的功能 使用#号注释代码
- 缩进必须是统一的,不能空格和tab混用
- 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的
- YAML文件内容和Linux系统大小写判断方式保持一致,是区别大小写的,k/v的值均需大小写敏感
- k/v的值可同行写也可换行写。同行使用:分隔
- v可是个字符串,也可是另一个列表
- 一个完整的代码块功能需最少元素需包括name: task
- 一个name只能包括一个task
- YAML文件扩展名通常为yml或yaml
(4)List:列表,其所有元素均使用"-"打头
示例:
[root@ansible ansible]#cat file.yml
---
- hosts: webserver #一个hosts列表,定义针对的列表主机
remote_user: root
tasks: #任务
- name: create new file #任务列表1
file: name=/root/newfile state=touch
- name: create new user #任务列表2
user: name=test system=yes shell=/sbin/nologin
(5)Dictionary:字典,通常由多个key与value构成
示例:
# An employee record
name: Example Developer
job: Developer
skill: Elite
也可以将key:value放置于{}中进行表示,用","分隔多个key:value
# An employee record
{name: Example Developer, job: Developer, skill: Elite}
(6)Hosts:执行的远程主机列表
playbook中的每一个play的目的都是为了让某个或某些主机以某个指定的用户身份执行任务。hosts用于指定要执行指定任务的主机,须事先定义在主机清单中。
可以是如下形式:
- one.example.com
- one.example.com:two.example.com
- 192.168.100.10
- 192.168.100.*
- webserver:dbserver 两个组的并集
- webserver:&dbserver 两个组的交集
- webservers:!dbserver 在webserver组,但不在dbserver组
- all /etc/ansible/hosts主机清单中的所有主机
---
- hosts: all #主机清单中的所有主机
remote_user: root
tasks: #任务
......
(7)task列表和action
?play的主体部分是task list,task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后再开始第二个。在运行自下而下某playbook时,如果中途发生错误,所有已执行任务都将回滚,因此,在更正playbook后重新执行一次即可。
?task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致。
?每个task都应该有其name,用于playbook的执行结果输出,建议其内容尽可能清晰地描述任务执行步骤,如果未提供name,则action的结果将用于输出。
tasks:任务列表
格式:
- action: module arguments
- module: arguments #建议使用
?注意:shell和command模块后面跟命令,而非key=value
某任务的状态在运行后为changed时,可通过"notify"通知给相应的 handlers
handlers(触发器)和notify(通知)结合使用触发条件Handlers是task列表,这些task与前述的task并没有本质上的不同,用于当关注的资源发生变化时,才会采取一定的操作Notify此action可用于在每个play的最后被触发,这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作称为handler,也即notify中调用handler中定义的操作。
#编辑httpd.yml,实现httpd的安装,配置文件更改,服务启动
#问题:第一次启动后,更改httpd的配置文件,第二次再执行,会因为之前启动了,而无法重启服务
#解决:通过设置"notify",当某任务的状态在运行后为changed时,通知给相应的 handlers ,触发相应的命令
[root@ansible ansible]#vim httpd.yml
---
- hosts: all
remote_user: root
tasks:
- name: install httpd package
yum: name=httpd
- name: copy conf file
copy: src=/etc/httpd/conf/httpd.conf dest=/etc/httpd/conf/ backup=yes
notify: restart service
- name: start service
service: name=httpd state=started enabled=yes
handlers:
- name: restart service
service: name=httpd state=restarted
?任务可以通过"tags"打标签,而后可在ansible-playbook命令上使用-t指定进行调用
[root@ansible ansible]#ansible all -m yum -a 'name=httpd state=absent'
[root@ansible ansible]#ansible all -m shell -a 'rpm -q httpd'
[WARNING]: Consider using the yum, dnf or zypper module rather than running 'rpm'.
If you need to use command because yum, dnf or zypper is insufficient you can add
'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg
to get rid of this message.
192.168.100.20 | FAILED | rc=1 >>
未安装软件包 httpd non-zero return code
192.168.100.10 | FAILED | rc=1 >>
未安装软件包 httpd non-zero return code
通过ansible卸载httpd,在通过tags标签指定只下载httpd
[root@ansible ansible]#ansible-playbook -t install -C httpd.yml
PLAY [all] *************************************************************************
TASK [Gathering Facts] *************************************************************
ok: [192.168.100.20]
ok: [192.168.100.10]
TASK [install httpd package] *******************************************************
changed: [192.168.100.20]
changed: [192.168.100.10]
PLAY RECAP *************************************************************************
192.168.100.10 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.100.20 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansible ansible]#ansible-playbook -t install httpd.yml
PLAY [all] *************************************************************************
TASK [Gathering Facts] *************************************************************
ok: [192.168.100.20]
ok: [192.168.100.10]
TASK [install httpd package] *******************************************************
changed: [192.168.100.10]
changed: [192.168.100.20]
PLAY RECAP *************************************************************************
192.168.100.10 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.100.20 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansible ansible]#ansible all -m shell -a 'rpm -q httpd'
[WARNING]: Consider using the yum, dnf or zypper module rather than running 'rpm'.
If you need to use command because yum, dnf or zypper is insufficient you can add
'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg
to get rid of this message.
192.168.100.20 | CHANGED | rc=0 >>
httpd-2.4.6-67.el7.centos.x86_64
192.168.100.10 | CHANGED | rc=0 >>
httpd-2.4.6-67.el7.centos.x86_64
[root@ansible ansible]#ansible all -m shell -a 'ss -ntl | grep 80'
192.168.100.20 | FAILED | rc=1 >>
non-zero return code
192.168.100.10 | FAILED | rc=1 >>
non-zero return code
(8)运行playbook
如果命令或脚本的退出码不为零,可以使用如下方式替代
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand || /bin/true
或者使用ignore_errors来忽略错误信息:
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand
ignore_errors: True
运行playbook的方式
ansible-playbook <filename.yml> ... [options]
常见选项:
--check只检测可能会发生的改变,但不真正执行操作
--list-hosts 列出运行任务的主机
--limit主机列表只针对主机列表中的主机执行
-v显示过程-vv -vvv 更详细
示例:
ansible-playbook file.yml --check #只检测
ansible-playbook file.yml #执行
ansible-playbook file.yml --limit webserver
(9)ansible-playbook支持变量:
变量名:仅能由字母、数字和下划线组成,且只能以字母开头
变量来源:
1.ansible setup facts远程主机的所有变量都可直接调用
2.在/etc/ansible/hosts中定义
- 普通变量:主机组中主机单独定义,优先级高于公共变量
- 公共(组)变量:针对主机组中所有主机定义统一变量
3.通过命令行指定变量,优先级最高
- ansible-playbook -e varname=value
4.在playbook中定义
[root@ansible ansible]#vim apps.yml
---
- hosts: all
remote_user: root
tasks:
- name: install package
yum: name={{ pkname }} #定义变量
- name: start service
service: name={{ pkname }} state=started enabled=yes
[root@ansible ansible]#ansible-playbook -e 'pkname=vsftpd' -C apps.yml
PLAY [all] *************************************************************************
TASK [Gathering Facts] *************************************************************
ok: [192.168.100.20]
ok: [192.168.100.10]
TASK [install package] *************************************************************
changed: [192.168.100.20]
changed: [192.168.100.10]
TASK [start service] ***************************************************************
changed: [192.168.100.10]
changed: [192.168.100.20]
PLAY RECAP *************************************************************************
192.168.100.10 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.100.20 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansible ansible]#ansible-playbook -e 'pkname=vsftpd' apps.yml
PLAY [all] *************************************************************************
TASK [Gathering Facts] *************************************************************
ok: [192.168.100.10]
ok: [192.168.100.20]
TASK [install package] *************************************************************
changed: [192.168.100.20]
changed: [192.168.100.10]
TASK [start service] ***************************************************************
changed: [192.168.100.10]
changed: [192.168.100.20]
PLAY RECAP *************************************************************************
192.168.100.10 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.100.20 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansible ansible]#ansible all -m shell -a 'ss -ntl|grep 21'
192.168.100.20 | CHANGED | rc=0 >>
LISTEN 0 32 :::21 :::*
192.168.100.10 | CHANGED | rc=0 >>
LISTEN 0 32 :::21 :::*
也可以在playbook中,定义vars
也可以使用变量文件:
[root@ansible ansible]#vim vars.yml
var1: httpd
var2: vsftpd
[root@ansible ansible]#vim testvar.yml
---
- hosts: all
remote_user: root
vars_files:
- vars.yml
tasks:
- name: install package
yum: name={{ var1 }}
- name: create file
file: name=/root/{{ var2 }}.log state=touch
[root@ansible ansible]#ansible-playbook -C testvar.yml
......
[root@ansible ansible]#ansible-playbook testvar.yml
......
[root@ansible ansible]#ansible all -a 'ls /root'
192.168.100.20 | CHANGED | rc=0 >>
......
vsftpd.log
192.168.100.10 | CHANGED | rc=0 >>
......
vsftpd.log
[root@ansible ansible]#ansible all -m shell -a 'rpm -q httpd'
[WARNING]: Consider using the yum, dnf or zypper module rather than running 'rpm'.
If you need to use command because yum, dnf or zypper is insufficient you can add
'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg
to get rid of this message.
192.168.100.20 | CHANGED | rc=0 >>
httpd-2.4.6-67.el7.centos.x86_64
192.168.100.10 | CHANGED | rc=0 >>
httpd-2.4.6-67.el7.centos.x86_64
5 在role中定义
变量定义:key=value
示例:http_port=80
变量调用方式:
- 通过{{ variable_name }}调用变量,且变量名前后必须有空格,有时用"{{ variable_ name}}" 才生效
- ansible playbook -e选项指定
4>Ansible-vault
功能:管理加密解密yml文件
ansible-vault [create |decrypt| edit encrypt|rekey |view]
ansible-vault encrypt hello.yml 加密
ansible-vault decrypt hello.yml 解密
ansible-vault view hello.yml 查看
ansible-vault edit hello.yml 编辑加密文件
ansible-vault rekey hello.yml 修改口令
ansible-vault create new.yml 创建新文件
5>Ansible-console:2.0+新增,可交互执行命令,支持tab
root@test (2)[f:10] $
执行用户@当前操作的主机组(当前组的主机数量)[f:并发数]$
?设置并发数:forksn 例如:forks 10
?切换组:cd主机组 例如:cd web
?列出当前组主机列表:list
?列出所有的内置命令:?或help
?示例:
[root@ansible ~]#ansible-console
Welcome to the ansible console.
Type help or ? to list commands.
root@all (2)[f:5]$ cd webserver
root@webserver (1)[f:5]$ forks 10
root@webserver (1)[f:10]$ command hostname
192.168.100.10 | CHANGED | rc=0 >>
node1
root@webserver (1)[f:10]$ shell ls /root
192.168.100.10 | CHANGED | rc=0 >>
anaconda-ks.cfg
hello.sh
hello.sh.4604.2020-03-17@21:14:22~
14、模板templates
文本文件,嵌套有脚本(使用模板编程语言编写)
Jinja2语言,使用字面量,有下面形式
- 字符串:使用单引号或双引号
- 数字:整数,浮点数
- 列表: [item1, item2, ...]
- 元组: (item1, item2, ...)
- 字典: {key1:value1, key2:value2, ...}
- 布尔型: true/false
- 算术运算: +,-, *,/.// %,**
- 比较操作: ==,!=,>,>=, <, <=
- 逻辑运算: and, or, not
- 流表达式: For If When
templates功能:根据模块文件动态生成对应的配置文件
templates文件必须存放于templates目录下,且命名为.j2结尾
yamI/yml文件需和templates目录平级,目录结构如下:
├── ansible
└── templates
#实例:配置nginxtemplates模板文件,使不同主机的worker进程数量=CPU*2
[root@ansible ~]#mkdir ansiable/templates
[root@ansible ~]#tree -d
.
├── ansible
│ └── templates
└── bin
[root@ansible ansible]#ansible webserver -m setup | grep "processor" #查看CPU变量名
"ansible_processor": [
"ansible_processor_cores": 1,
"ansible_processor_count": 1,
"ansible_processor_threads_per_core": 1,
"ansible_processor_vcpus": 1,
[root@ansible ansible]#cp /etc/nginx/nginx.conf ./templates/nginx.conf.j2
[root@ansible ansible]#vim templates/nginx.conf.j2
[root@ansible ansible]#vim testtempl.yml
---
- hosts: webserver
remote_user: root
tasks:
- name: install paskage
yum: name=nginx
- name: copy template
tempate: src=/root/ansible/templates/nginx.conf.j2 dest=/etc/nginx/nginx.conf
- name: start service
service: name=nginx state=started enabled=yes
[root@ansible ansible]#ansible-playbook testtempl.yml
when语句:
条件测试:如果需要根据变量、facts或此前任务的执行结果来作为某task执行与否的前提时要用到条件测试,通过when语句实现,在task中使用,jinja2的语法
格式:
- 在task后添加when子句即可使用条件测试;when语句支持Jinja2表达式语法
- 对不同centos版本针对配置
[root@ansible ansible]#ansible all -m setup -a 'filter="*distribution*"'
192.168.100.20 | SUCCESS => {
"ansible_facts": {
"ansible_distribution": "CentOS",
"ansible_distribution_file_parsed": true,
"ansible_distribution_file_path": "/etc/redhat-release",
"ansible_distribution_file_variety": "RedHat",
"ansible_distribution_major_version": "7",
"ansible_distribution_release": "Core",
"ansible_distribution_version": "7.4",
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
192.168.100.10 | SUCCESS => {
"ansible_facts": {
"ansible_distribution": "CentOS",
"ansible_distribution_file_parsed": true,
"ansible_distribution_file_path": "/etc/redhat-release",
"ansible_distribution_file_variety": "RedHat",
"ansible_distribution_major_version": "7",
"ansible_distribution_release": "Core",
"ansible_distribution_version": "7.4",
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
迭代:当有需要重复性执行的任务时,可以使用迭代机制
对迭代项的引用,固定变量名为"item"
要在task中使用with_items给定要迭代的元素列表
列表格式:
- 字符串
- 字典
迭代嵌套子变量
[root@ansible ansible]#cat testitem.yml
---
- hosts: all
remote_user: root
tasks:
- name: create some groups
group: name={{ item }}
with_items:
- g1
- g2
- g3
- name: create some users
user: name={{ item.name }} group={{ item.group }}
with_items:
- { name: 'user1', group: 'g1' }
- { name: 'user2', group: 'g2' }
- { name: 'user3', group: 'g3' }
playbook中的template for if:
[root@ansible ansible]#cat templates/for1.conf.j2
{% for port in ports %}
server{
listen {{ port }}
}
{% endfor %}
[root@ansible ansible]#cat testfor.yml
---
- hosts: all
remote_user: root
vars:
ports:
- 81
- 82
- 83
tasks:
- name: copy conf
template: src=/root/ansible/templates/for1.conf.j2 dest=/root/for1.conf
[root@ansible ansible]#ansible-playbook -C testfor.yml
PLAY [all] *************************************************************************
TASK [Gathering Facts] *************************************************************
ok: [192.168.100.20]
ok: [192.168.100.10]
TASK [copy conf] *******************************************************************
changed: [192.168.100.10]
changed: [192.168.100.20]
PLAY RECAP *************************************************************************
192.168.100.10 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.100.20 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansible ansible]#ansible-playbook testfor.yml
PLAY [all] *************************************************************************
TASK [Gathering Facts] *************************************************************
ok: [192.168.100.20]
ok: [192.168.100.10]
TASK [copy conf] *******************************************************************
changed: [192.168.100.10]
changed: [192.168.100.20]
PLAY RECAP *************************************************************************
192.168.100.10 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.100.20 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node1节点查看:
[root@node1 ~]# cat for1.conf
server{
listen 81
}
server{
listen 82
}
server{
listen 83
}
[root@ansible ansible]#cat testfor2.yml
---
- hosts: all
remote_user: root
vars:
ports:
- listen_port: 80
- listen_port: 82
- listen_port: 83
tasks:
- name: copy conf
template: src=/root/ansible/templates/for2.conf.j2 dest=/root/for2.conf
[root@ansible ansible]#cat templates/for2.conf.j2
{% for port in ports %}
server{
listen {{ port.listen_port }}
}
{% endfor %}
[root@ansible ansible]#ansible-playbook testfor2.yml
PLAY [all] *************************************************************************
TASK [Gathering Facts] *************************************************************
ok: [192.168.100.20]
ok: [192.168.100.10]
TASK [copy conf] *******************************************************************
changed: [192.168.100.10]
changed: [192.168.100.20]
PLAY RECAP *************************************************************************
192.168.100.10 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.100.20 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node1节点查看:
[root@node1 ~]# cat for2.conf
server{
listen 80
}
server{
listen 82
}
server{
listen 83
}
[root@ansible ansible]#cat testfor3.yml
---
- hosts: all
remote_user: root
vars:
ports:
- web1:
port: 81
name: web1.yang.com
rootdir: /root/website1
- web1:
port: 82
name: web2.yang.com
rootdir: /root/website2
- web1:
port: 83
name: web3.yang.com
rootdir: /root/website3
tasks:
- name: copy conf
template: src=/root/ansible/templates/for3.conf.j2 dest=/root/for3.conf
[root@ansible ansible]#cat templates/for3.conf.j2
{% for p in ports %}
server{
listen {{ p.port }}
servername {{ p.name }}
documentroot {{ p.rootdir }}
}
{% endfor %}
[root@ansible ansible]#ansible-playbook testfor3.yml
PLAY [all] *************************************************************************
TASK [Gathering Facts] *************************************************************
ok: [192.168.100.20]
ok: [192.168.100.10]
TASK [copy conf] *******************************************************************
changed: [192.168.100.20]
changed: [192.168.100.10]
PLAY RECAP *************************************************************************
192.168.100.10 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.100.20 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node1节点查看:
[root@node1 ~]# cat for3.conf
server{
listen 81
servername web1.yang.com
documentroot /root/website1
}
server{
listen 82
servername web2.yang.com
documentroot /root/website2
}
server{
listen 83
servername web3.yang.com
documentroot /root/website3
}
[root@ansible ansible]#cat testfor4.yml
---
- hosts: all
remote_user: root
vars:
ports:
- web1:
port: 81
#name: web1.yang.com
rootdir: /root/website1
- web1:
port: 82
name: web2.yang.com
rootdir: /root/website2
- web1:
port: 83
#name: web3.yang.com
rootdir: /root/website3
tasks:
- name: copy conf
template: src=/root/ansible/templates/for4.conf.j2 dest=/root/for4.conf
[root@ansible ansible]#cat templates/for4.conf.j2
{% for p in ports %}
server{
listen {{ p.port }}
{% if p.name is defined %} #如果被定义了则生成,没有定义则不生成
servername {{ p.name }}
{% endif %}
documentroot {{ p.rootdir }}
}
{% endfor %}
[root@ansible ansible]#ansible-playbook testfor4.yml
PLAY [all] *************************************************************************
TASK [Gathering Facts] *************************************************************
ok: [192.168.100.10]
ok: [192.168.100.20]
TASK [copy conf] *******************************************************************
changed: [192.168.100.20]
changed: [192.168.100.10]
PLAY RECAP *************************************************************************
192.168.100.10 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.100.20 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node1节点查看:
[root@node1 ~]# cat for4.conf
server{
listen 81
documentroot /root/website1
}
server{
listen 82
servername web2.yang.com
documentroot /root/website2
}
server{
listen 83
documentroot /root/website3
}
15、roles
1>定义:ansilbe自1.2版本引入的新特性,用于层次性、结构化的组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。
复杂场景:建议使用roles,代码复用度高
- 变更指定主机或主机组
- 如命名不规范维护和传承成本大
- 某些功能需多个Playbook,通过Includes即可实现
2>roles目录结构
每个角色,以特定的层级目录结构进行组织
playbook.yml
roles/
project/
tasks/
files/
vars/ 不常用
default/ 不常用
templates/
handlers/
meta/ 不常用
/roles/project/:项目名称,有以下子目录
files/ : 存放由copy或script模块等调用的文件
templates/ : template模块查找所需要模板文件的目录
tasks/ : 定义task,role的基本元素,至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
handlers/ : 至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
vars/ : 定义变量,至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
meta/ : 定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为main.ymI的文件,其它文件需在此文件中通过include进行包含
default/ : 设定默认变量时使用此目录中的main.yml文件
3>使用:
角色(roles):角色集合
roles/(官方建议目录/etc/ansible/roles,不过也可以自定义)
- mysql/
- httpd/
- nginx/
- memcached/
[root@ansible ansible]#tree #构建目录结构,如果没有可以mkdir创建目录
.
└── roles
├── httpd
├── memcache
├── mysql
└── nginx
5 directories, 0 files
[root@ansible ansible]#cd roles/nginx/
[root@ansible nginx]#pwd
/root/ansible/roles/nginx
[root@ansible nginx]#mkdir tasks templates #在roles/nginx创建一个任务目录和模板目录
[root@ansible nginx]#ls
tasks templates
[root@ansible nginx]#cd tasks/ #进入任务tasks目录
[root@ansible tasks]#vim group.yml #先创建组文件
[root@ansible tasks]#cat group.yml
- name: create group
group: name=nginx gid=80
[root@ansible tasks]#vim user.yml #再创建用户文件
[root@ansible tasks]#cat user.yml
- name: create user
user: name=nginx uid=80 group=nginx system=yes shell=/sbin/nologin
[root@ansible tasks]#vim yum.yml #再创建安装文件
[root@ansible tasks]#cat yum.yml
- name: install package
yum: name=nginx
[root@ansible tasks]#vim start.yml #进而创建启动文件
[root@ansible tasks]#cat start.yml
- name: start service
service: name=nginx state=started enabled=yes
[root@ansible tasks]#cp start.yml restart.yml
[root@ansible tasks]#vim restart.yml #重启服务文件
[root@ansible tasks]#cat restart.yml
- name: restart service
service: name=nginx state=restarted
[root@ansible templates]#cd ../templates/ #进入模板templates目录
[root@ansible templates]#cp /etc/nginx/nginx.conf nginx.conf.j2 #拷贝本机的nginx文件成为模板文件
[root@ansible templates]#vim nginx.conf.j2
[root@ansible templates]#cd ../tasks/
[root@ansible tasks]#ls
group.yml restart.yml start.yml user.yml yum.yml
[root@ansible tasks]#vim templ.yml
[root@ansible tasks]#cat templ.yml #回到任务tasks目录,创建templ.yml文件
- name: copy conf
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
[root@ansible tasks]#ls
group.yml restart.yml start.yml templ.yml user.yml yum.yml
[root@ansible tasks]#vim main.yml #创建全局文件,定义调用各个板块文件的顺序
[root@ansible tasks]#cat main.yml
- include: group.yml
- include: user.yml
- include: yum.yml
- include: templ.yml
- include: start.yml
[root@ansible tasks]#cd ../../
[root@ansible roles]#ls
httpd memcache mysql nginx
[root@ansible roles]#cd ../
[root@ansible ansible]#ls
roles
[root@ansible ansible]#vim nginx_role.yml #创建nginx role文件,注意必须和roles同级
[root@ansible ansible]#cat nginx_role.yml
- hosts: all
remote_user: root
roles:
- role: nginx
[root@ansible ansible]#ansible-playbook -C nginx_role.yml #检查语法
[root@ansible ansible]#ansible-playbook nginx_role.yml #执行
总结:构建目录树结构如下
[root@ansible ansible]#tree
.
├── nginx_role.yml
└── roles
├── httpd
├── memcache
├── mysql
└── nginx
├── tasks
│ ├── group.yml
│ ├── main.yml
│ ├── restart.yml
│ ├── start.yml
│ ├── templ.yml
│ ├── user.yml
│ └── yum.yml
└── templates
└── nginx.conf.j2
7 directories, 9 files
感谢作者:我听过
出处:http://dwz.date/bYGu