yaml 语言应用在 ansible 中时,每一个 YAML 文件都是从一个列表开始. 列表中的每一项都是一个键值对,一般
被称为一个 “哈希” 或 “字典”。
ymal 有个小特点,所有的 YAML 文件开始行都应该是 “—”。 这是 YAML 格式的一部分, 表明一个文件的开始。
ansible 的 yaml 语法
---
# 一个美味水果的列表
- Apple
- Orange
- Strawberry
- Mango
---
# 一位职工的记录
name: Front-end Developer
job: Developer
skill: Brilliant
---
# 一位职工的记录
{ name: Front-end Developer, job: Developer, skill: Brilliant }
---
create_key: yes
needs_agent: no
knows_oop: True
likes_emacs: TRUE
uses_cvs: false
---
# 一位职工记录
name: stevenux
job: DevOps
skill: Excellent
employed: True
foods:
- Apple
- Orange
- Strawberry
- Mango
languages:
ruby: Lame
python: Fluent
dotnet: Lame
name: John Smith
age: 41
gender: Male
spouse:
name: Jane Smith
age: 37
gender: Female
children:
- name: Jimmy Smith
age: 17
gender: Male
- name: Jenny Smith
age 13
gender: Female
除了 yaml 格式,还有 xml 和 json 等数据交换格式,对比如下
ymal
---
# Employee records
- Employee one:
name: Alex
job: DevOps
skills:
- Python
- C/C++
- Ruby
- Employee two:
name: steve
job: DevOps
skills:
- Assambly
- C/C++
- vue
{
"EmpRecord": {
"Employee": [
{
"-id": "emp01",
"name": "Alex",
"job": "DevOps",
"skills": "python, C/C++, java"
},
{
"-id": "emp02",
"name": "Bob",
"job": "Front-end",
"skills": "lips, forton, REST APIs"
}
]
}
}
<EmpRecord>
<Employee id="emp01">
<name>Alexname>
<job>DevOpsjob>
<skills>python, C/C++, javaskills>
Employee>
<Employee id="emp02">
<name>Bobname>
<job>Front-endjob>
<skills>lips, forton, REST APIsskills>
Employee>
EmpRecord>
Hosts
被控制和管理的的远程主机列表Tasks
任务集,每个 task 完成某个简单任务Variables
内置变量或自定义变量在 playbook 中调用Templates
模板,可替换模板文件中的变量并实现一些简单逻辑的文件Handlers
和 notify
结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行tags
标签 指定某条任务执行,用于选择运行 playbook 中的部分代码。ansible 具有幂等性,因此/etc/ansible/hosts
)---
# 指定本playbook管理的主机为websrvs组的主机
- hosts: websrvs
或者
---
# 指定本playbook管理的主机为websrvs组的主机
- hosts: appsrvs
或者
---
# 指定本playbook管理的主机为appsrvs组和websrvs组的主机
- hosts: appsrvs:websrvs
或者
---
# 指定本playbook管理的主机为所有主机
- hosts: all
remote_user 可用于主机级别(针对某个主机使用某个身份执行任务)和 task 级别(针对某个 task 以某个用户身份
执行任务)
如:
---
- hosts: websrvs
remote_user: root # 针对主机级别
tasks:
- name: connection detect
ping:
remote_user: stevenux # 针对某个task任务
sudo: yes # 默认sudo为root
sudo_user:steve # sudo为steve
playbook 的大部分是需要进行的各项任务 task list,task list 中有一个或多个 task。各个 task 从上到下按
次序逐个在 hosts 中指定的所有主机上执行。在所有主机上完成第一个 task 后,再开始第二个 task。task 的
目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的2,多次执行是安全的,
因为其结果均一致每个 task 都应该有其 name,用于 playbook 的执行结果输出,建议其内容能清晰地描述任务
执行步骤。如果未提供 name,则 action 的结果将用于输出。
task 可以使用两种格式在 playbook 中定义
acton: module arguments
module: arguments
例如:
---
- hosts: websrvs
remote_user: root
tasks:
- name: install httpd
yum: name=httpd
- name: start httpd
service: name=httpd state=started enabled=yes
handlers 是一个或多个 task ,其中的 task 与前述的 task 并没有本质上的不同,只是当关注的资源发生变化时,
才会采取一定的操作。Notify 对应的 action 可用于在每个 playbook 的最后被触发,这样可避免多次有改变发生
时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。在 notify 中列出的操作称为
handler,也即 notify 中调用 handler 中定义的操作。
例如:
---
- hosts: websrvs
remote_user: root
tasks:
- name: Install httpd
yum: name=httpd state=present
- name: Install configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
notify: restart httpd # 定义notify
- name: ensure apache is running
service: name=httpd state=started enabled=yes
handlers:
- name: restart httpd # notify定义的操作完成后就运行此任务
service: name=httpd state=restarted
在 playbook 文件中,可以利用 tags 组件,为特定 task 指定标签。当在执行 playbook 时,可以只执行特定
tags 标识的 task,而非整个 playbook 文件
例如:
---
# httpd.yml
# use tags execute specific task
- hosts: websrvs
remote_user: root
tasks:
- name: Install httpd
yum: name=httpd state=present
- name: Install configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
tags: conf
- name: start httpd service
tags: service
service: name=httpd state=started enabled=yes
root@ubuntu1904:~#ansible-playbook -t conf,service httpd.yml
只执行 tags 标识的 task
---
# install httpd example
- hosts: websrvs
remote_user: root
tasks:
- name: Install httpd
yum: name=httpd state=present
- name: Install configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
- name: start service
service: name=httpd state=started enaled=yes
# remove httpd example
---
- hosts: websrvs
remote_user: root
tasks:
- name: remove httpd package
yum: name=httpd state=absent
- name: remove apache user
user: name=apache state=absent
- name: remove data file
file: name=/etc/httpd state=absent
---
- hosts: dbsrvs
remote_user: root
tasks:
- {name: create group, group: name=mysql system=yes gid=306}
- name: create user
user: name=mysql shell=/sbin/nologin system=yes group=mysql uid=306
home=/data/mysql create_home=no
---
# install nginx
- hosts: websrvs
remote_user: root
tasks:
- name: add group nginx
user: name=nginx state=present
- name: add user nginx
user: name=nginx state=present group=nginx
- name: Install Nginx
yum: name=nginx state=present
- name: Start Nginx
service: name=nginx state=started enabled=yes
root@ubuntu1904:~#ll /data/ansible_exercise/roles/mysqld/files/mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz
-rw-r--r-- 1 root root 403177622 Nov 18 19:13 /data/ansible_exercise/roles/mysqld/files/mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz
root@ubuntu1904:~#cat /data/ansible_exercise/roles/mysqld/files/my.cnf
[mysqld]
log-bin
socket=/data/mysql/mysql.sock
user=mysql
symbolic-links=0
datadir=/data/mysql
innodb_file_per_table=1
[client]
port=3306
socket=/data/mysql/mysql.sock
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/data/mysql/mysql.pid
root@ubuntu1904:~#cat /data/ansible_exercise/roles/mysqld/files/secure_mysql.sh
#!/bin/bash
/usr/local/mysql/bin/mysql_secure_installation <<EOF
y
stevenux
stevenux
y
y
y
y
EOF
# install mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz
- hosts: websrvs
remote_user: root
tasks:
- name: install packages
yum: name=libaio,perl-Data-Dumper,perl-Getopt-Long
- name: create mysql group
group: name=mysql gid=306
- name: create mysql user
user: name=mysql uid=306 group=mysql shell=/sbin/nologin system=yes create_home=no home=/data/mysql
- name: copy tar to remote host and file mode
unarchive: src=/data/ansible/files/mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz dest=/usr/local/ owner=root group=root
- name: mkdir /usr/local/mysql
file: src=/usr/local/mysql-5.6.46-linux-glibc2.12-x86_64 dest=/usr/local/mysql state=link
- name: data dir
shell: chdir=/usr/local/mysql/ ./scripts/mysql_install_db --datadir=/data/mysql --user=mysql
tags: data
- name: config my.cnf
copy: src=/data/ansible/files/my.cnf dest=/etc/my.cnf
- name: service script
shell: /bin/cp /usr/local/mysql/support-files/mysql.server/etc/init.d/mysqld
- name: enable service
shell: /etc/init.d/mysqld start;chkconfig --add mysqld;chkconfig mysqld on
tags: service
- name: PATH variable
copy: content='PATH=/usr/local/mysql/bin:$PATH' dest=/etc/profile.d/mysql.sh
- name: secure script
script: /data/ansible/files/secure_mysql.sh
tags: script
---
#Installing MariaDB Binary Tarballs
- hosts: dbsrvs
remote_user: root
tasks:
- name: create group
group: name=mysql gid=27 system=yes
- name: create user
user: name=mysql uid=27 system=yes group=mysql shell=/sbin/nologin
home=/data/mysql create_home=no
- name: mkdir datadir
file: path=/data/mysql owner=mysql group=mysql state=directory
- name: unarchive package
unarchive: src=/data/ansible/files/mariadb-10.2.27-linux-x86_64.tar.gz
dest=/usr/local/ owner=root group=root
- name: link
file: src=/usr/local/mariadb-10.2.27-linux-x86_64 path=/usr/local/mysql
state=link
- name: install database
shell: chdir=/usr/local/mysql ./scripts/mysql_install_db --
datadir=/data/mysql --user=mysql
- name: config file
copy: src=/data/ansible/files/my.cnf dest=/etc/ backup=yes
- name: service script
shell: /bin/cp /usr/local/mysql/support-files/mysql.server
/etc/init.d/mysqld
- name: start service
service: name=mysqld state=started enabled=yes
- name: PATH variable
copy: content='PATH=/usr/local/mysql/bin:$PATH'
dest=/etc/profile.d/mysql.sh
Playbook 中的变量可以在多个地方定义,在 playbook 中调用。使用等号将值赋给变量。
变量定义
Key(variable)=Value
如:
http_port=80
install_path=/usr/local/
变量调用
在 playbook 中使用 {{ variable }}
形式调用变量的值
playbook 中的变量可以来自:
{{ ansible_default_ipv4.address }}
{{ansible_distribution}}
{{ansible_distribution_major_version}}
{{ansible_fqdn}}
{{ansible_hostname}}
{{ansible_machine}}
{{ansible_memtotal_mb}}
{{ansible_memory_mb.nocache.free}}
{{ansible_memory_mb.nocache.used}}
{{ansible_memory_mb.real.total}}
{{ansible_memory_mb.real.free}}
{{ansible_memory_mb.real.used}}
{{ansible_service_mgr}}
{{ansible_processor_cores}}
{{ansible_processor_count}}
{{ansible_processor_threads_per_core}}
{{ansible_pkg_mgr}}
ansible-playbook -e varname=value
---
vars:
- var1: value1
- var2: value2
---
# vars.yml
var1: value1
var2: value2
---
# main.yml
- hosts: all
vars_files:
- vars.yml
/etc/ansible/hosts
中也可以定义关于主机的变量---
# setup_var_exp.yml
- hosts: websrvs
remote_user: root
tasks:
- name: create log file
file: name=/var/log/ {{ ansible_fqdn }} state=touch
---
# cli_var.yml
- hosts: websrvs
remote_user: root
tasks:
- name: install package
yum: name={{ pkg_name }} state=present
使用:root@ubuntu1904:~#ansible-playbook –e pkg_name=httpd cli_var.yml
---
# self_var.yml
- hosts: websrvs
remote_user: root
vars:
- username: user1
- groupname: group1
tasks:
- name: create group
group: name={{ groupname }} state=present
- name: create user
user: name={{ username }} state=present
使用root@ubuntu1904:~#ansible-playbook self_var.yml
或者root@ubuntu1904:~#ansible-playbook -e "username=user2 groupname=group2" self_var.yml
此时,cli 的变量优先级高,playbook 内的变量值不再使用。
可以在一个独立的 playbook 文件中定义变量,在另一个 playbook 文件中引用变量文件中的变量,
其比 playbook 中定义的变量优化级高
如:
---
# variables file
pack: vsftpd
service: vsftpd
---
#install app and configure
- hosts: appsrvs
remote_user: root
vars_files:
- vars.yml # 包含进变量文件
tasks:
- name: install package
yum: name={{pack}}
tags: install
- name: start service
service: name={{service}} state=started enabled=yes
handlers:
- name: restart httpd service
service: name={{service}} state=restarted
主机变量:在主机 ip 地址后或者主机的 fqdn 后定义
如:
[websrvs]
172.20.1.68 http_port=80 # 变量
172.20.1.69 http_port=8080 maxRequestsPerChild=909 # 两个变量
[websrvs]
wwwa.stevenux.com
wwwb.stevenux.com
[websrvs:vars]
ntp_server=ntp.stevenux.com
nfs_server=nfs.stevenux.com
如:
/etc/ansible/hosts
[websrvs]
192.168.0.101 http_port=8080 hname=www1
192.168.0.102 http_port=80 hname=www2
[websvrs:vars]
http_port=808
mark=“-”
[websrvs]
192.168.0.101 http_port=8080 hname=www1
192.168.0.102 http_port=80 hname=www2
使用root@ubuntu1904:~#ansible websvrs –m hostname –a 'name={{ hname }}{{ mark }}{{ http_port }}'
或者ansible websvrs –e http_port=8000 –m hostname –a 'name={{ hname }}{{ mark }}{{ http_port }}'
1.jinja2 语言大量使用下面的数据结构:
字符串:使用单引号或双引号
数字:整数,浮点数
列表:[item1, item2, ...]
元组:(item1, item2, ...)
字典:{key1:value1, key2:value2, ...}
布尔型:true/false
{{ var }}
: 变量使用两个花括号括起来
{%...%}
: jinja2 语句(for 遍历和 if 条件等)
{#...#}
: 注释
2.jinja2 支持如下运算:
+
把两个对象加到一起。通常对象是数字,但是如果两者是字符串或列表,也可以用这种方式来衔接它们。无论如何
这不是首选的连接字符串的方式!连接字符串一般使用~
运算符。 {{ 1 + 1 }}
等于 2
-
用第一个数减去第二个数。 {{ 3 - 2 }}
等于 1
/
对两个数做除法。返回值会是一个浮点数。 {{ 1 / 2 }}
等于 {{ 0.5 }}
//
对两个数做除法,返回整数商。 {{ 20 // 7 }}
等于 2
%
计算整数除法的余数。 {{ 11 % 7 }}
等于 4
*
用右边的数乘左边的操作数。{{ 2 * 2 }}
会返回 4 。也可以用于重 复一个字符串多次。{{ ‘=’ * 80 }}
会打印 80 个等号的横条
**
取左操作数的右操作数次幂。 {{ 2**3 }}
会返回 8
3.比较操作符
==
比较两个对象是否相等
!=
比较两个对象是否不等
>
如果左边大于右边,返回 true
>=
如果左边大于等于右边,返回 true
<
如果左边小于右边,返回 true
<=
如果左边小于等于右边,返回 true
逻辑运算
and
如果左操作数和右操作数同为真,返回 true
or
如果左操作数和右操作数有一个为真,返回 true
not
对一个表达式取反
(expr)
表达式组
true / false
true 永远是 true ,而 false 始终是 false
在 playbook 中 template 模块用来将 ansible 所在的主控机上的 jinja2 格式模板文件(如:xxx.conf.j2)处理为相应
的配置文件并发送到远程被控主机。根据模板文件动态生成配置文件。template 模板文件必须存放于 templates
目录下,且命名为.j2 结尾的 jinja2 文件。yaml/yml 文件需和 templates 目录平级,目录结构如下:
root@ubuntu1904:/data/ansible_exercise/roles#tree httpd/
httpd/
├── handlers
│ └── main.yml
│────── config.yml
└─── templates
└── httpd.conf.j2
httpd/handlers/main.yml
root@ubuntu1904:/data/ansible_exercise/roles/httpd#cat handlers/main.yml
---
- name: restart
service: name=httpd state=restarted
httpd/tasks/config.yml
root@ubuntu1904:/data/ansible_exercise/roles/httpd#cat config.yml
---
- name: config
template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf backup=yes
notify: restart
ServerRoot "/etc/httpd"
Listen {{ 8080 }} {#将配置文件的端口定义为8080,远程主机将使用8080监听#}
Include conf.modules.d/*.conf
User apache
Group apache
ServerAdmin root@localhost
......
使用root@ubuntu1904:~#ansible-playbook /data/ansible_exercise/roles/httpd/config.yml
在 template 模板中使用 for 和 if 语句
如:
temp_nginx.yml
---
# temp_nginx.yml
- hosts: websrvs
remote_user: root
vars:
nginx_vhosts:
- listen: 8080
tasks:
- name: config file
template: src=nginx2.conf.j2 dest=/data/nginx2.conf
templates/nginx.conf.j2
{% for vhost in nginx_vhosts %}
server {
listen {{ vhost.listen }}
}
{% endfor %}
{#在远程主机生成的结果#}
server {
listen 8080
}
for 例子:
root@ubuntu1904:/data/test_ansible#cat /data/test_ansible/config.yml
---
- hosts: websrvs
remote_user: root
vars:
nginx_vhosts:
- 11
- 22
- 33
- 44
tasks:
- name: gen config
template: src=test.conf.j2 dest=/data/test.conf
notify: test
handlers:
- name: test
shell: cat /data/test.conf > /dev/pts/0
root@ubuntu1904:/data/test_ansible#cat /data/test_ansible/templates/test.conf.j2
{% for vhost in nginx_vhosts %}
I'm : {{ ansible_default_ipv4.address }}
server {
Listen {{ vhost }}
}
{% endfor %
使用root@ubuntu1904:/data/test_ansible#ansible-playbook /data/test_ansible/config.yml
生成:
I'm : 172.20.1.67
server {
Listen 11
}
I'm : 172.20.1.67
server {
Listen 22
}
I'm : 172.20.1.67
server {
Listen 33
}
I'm : 172.20.1.67
server {
Listen 44
}
#temnginx3.yml
- hosts: websrvs
remote_user: root
vars:
nginx_vhosts:
- listen: 8080
server_name: "web1.magedu.com"
root: "/var/www/nginx/web1/"
- listen: 8081
server_name: "web2.magedu.com"
root: "/var/www/nginx/web2/"
- {listen: 8082, server_name: "web3.magedu.com", root:"/var/www/nginx/web3/"}
tasks:
- name: template config
template: src=nginx3.conf.j2 dest=/data/nginx3.conf
# templates/nginx3.conf.j2
{% for vhost in nginx_vhosts %}
server {
listen {{ vhost.listen }}
server_name {{ vhost.server_name }}
root {{ vhost.root }}
}
{% endfor %}
#生成结果:
server {
listen 8080
server_name web1.magedu.com
root /var/www/nginx/web1/
}
server {
listen 8081
server_name web2.magedu.com
root /var/www/nginx/web2/
}
server {
listen 8082
server_name web3.magedu.com
root /var/www/nginx/web3/
}
#temnginx4.yml
- hosts: websrvs
remote_user: root
vars:
nginx_vhosts:
- web1:
listen: 8080
root: "/var/www/nginx/web1/"
- web2:
listen: 8080
server_name: "web2.magedu.com"
root: "/var/www/nginx/web2/"
- web3:
listen: 8080
server_name: "web3.magedu.com"
root: "/var/www/nginx/web3/"
tasks:
- name: template config to
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
#templates/nginx.conf4.j2
{% for vhost in nginx_vhosts %}
server {
listen {{ vhost.listen }}
{% if vhost.server_name is defined %}
server_name {{ vhost.server_name }}
{% endif %}
root {{ vhost.root }}
}
{% endfor %}
#生成的结果
server {
listen 8080
root /var/www/nginx/web1/
}
server {
listen 8080
server_name web2.magedu.com
root /var/www/nginx/web2/
}
server {
listen 8080
server_name web3.magedu.com
root /var/www/nginx/web3/
}
when 语句,可以实现条件测试。如果需要根据变量、facts 或此前任务的执行结果来做为某 task 执行与否的
前提时要用到条件测试,通过在 task 后添加 when 子句即可使用条件测试,jinja2 的语法格式
例如:
---
- hosts: websrvs
remote_user: root
tasks:
- name: "shutdown RedHat flavored systems"
command: /sbin/shutdown -h now
when: ansible_os_family == "RedHat"
---
- hosts: websrvs
remote_user: root
tasks:
- name: add group nginx
tags: user
user: name=nginx state=present
- name: add user nginx
user: name=nginx state=present group=nginx
- name: Install Nginx
yum: name=nginx state=present
- name: restart Nginx
service: name=nginx state=restarted
when: ansible_distribution_major_version == “6”
---
- hosts: websrvs
remote_user: root
tasks:
- name: install conf file to centos7
template: src=nginx.conf.c7.j2 dest=/etc/nginx/nginx.conf
when: ansible_distribution_major_version == "7"
- name: install conf file to centos6
template: src=nginx.conf.c6.j2 dest=/etc/nginx/nginx.conf
when: ansible_distribution_major_version == "6"
迭代:当有需要重复性执行的任务时,可以使用迭代机制对迭代项的引用,固定变量名为’item’
需要在 task 中使用 with_items 给定要迭代的元素列表(字符串或者字典)
例如:
---
- hosts: websrvs
remote_user: root
tasks:
- name: add some users
user: name={{ item }} state=present groups=wheel
with_items:
- testuser1
- testuser2
#上面语句的功能等同于下面的语句
- name: add user testuser1
user: name=testuser1 state=present groups=wheel
- name: add user testuser2
user: name=testuser2 state=present groups=wheel
---
#remove mariadb server
- hosts: appsrvs:!192.168.38.8
remote_user: root
tasks:
- name: stop service
shell: /etc/init.d/mysqld stop
- name: delete files and dir
file: path={{item}} state=absent
with_items:
- /usr/local/mysql
- /usr/local/mariadb-10.2.27-linux-x86_64
- /etc/init.d/mysqld
- /etc/profile.d/mysql.sh
- /etc/my.cnf
- /data/mysql
- name: delete user
user: name=mysql state=absent remove=yes
---
- hosts:websrvs
remote_user: root
tasks
- name: install some packages
yum: name={{ item }} state=present
with_items:
- nginx
- memcached
- php-fpm
---
- hosts: websrvs
remote_user: root
tasks:
- name: copy file
copy: src={{ item }} dest=/tmp/{{ item }}
with_items:
- file1
- file2
- file3
- name: yum install httpd
yum: name={{ item }} state=present
with_items:
- apr
- apr-util
- httpd
---
- hosts: websrvs
remote_user: root
tasks:
- name: add some groups
group: name={{ item }} state=present
with_items:
- nginx
- mysql
- apache
- name: add some users
user: name={{ item.name }} group={{ item.group }} state=present
with_items:
- { name: 'nginx', group: 'nginx' }
- { name: 'mysql', group: 'mysql' }
- { name: 'apache', group: 'apache' }
root@ubuntu1904:/data/ansible_exercise#tree -L 1 roles/
roles/
├── httpd
├── memcached
├── mysqld
├── nginx
├── pxc
├── role_httpd.yml
├── role_nginx.yml
├── role_pxc.ym
root@ubuntu1904:/data/ansible_exercise#tree roles/httpd/
roles/httpd/
├── default
│ └── main.yml
├── files
│ ├── httpd.conf
│ └── index.html
├── handlers
│ └── main.yml
├── tasks
│ ├── config.yml
│ ├── index.yml
│ ├── install.yml
│ ├── main.yml
│ ├── remove.yml
│ └── service.yml
├── templates
│ └── httpd.conf.j2
└── vars
└── main.yml
/roles/project/
:项目名称,有以下子目录files/
:存放由 copy 或 script 模块等调用的文件templates/
:template 模块查找所需要模板文件的目录tasks/
:定义 task,role 的基本元素,至少应该包含一个名为 main.yml 的文件;其它的文件需要在此文件中通过 include 进行包含handlers/
:至少应该包含一个名为 main.yml 的文件;其它的文件需要在此文件中通过 include 进行包含vars/
:定义变量,至少应该包含一个名为 main.yml 的文件;其它的文件需要在此文件中通过 include 进行包含meta/
:定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为 main.yml 的文件,其它文件需在此文件中通过 include 进行包含default
/:设定默认变量时使用此目录中的 main.yml 文件创建 role 的步骤
(1) 创建以 roles 命名的目录
(2) 在 roles 目录中分别创建以各角色名称命名的目录,如 webservers 等
(3) 在每个角色命名的目录中分别创建 files、handlers、meta、tasks、templates 和 vars 目录;用不到
的目录可以创建为空目录,也可以不创建
(4) 在 playbook 文件中,调用各角色
针对大型项目使用 Roles 进行编
例子:
root@ubuntu1904:/data/ansible_exercise#tree roles/
roles/
├── httpd
│ ├── default
│ │ └── main.yml
│ ├── files
│ │ ├── httpd.conf
│ │ └── index.html
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ ├── config.yml
│ │ ├── index.yml
│ │ ├── install.yml
│ │ ├── main.yml
│ │ ├── remove.yml
│ │ └── service.yml
│ ├── templates
│ │ └── httpd.conf.j2
│ └── vars
│ └── main.yml
├── memcached
│ ├── default
│ ├── handlers
│ ├── tasks
│ ├── templates
│ └── vars
├── mysqld
│ ├── default
│ ├── files
│ │ ├── my.cnf
│ │ ├── mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz
│ │ └── secure_mysql.sh
│ ├── handlers
│ ├── tasks
│ │ ├── main.yml
│ │ └── remove_mysql.yml
│ ├── templates
│ └── vars
│ └── mysql_vars.yml
├── nginx
│ ├── default
│ │ └── main.yml
│ ├── files
│ ├── handlers
│ │ ├── handler.yml
│ │ └── main.yml
│ ├── tasks
│ │ ├── config.yml
│ │ ├── file.yml
│ │ ├── install.yml
│ │ ├── main.yml
│ │ └── service.yml
│ ├── templates
│ └── vars
│ └── main.yml
├── pxc
│ ├── default
│ │ └── main.yml
│ ├── files
│ │ ├── percona.repo
│ │ └── wsrep.cnf
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ ├── install_pxc.retry
│ │ ├── install_pxc.yml
│ │ └── main.yml
│ ├── templates
│ └── vars
├── role_httpd.yml
├── role_nginx.yml
├── role_pxc.yml
└── self_report
├── self_report.j2
├── self_report.retry
└── self_report.yml
root@ubuntu1904:/data/ansible_exercise#cat roles/role_httpd.ym
---
- hosts: websrvs
remote_user: root
roles:
- role: httpd`
root@ubuntu1904:/data/ansible_exercise#tree roles/httpd/
roles/httpd/
├── default
│ └── main.yml
├── files
│ ├── httpd.conf
│ └── index.html
├── handlers
│ └── main.yml
├── tasks
│ ├── config.yml
│ ├── index.yml
│ ├── install.yml
│ ├── main.yml
│ ├── remove.yml
│ └── service.yml
├── templates
│ └── httpd.conf.j2
└── vars
└── main.yml
---
- hosts: all
remote_user: root
roles:
- mysql
- { role: nginx, username: nginx }
---
- hosts: all
remote_user: root
roles:
- { role: nginx, username: nginx, when: ansible_distribution_major_version == ‘7’ }
#nginx-role.yml
---
- hosts: websrvs
remote_user: root
roles:
- { role: nginx ,tags: [ 'nginx', 'web' ] ,when: ansible_distribution_major_version == "6“ }
- { role: httpd ,tags: [ 'httpd', 'web' ] }
- { role: mysql ,tags: [ 'mysql', 'db' ] }
- { role: mariadb ,tags: [ 'mariadb', 'db' ] }
ansible-playbook --tags="nginx,httpd,mysql" nginx-role.yml
返璞词(retronyms):语言变化的一种方式即创造词条,描述已有概念的新版本或新发明,例如合成词 electric guitar(电吉他),将新发明与现有类型的吉他区分开来。然而,随着电吉他的使用变得越来越普遍,guitar(吉他)一词已不再明确地描述一种不用电子放大器就能弹奏的乐器。相反,早期的发明获得了一个新名称,acoustic guitar(原声吉他),以明确所指哪一种吉他。为了将已有概念与新概念区分开来而发明的词称为返璞词。 ↩︎
幂等(idempotent):幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。 在数学里, 幂等有两种主要的定义。在某二元运算下, 幂等元素是指被自己重复运算(或对于函数是为复合)的结果等于它自己的元素。例如,乘法下唯一两个幂等实数为 0 和 1。某一元运算为 幂等的时,其作用在任一元素两次后会和其作用一次的结果相同。例如,高斯符号便是幂等的。 ↩︎