写作时间:2022年2月 系统:centos 7.9 ansible版本:2.9.27
1.不要只用一组秘钥对,多主机按模块用几组ssh秘钥对(保障安全)
2.ssh秘钥对的key进行加密,不同的key设置不同的密码,防止别人登录ansible主机能操作所有服务器
可参考下面的链接做配置。在满足上面推荐的使用方法下,能像所有主机只用一个秘钥对而且key不加密一样方便。
利用ssh-agent提升ansible使用的方便及安全性_sinat_24354307的博客-CSDN博客
1)ANSIBLE_CONFIG:首先,Ansible命令会检查环境变量指定的位置(export ANSIBLE_CONFIG=/etc/ansible.cfg)
2)./ansible.cfg:其次,将会检查当前目录下的ansible.cfg配置文件
3)~/.ansible.cfg:再次,将会检查当前用户home目录下的.ansible.cfg配置文件
4)/etc/ansible/ansible.cfg:最后,将会检查在用软件包管理工具安装Ansible时自动产生的配置文件
inventory = /etc/ansible/hosts #这个参数表示资源清单inventory文件的位置
forks = 5 #并发连接数,默认为5
sudo_user = root #设置默认执行命令的用户
remote_port = 22 #指定连接被管节点的管理端口,默认为22端口,建议修改,能够更加安全
host_key_checking = False #设置是否检查SSH主机的密钥,值为True/False。关闭后第一次连接不会提示配置实例
timeout = 60 #设置SSH连接的超时时间,单位为秒
roles_path = /root/roles #设置roles的目录
log_path = /var/log/ansible.log #指定一个存储ansible日志的文件(默认不记录日志)
[defaults]
[inventory]
[privilege_escalation]
[paramiko_connection]
[ssh_connection]
[persistent_connection]
[accelerate]
[selinux]
[colors]
[diff]
请看下面的第三行
[root@vm10 ~]# ansible --version
ansible 2.9.27
config file = /root/a.cfg
configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, Oct 14 2020, 14:45:30) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
[root@vm10 ~]#
修改了hosts文件路径并添加了ansible的日志,其他配置可以按需修改
说明日志信息==终端输出的信息+时间+用户。结合命令行的history带时间,来看效果更好。
[defaults]
inventory = /tmp/hosts
log_path = /var/log/ansible.log
roles_path = /root/roles #设置roles的目录,按需配置,切莫创造需求
[inventory]
[privilege_escalation]
[paramiko_connection]
[ssh_connection]
[persistent_connection]
[accelerate]
[selinux]
[colors]
[diff]
/etc/ansible/hosts # 小编是用yum安装的ansible
举例指定hosts文件路径为/tmp/hosts,此时ansible.cfg完整的配置文件如下(默认的基础上新增了第二行)
[defaults]
inventory = /tmp/hosts
[inventory]
...
ansible -i /etc/ansible/hosts ....
[root@vm10 ~]# ansible --list-hosts all
hosts (2):
192.168.9.16
192.168.9.17
[root@vm10 ~]# ansible --list-hosts test1
hosts (2):
192.168.9.16
192.168.9.17
[root@vm10 ~]#
也支持主机名,本文没涉及,可自行实验
一个IP可以放到多个组里面
实例的hosts文件为
[test1]
192.168.9.16
192.168.9.17
[test1:children] # 组嵌套,下面的组也属于test1
test2
[test2]
1.1.1.[1:5:2] #支持范围,从1到5间隔为2,结果是1 3 5
1.1.2.1 ansible_connection=local #指定是本地主机不用ssh
1.1.2.2 ansible_connection=ssh ansible_port=222 ansible_user=manage ansible_password=123456 #指定特定的连接信息
[root@server ~]# ansible web -m ping
192.168.37.122 | SUCCESS => {
"changed": false,
"ping": "pong"
}
不能用管道符,直接用shell模块更通用些。此模块不做具体说明。可查看下方参考链接获取具体用法。
跟在电脑上执行shell一样,可以使用管道符等,不做说明。
这个模块用于将文件复制到远程主机,同时支持给定内容生成文件和修改权限等。其相关选项如下:
src
#被复制到远程主机的本地文件。可以是绝对路径,也可以是相对路径。如果路径是一个目录,则会递归复制,用法类似于"rsync"
content
#用于替换"src",可以直接指定文件的值
dest
#必选项,将源文件复制到的远程主机的绝对路径
backup
#当文件内容发生改变后,在覆盖之前把源文件备份,备份文件包含时间信息
directory_mode
#递归设定目录的权限,默认为系统默认权限
force
#当目标主机包含该文件,但内容不同时,设为"yes",表示强制覆盖;设为"no",表示目标主机的目标位置不存在该文件才复制。默认为"yes"
others
#所有的 file 模块中的选项可以在这里使用
用法举例如下:
1.复制文件
ansible web -m copy -a 'src=~/hello dest=/data/hello'
2.给定内容生成文件,并制定权限
ansible web -m copy -a 'content="I am keer\n" dest=/data/name mode=666'
3.backup的用法,覆盖的时候要不要备份,下面的备份旧文件的选项
ansible web -m copy -a 'content="I am keerya\n" backup=yes dest=/data/name mode=666'
4.force的用法,因目标主机有a.cfg而且跟src的不一样,所以本次copy不做任何操作
[root@vm10 ~]# ansible z -m copy -a "src=a.cfg dest=/tmp/a.cfg force=no"
192.168.9.16 | SUCCESS => {
"changed": false,
"dest": "/tmp/a.cfg",
"src": "/root/a.cfg"
}
192.168.9.17 | SUCCESS => {
"changed": false,
"dest": "/tmp/a.cfg",
"src": "/root/a.cfg"
}
该模块主要用于设置文件的属性,比如创建文件、创建链接文件、删除文件等。下面是一些常见的命令:
force
#需要在两种情况下强制创建软链接,一种是源文件不存在,但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes|no
group
#定义文件/目录的属组。后面可以加上mode
:定义文件/目录的权限
owner
#定义文件/目录的属主。后面必须跟上path
:定义文件/目录的路径
recurse
#递归设置文件的属性,只对目录有效,后面跟上src
:被链接的源文件路径,只应用于state=link
的情况
dest
#被链接到的路径,只应用于state=link
的情况
state
#状态,有以下选项:
directory
:如果目录不存在,就创建目录
file
:即使文件不存在,也不会被创建
link
:创建软链接
hard
:创建硬链接
touch
:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
absent
:删除目录、文件或者取消链接文件
用法举例如下:
1.创建目录
ansible web -m file -a 'path=/data/app state=directory'
2.创建软链接
ansible web -m file -a 'path=/data/bbb.jpg src=aaa.jpg state=link'
结果为:
-rw-r--r-- 1 root root 5649 Dec 4 14:44 aaa.jpg
lrwxrwxrwx 1 root root 7 Dec 5 10:25 bbb.jpg -> aaa.jpg
3.删除文件
ansible web -m file -a 'path=/data/a state=absent'
该模块用于从远程某主机获取(复制)文件到本地。有两个选项:
dest
:用来存放文件的目录
src
:在远程拉取的文件,并且必须是一个file,不能是目录
用法举例:
ansible web -m fetch -a 'src=/data/hello dest=/data'
结果查看:
要注意,文件保存的路径是我们设置的接收目录下的被管制主机ip目录下
[root@server ~]# cd /data/
[root@server data]# ls
1 192.168.37.122 192.168.37.133 fastdfs web
[root@server data]# cd 192.168.37.122
[root@server 192.168.37.122]# ls
data
[root@server 192.168.37.122]# cd data/
[root@server data]# ls
hello
[root@server data]# pwd
/data/192.168.37.122/data
该模块适用于管理cron
计划任务的。
其使用的语法跟我们的crontab
文件中的语法一致,同时,可以指定以下选项:
day=
#日应该运行的工作( 1-31, *, */2, )
hour=
# 小时 ( 0-23, *, */2, )
minute=
#分钟( 0-59, *, */2, )
month=
# 月( 1-12, *, /2, )
weekday=
# 周 ( 0-6 for Sunday-Saturday, )
job=
#指明运行的命令是什么
name=
#定时任务描述
reboot
# 任务在重启时运行,不建议使用,建议使用special_time
special_time
#特殊的时间范围,参数:reboot(重启时),annually(每年),monthly(每月),weekly(每周),daily(每天),hourly(每小时)
state
#指定状态,present表示添加定时任务,也是默认设置,absent表示删除定时任务
user
# 以哪个用户的身份执行
举例如下:
1.添加周期任务
ansible web -m cron -a 'name="ntp update every 5 min" minute=*/5 job="/sbin/ntpdate 172.17.0.1 &> /dev/null"'
结果:
#Ansible: ntp update every 5 min
*/5 * * * * /sbin/ntpdate 172.17.0.1 &> /dev/null
2.删除周期任务(只需要名字就行)
ansible web -m cron -a 'name="ntp update every 5 min" state=absent'
3.设置重启的时候执行
ansible z -m cron -a 'name="test1" special_time=reboot job="/usr/bin/date >> /root/a.txt"'
结果:
#Ansible: test1
@reboot /usr/bin/date >> /root/a.txt
crontab说明
@reboot : Run once after reboot. 重启时执行一次
@yearly : Run once a year, ie. "0 0 1 1 *". 一年执行一次,1月1号0点0分执行
@annually : Run once a year, ie. "0 0 1 1 *". 一年执行一次,1月1号0点0分执行
@monthly : Run once a month, ie. "0 0 1 * *". 一月执行一次,每月1号0点0分执行
@weekly : Run once a week, ie. "0 0 * * 0". 一周执行一次
@daily : Run once a day, ie. "0 0 * * *". 一天执行一次
@hourly : Run once an hour, ie. "0 * * * *". 一小时执行一次
其选项如下:
name=
#所安装的包的名称
state=
#present
—>安装,latest
—>安装最新的,absent
—> 卸载软件。
update_cache
#强制更新yum的缓存
conf_file
#指定远程yum安装时所依赖的配置文件(安装本地已有的包)。
disable_pgp_check
#是否禁止GPG checking,只用于present
orlatest
。
disablerepo
#临时禁止使用yum库。 只用于安装或更新时。
enablerepo
#临时使用的yum库。只用于安装或更新时。
用法举例:
安装httpd
ansible web -m yum -a 'name=httpd state=present'
该模块用于服务程序的管理。其主要选项如下:
arguments
#命令行提供额外的参数
enabled
#设置开机启动。
name=
#服务名称
runlevel
#开机启动的级别,一般不用指定。
sleep
#在重启服务的过程中,是否等待。如在服务关闭以后等待2秒再启动。(定义在剧本中。)
state
#有四种状态,分别为:started
—>启动服务,stopped
—>停止服务,restarted
—>重启服务,reloaded
—>重载配置
示例:
1.启动服务并设置开机自启动
ansible web -m service -a 'name=nginx state=started enabled=true'
2.停止服务
ansible web -m service -a 'name=nginx state=stopped'
该模块主要是用来管理用户账号。其主要选项如下:
comment
# 用户的描述信息
createhome
# 是否创建家目录
force
# 在使用state=absent时, 行为与userdel –force一致.
group
# 指定基本组
groups
# 指定附加组,如果指定为(groups=)表示删除所有组
home
# 指定用户家目录
move_home
# 如果设置为home=时, 试图将用户主目录移动到指定的目录
name
# 指定用户名
non_unique
# 该选项允许改变非唯一的用户ID值
password
# 指定用户密码
remove
# 在使用state=absent时, 行为是与userdel –remove一致
shell
# 指定默认shell
state
# 设置帐号状态,不指定为创建,指定值为absent表示删除
system
# 当创建一个用户,设置这个用户是系统用户。这个设置不能更改现有用户
uid
# 指定用户的uid
示例:
1.添加用户并指定uid
ansible web -m user -a 'name=keer uid=11111'
2.添加用户并不创建家目录
ansible web -m user -a 'name=keer create_home=false'
3.删除用户(不会删除家目录,需要删除的话请用shell模块删除家目录)
ansible web -m user -a 'name=keer state=absent'
该模块主要用于添加或删除组。常用的选项如下:
gid=
#设置组的GID号
name=
#指定组的名称
state=
#指定组的状态,默认为创建,设置值为absent
为删除
system=
#设置值为yes
,表示创建为系统组
举例如下:
1.创建组
ansible web -m group -a 'name=sanguo gid=12222'
2.删除组
ansible web -m group -a 'name=sanguo state=absent'
该模块用于将本机的脚本在被管理端的机器上运行。
首先,我们写一个脚本,并给其加上执行权限(测试不加也能成功),然后执行ansible命令
ansible web -m script -a '/tmp/df.sh'
该模块主要用于收集信息,是通过调用facts组件来实现的。
facts组件是Ansible用于采集被管机器设备信息的一个功能,我们可以使用setup模块查机器的所有facts信息,可以使用filter来查看指定信息。整个facts信息被包装在一个JSON格式的数据结构中,ansible_facts是最上层的值。
facts就是变量,内建变量 。每个主机的各种信息,cpu颗数、内存大小等。会存在facts中的某个变量中。调用后返回很多对应主机的信息,在后面的操作中可以根据不同的信息来做不同的操作。如redhat系列用yum安装,而debian系列用apt来安装软件。
filter常用汇总:
ansible_all_ipv4_addresses # ipv4的所有地址
ansible_all_ipv6_addresses # ipv6的所有地址
ansible_date_time # 获取到控制节点时间
ansible_default_ipv4 # 默认的ipv4地址
ansible_distribution # 系统
ansible_distribution_major_version # 系统的大版本
ansible_distribution_version # 系统的版本号
ansible_domain #系统所在的域
ansible_env #系统的环境变量
ansible_hostname #系统的主机名
ansible_fqdn #系统的全名
ansible_machine #系统的架构
ansible_memory_mb #系统的内存信息
ansible_os_family # 系统的家族
ansible_pkg_mgr # 系统的包管理工具
ansible_processor_cores #系统的cpu的核数(每颗)
ansible_processor_count #系统cpu的颗数
ansible_processor_vcpus #系统cpu的总个数=cpu的颗数*CPU的核数
ansible_python # 系统上的python
filter="*关键词*" #用来搜索关键词
示例:
1.查看主机所有setup信息(内容很多)
ansible web -m setup
2.过滤内存信息
ansible web -m setup -a 'filter="*mem*"'
3.保存过滤的信息到文件,每个主机占一个文件
ansible web -m setup -a 'filter="*mem*"' --tree /tmp/facts
结果如下:
[root@vm10 ~]# tree /tmp/facts/
/tmp/facts/
├── 192.168.9.16
└── 192.168.9.17
0 directories, 2 files
[root@vm10 ~]# cat /tmp/facts/192.168.9.16 | python -m json.tool
{
"ansible_facts": {
"ansible_memfree_mb": 781,
"ansible_memory_mb": {
"nocache": {
"free": 862,
"used": 128
},
"real": {
"free": 781,
"total": 990,
"used": 209
},
"swap": {
"cached": 0,
"free": 2047,
"total": 2047,
"used": 0
}
},
"ansible_memtotal_mb": 990,
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
修改文件专用的模块,非常好用。支持正则
参数:
用法举例:
1.在匹配到的行前添加一行或多行内容(一次只改一行,改了之后因已经添加过了,所以执行第二次无效)
把带有"nd1"字段的行后面插入"befor1\nbefor2"因为有\n所以是2行内容
ansible 192.168.9.12 -m lineinfile -a 'dest=/tmp/a.txt insertbefore="nd1" line="befor1\nbefor2"'
2.在匹配到的行后添加一行或多行内容(一次只改一行,改了之后因已经添加过了,所以执行第二次无效)
把带有"hand1"字段的行后面插入"after1\nafter2"因为有\n所以是2行内容
ansible 192.168.9.12 -m lineinfile -a 'dest=/tmp/a.txt insertafter="hand1" line="after1\nafter2"'
3.替换匹配到的行的内容并修改文件权限(一次只改一行)
把带有"befor"的行替换为"前面" 并设置文件权限
ansible 192.168.9.12 -m lineinfile -a 'dest=/tmp/a.txt regex="befor" line="前面" owner=root group=root mode=0777'
4.删除匹配到的行(自动一次删除匹配到的所有行)
删除所有带"befor"字符的行
ansible 192.168.9.12 -m lineinfile -a 'dest=/tmp/a.txt regex="befor" state=absent'
5.如果该文件存在,且文件中没有跟line中一模一样的行,则添加一行;文件不存在不做操作;文件中有跟line一模一样的行也不做操作
ansible 192.168.9.12 -m lineinfile -a 'dest=/tmp/a.txt line="step5"'
[root@vm10 ansible_playbook]# ansible-playbook --list-hosts 01-install_and_start_httpd.yml
playbook: 01-install_and_start_httpd.yml
play #1 (192.168.9.12): 192.168.9.12 TAGS: []
pattern: [u'192.168.9.12']
hosts (1):
192.168.9.12
[root@vm10 ansible_playbook]# ansible-playbook --list-tasks 01-install_and_start_httpd.yml
playbook: 01-install_and_start_httpd.yml
play #1 (192.168.9.12): 192.168.9.12 TAGS: []
tasks:
install httpd TAGS: []
start httpd TAGS: []
[root@vm10 ansible_playbook]# ansible-playbook --list-tags 01-install_and_start_httpd.yml
playbook: 01-install_and_start_httpd.yml
play #1 (192.168.9.12): 192.168.9.12 TAGS: []
TASK TAGS: []
---
- hosts: z
remote_user: root
tasks:
- shell: 这里直接输命令即可
只有notify对应的task执行了,才会执行对应的handler。比如task用lineinfile模块修改配置文件的,如果文件没有在task中做变动,则对应的handler是不执行的。
---
- hosts: z
remote_user: root
tasks:
- name: step 1 shell
shell: echo step1 > /tmp/a.txt;sleep 2
notify: handlers2
- name: step 2 shell
shell: echo step2 >> /tmp/a.txt;sleep 2
notify:
- handlers1
- handlers0
handlers:
- name: handlers0
shell: echo hand0 >> /tmp/a.txt;sleep 2
- name: handlers1
shell: echo hand1 >> /tmp/a.txt;sleep 2
- name: handlers2
shell: echo hand2 >> /tmp/a.txt;sleep 2
- name: hand3 #没有被notify所以不执行
shell: echo hand3 >> /tmp/a.txt
# 执行结果的顺序为 step1 -> step2 -> handler0 -> handler1 -> handler2
# handler执行的顺序与handler在playbook中定义的顺序是相同的,与”handler被notify”的顺序无关。
# 先执行task再执行handler
每个task可以设置tags,可以用ansible-playbook *.yml -t tags1 来执行需要执行的tags1对应的task
- hosts: z
remote_user: root
tasks:
- name: shell1
shell: echo shell1
tags: shell1
- name: shell2
shell: shell2
tags: shell2
#举例yml文件如上,如果单独想执行shell1标签的task,执行下面的命令
#ansible-playbook 05-tag.yml -t shell1
注意:检查语法的时候也要加上变量的值,如:
ansible-playbook -C 06-vars-in-shell.yml -e service=httpd -e service2=httpd2 # 多个变量就多个-e即可
全文如下
- hosts: z
remote_user: root
tasks:
- name: 'task1: {{ service }}'
shell: echo {{ service }}
- name: task2 start {{ service2 }}
service: name={{ service2 }} state=started
# 执行任务时,输入:
# ansible-playbook 06-vars-in-shell.yml -e service=httpd -e service2=httpd2
注意:vars部分也可以写到tasks部分下面
- hosts: z
remote_user: root
vars: #看这里
- service: http
- service2: http2
tasks:
- name: 'task1: {{ service }}'
shell: echo {{ service }}
- name: task2 start {{ service2 }}
service: name={{ service2 }} state=started
分配变量给主机,只需要将变量定义在主机的host之后,就可在 playbooks 中使用。如:
[atlanta]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909
[atlanta]
host1
host2
[atlanta:vars] #给atlanta组设定变量
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com
在 inventory 主文件中保存所有的变量并不是最佳的方式。还可以保存在独立的文件中,这些独立文件与 inventory 文件保持关联。
假设在inventory文件中有一个主机名为 ‘foosball,主机同时属于两个组,一个是 ‘raleigh’,另一个是 ‘webservers’:
[raleigh]
foosball
[webservers]
foosball
那么以下配置文件(YAML 格式)中的变量可以为 ‘foosball’ 主机所用。依次为 ‘raleigh’ 的组变量,’webservers’ 的组变量,’foosball’ 的主机变量:
/etc/ansible/group_vars/raleigh #注意看路径 group_vars
/etc/ansible/group_vars/webservers
/etc/ansible/host_vars/foosball #注意看路径 host_vars
优先级最高的是host_vars中定义的变量,其次组的变量是根据组的名字排序来进行优先级排序的,组名称靠后的优先级高。
实例:
yaml文件为
- hosts: z
remote_user: root
tasks:
- name: 'task1: {{ service }}'
shell: echo {{ service }}
- name: task2 start {{ service2 }}
service: name={{ service2 }} state=started
/etc/ansible/group_vars/z 文件为
service:
- http3
执行命令(service变量从变量文件读了)
ansible-playbook -C 06-vars-in-shell.yml -e service2=http2
Dynamic Inventory指通过外部脚本获取主机列表,并按照ansible 所要求的格式返回给ansilbe命令的。
这部分一般会结合CMDB资管系统、zabbix 监控系统、crobble安装系统、云计算平台等获取主机信息。由于主机资源一般会动态的进行增减,而这些系统一般会智能更新。我们可以通过这些工具提供的API 或者接入库查询等方式返回主机列表。
由于Ansible在接受脚本动态获取主机信息时支持的是json格式,这里直接通过一段代码打印一个段json格式的主机信息:
a.py内容如下,并设置a.py有可执行的权限
#!/usr/bin/env python
# coding=utf-8
# 脚本中一定要加上解释器,如 #!/usr/bin/python
import json
host1ip = ['10.212.52.252', '10.212.52.14']
host2ip = ['10.212.52.16']
group1 = 'test1'
group2 = 'test2'
hostdata = {group1: {"hosts": host1ip},
group2: {"hosts": host2ip}
}
print json.dumps(hostdata, indent=4)
a.py的输出为
{
"test1": {
"hosts": [
"10.212.52.252",
"10.212.52.14"
]
},
"test2": {
"hosts": [
"10.212.52.16"
]
}
}
执行ansible命令
ansible -i a.py test1 -m ping #即可动态获取test1组的主机清单。不一定非得是python,其它语言也行,输出是json即可。
当有需要重复性执行的任务时,可以使用迭代机制。其使用格式为将需要迭代的内容定义为item变量引用,并通过with_items语句来指明迭代的元素列表即可。例如:
- name: add several 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
另外,with_items中使用的元素还可以是hashes,例如:
- name: add several users
user: name={{ item.name }} state=present groups={{ item.groups }}
with_items:
- { name: 'testuser1', groups: 'wheel'}
- { name: 'testuser2', groups: 'root'}
【注意】:item是固定变量名。
when语句:在task中使用,jinja2的语法格式。
举例如下:
tasks:
- name: install conf file to centos7
template: src=files/nginx.conf.c7.j2
when: ansible_distribution_major_version == "7"
- name: install conf file to centos6
template: src=files/nginx.conf.c6.j2
when: ansible_distribution_major_version == "6"
ansible会根据"模板"文件,为每一台主机生成对应的配置文件(如setup中的变量)。使用Ansible的jinja2模板也就是使用template模块,该模块和copy模块一样,都是讲文件复制到远端主机上去,但是区别在于,template模块可以获取到文件中的变量,而copy则是原封不动的把文件内容复制过去。
模板文件:motd.j2
Welcome to {{ ansible_hostname }}
This system total mem is : {{ ansible_memtotal_mb }} MB
This system free mem is: {{ ansible_memfree_mb }} MB
yaml文件
- hosts: z
remote_user: root
tasks:
- name: muban
template: src=./motd.j2 dest=/tmp/motd1
模板文件:xunhuan.j2
{% for n in range(21) %}
server 172.16.1.{{ n }}
{% endfor %}
yaml文件
- hosts: z
remote_user: root
tasks:
- name: 循环
template: src=xunhuan.j2 dest=/tmp/xunhuan.txt
输出
server 172.16.1.0
server 172.16.1.1
.....省略
server 172.16.1.20
模板文件panduan.j2
{% if ansible_hostname == 'vm12' %} #注意vm12要加引号,因为是字符串,不加引号会以为是变量,导致报错
echo {{ ansible_hostname }} yes > /tmp/a.txt
{% elif ansible_hostname == 'vm13' %}
echo {{ ansible_hostname }} yes > /tmp/a.txt
echo {{ ansible_hostname }} yes > /tmp/a.txt
{% endif %}
yaml文件
- hosts: z
remote_user: root
tasks:
- name: 判断
template: src=panduan.j2 dest=/tmp/panduan.txt
输出(模板是空行输出也是空行)
192.168.9.13 | CHANGED | rc=0 >>
echo vm13 yes > /tmp/a.txt
echo vm13 yes > /tmp/a.txt
192.168.9.12 | CHANGED | rc=0 >>
echo vm12 yes > /tmp/a.txt
使用default()默认值,当我们定义了变量的值时,采用变量的值,当我们没有定义变量的值时,那么使用默认给定的值.
模板文件中默认值语法如下
Listen: {{ server_port|default(80) }}
卸载某个角色的话,也需要单独整个roles的目录
默认目录为:/etc/ansible/roles
可修改配置文件:ansible.cfg
...
[defaults]
roles_path = /root/roles
....
tasks目录:角色需要执行的主任务文件放置在此目录中,默认的主任务文件名为main.yml,当调用角色时,默认会执行main.yml文件中的任务,你也可以将其他需要执行的任务文件通过include的方式包含在tasks/main.yml文件中。
handlers目录:当角色需要调用handlers时,默认会在此目录中的main.yml文件中查找对应的handler
defaults目录:角色会使用到的变量可以写入到此目录中的main.yml文件中,通常,defaults/main.yml文件中的变量都用于设置默认值,以便在你没有设置对应变量值时,变量有默认的值可以使用,定义在defaults/main.yml文件中的变量的优先级是最低的。
vars目录:角色会使用到的变量可以写入到此目录中的main.yml文件中,看到这里你肯定会有疑问,vars/main.yml文件和defaults/main.yml文件的区别在哪里呢?区别就是,defaults/main.yml文件中的变量的优先级是最低的,而vars/main.yml文件中的变量的优先级非常高,如果你只是想提供一个默认的配置,那么你可以把对应的变量定义在defaults/main.yml中,如果你想要确保别人在调用角色时,使用的值就是你指定的值,则可以将变量定义在vars/main.yml中,因为定义在vars/main.yml文件中的变量的优先级非常高,所以其值比较难以覆盖。
meta目录:如果你想要赋予这个角色一些元数据,则可以将元数据写入到meta/main.yml文件中,这些元数据用于描述角色的相关属性,比如 作者信息、角色主要作用等等,你也可以在meta/main.yml文件中定义这个角色依赖于哪些其他角色,或者改变角色的默认调用设定,在之后会有一些实际的示例,此处不用纠结。
templates目录: 角色相关的模板文件可以放置在此目录中,当使用角色相关的模板时,如果没有指定路径,会默认从此目录中查找对应名称的模板文件。
files目录:角色可能会用到的一些其他文件可以放置在此目录中,比如,当你定义nginx角色时,需要配置https,那么相关的证书文件即可放置在此目录中。
当然,上述目录并不全是必须的,也就是说,如果你的角色并没有相关的模板文件,那么角色目录中并不用包含templates目录,同理,其他目录也一样,一般情况下,都至少会有一个tasks目录。
3.1 在roles目录下生成对应的目录结构
[root@server ansible]# cd roles/
[root@server roles]# ls
[root@server roles]# mkdir -pv ./{nginx,mysql,httpd}/{files,templates,vars,tasks,handlers,meta,default}
[root@server roles]# tree
.
├── httpd
│ ├── default
│ ├── files
│ ├── handlers
│ ├── meta
│ ├── tasks
│ ├── templates
│ └── vars
├── mysql
│ ├── default
│ ├── files
│ ├── handlers
│ ├── meta
│ ├── tasks
│ ├── templates
│ └── vars
└── nginx
├── default
├── files
├── handlers
├── meta
├── tasks
├── templates
└── vars
3.2 定义配置文件
我们需要修改的配置文件为/tasks/main.yml
,下面,我们就来修改一下:
[root@server roles]# vim nginx/tasks/main.yml
- name: cp
copy: src=nginx-1.10.2-1.el7.ngx.x86_64.rpm dest=/tmp/nginx-1.10.2-1.el7.ngx.x86_64.rpm
- name: install
yum: name=/tmp/nginx-1.10.2-1.el7.ngx.x86_64.rpm state=latest
- name: conf
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
tags: nginxconf
notify: new conf to reload
- name: start service
service: name=nginx state=started enabled=true
3.3放置我们所需要的文件到指定目录
因为我们定义的角色已经有了新的组成方式,所以我们需要把文件都放到指定的位置,这样,才能让配置文件找到这些并进行加载。
rpm包放在files
目录下,模板放在templates
目录下:
[root@server nginx]# cp /tmp/nginx-1.10.2-1.el7.ngx.x86_64.rpm ./files/
[root@server nginx]# cp /tmp/nginx.conf.j2 ./templates/
[root@server nginx]# tree
.
├── default
├── files
│ └── nginx-1.10.2-1.el7.ngx.x86_64.rpm
├── handlers
├── meta
├── tasks
│ └── main.yml
├── templates
│ └── nginx.conf.j2
└── vars
3.4 修改变量文件
我们在模板中定义的变量,也要去配置文件中加上:
[root@server nginx]# vim vars/main.yml
nginxprot: 9999
3.5定义handler文件
我们在配置文件中定义了notify
,所以我么也需要定义handlers
,我们来修改配置文件:
[root@server nginx]# vim handlers/main.yml
- name: new conf to reload
service: name=nginx state=restarted
3.6 定义playbook文件
接下来,我们就来定义剧本文件,由于大部分设置我们都单独配置在了roles里面,所以,接下来剧本就只需要写一点点内容即可:
[root@server ansible]# vim roles.yml
- hosts: web
remote_user: root
roles:
- nginx
3.7 启动服务
剧本定义完成以后,我们就可以来启动服务了:
[root@server ansible]# ansible-playbook roles.yml
PLAY [web] *********************************************************************
TASK [setup] *******************************************************************
ok: [192.168.37.122]
ok: [192.168.37.133]
TASK [nginx : cp] **************************************************************
ok: [192.168.37.122]
ok: [192.168.37.133]
TASK [nginx : install] *********************************************************
changed: [192.168.37.122]
changed: [192.168.37.133]
TASK [nginx : conf] ************************************************************
changed: [192.168.37.122]
changed: [192.168.37.133]
TASK [nginx : start service] ***************************************************
changed: [192.168.37.122]
changed: [192.168.37.133]
RUNNING HANDLER [nginx : new conf to reload] ***********************************
changed: [192.168.37.122]
changed: [192.168.37.133]
PLAY RECAP *********************************************************************
192.168.37.122 : ok=6 changed=4 unreachable=0 failed=0
192.168.37.133 : ok=6 changed=4 unreachable=0 failed=0
请在roles角色里面建一个新的角色"uninstall_角色",然后使用该角色即可
自动化运维工具——ansible详解(一) - 珂儿吖 - 博客园 (cnblogs.com)
自动化运维工具——ansible详解(二) - 珂儿吖 - 博客园 (cnblogs.com)
Ansible 1.2.2:Ansible 主机清单文件 hosts_学渣角鹿白的博客-CSDN博客_ansible host文件
Ansible lineinfile模块详解 - breezey - 博客园 (cnblogs.com)
Ansible(三十)-- ansible 中的模板 template模块 jinja2模板引擎(一)_CL82的博客-CSDN博客_ansible template模块