Ansible——从一到百的服务器管理神器(万字细讲)

Ansible介绍

ansible是一个配置管理工具,自动化运维工具,可以帮助批量完成任务,ansible是基于ssh工作的,所以只要ssh能接通就能基于ssh控制主机,ansible在执行明林的时候就是把脚本或命令推送到被控制机器上执行,执行之后又删除了,ansible推送的脚本或命令在远程主机的/ansible/tmp的目录下。
一般ansible直接用yum安装(ubuntu中使用apt install ansible)。
测试的时候可以使用ping模块进行测试看是否能控制主机,
ansible 192.168.240.133 -m ping

ansible配置文件说明

在/etc/ansible下是配置文件ansible.cfg,一般来说这个配置文件是不需要做修改的,主要需要修改的就是hosts文件,这个文件是主机清单文件,主机清单文件中写的主机的ip地址,可进行分组编写,以中括号为组名[webserver],如果ip地址是连续的,还可以写成192.168.240.[130:131],同一台主机可以被写进不同的分组中。

ansible [-m module_name] [-a args]
-a选项是模块支持的参数。

ansible选项说明

–version #显示版本
-m module #指定模块,默认为command
-v #详细过程
–list-hosts #显示主机列表,可简写为–list
-k --ask-pass #提示输入ssh连接密码,默认key验证
-c --check #检查,并不执行

ansible常用模块

所有的ansible模块的使用方法都可以使用ansible-doc -s module来查看

command模块

这个是默认模块,即Linux命令,可直接使用
ansible webserver -m command -a ‘ls’
也可使用chdir来切换目录,之后执行相关命令
ansible webserver -m command -a ‘chdir=/etc ls’
command模块有很多局限性,也有很多Linux命令是不能执行的,很多符号不支持。

shell模块

与command相似,用shell执行命令,支持一些特殊符号的Linux命令。由此可知shell模块比command模块功能强大,所以可以修改默认模块。
即修改/etc/ansible/ansible.cfg 中参数module_name=shell

free_form参数 :必须参数,指定需要远程执行的命令,但是并没有具体的一个参数名叫free_form,具体解释参考command模块。

chdir参数 : 此参数的作用就是指定一个目录,在执行对应的命令之前,会先进入到chdir参数指定的目录中。

creates参数 :使用此参数指定一个文件,当指定的文件存在时,就不执行对应命令,可参考command模块中的解释。

removes参数 :使用此参数指定一个文件,当指定的文件不存在时,就不执行对应命令,可参考command模块中的解释。

executable参数:默认情况下,shell模块会调用远程主机中的/bin/sh去执行对应的命令,通常情况下,远程主机中的默认shell都是bash,如果你想要使用其他类型的shell执行命令,则可以使用此参数指定某种类型的shell去执行对应的命令,指定shell文件时,需要使用绝对路径。

script模块

script模块可以帮助我们在远程主机上执行ansible主机上的脚本,也就是说,脚本一直存在于ansible主机本地,不需要手动拷贝到远程主机后再执行。

free_form参数 :必须参数,指定需要执行的脚本,脚本位于ansible主机本地,并没有具体的一个参数名叫free_form,具体解释参考command模块。

chdir参数 : 此参数的作用就是指定一个远程主机中的目录,在执行对应的脚本之前,会先进入到chdir参数指定的目录中。

creates参数 :使用此参数指定一个远程主机中的文件,当指定的文件存在时,就不执行对应脚本,可参考command模块中的解释。

removes参数 :使用此参数指定一个远程主机中的文件,当指定的文件不存在时,就不执行对应脚本,可参考command模块中的解释。

copy模块

将ansible主机上的文件复制到远程主机,如果目标文件存在,默认覆盖。与之相反的模块叫fetch模块,这个模块的功能是将远程主机的文件提取至ansible主机,目前版本fetch模块只支持复制文件,不支持复制目录。
src参数 :用于指定需要copy的文件或目录

dest参数 :用于指定文件将被拷贝到远程主机的哪个目录中,dest为必须参数

content参数 :当不使用src指定拷贝的文件时,可以使用content直接指定文件内容,src与content两个参数必有其一,否则会报错。

force参数 : 当远程主机的目标路径中已经存在同名文件,并且与ansible主机中的文件内容不同时,是否强制覆盖,可选值有yes和no,默认值为yes,表示覆盖,如果设置为no,则不会执行覆盖拷贝操作,远程主机中的文件保持不变。

backup参数 : 当远程主机的目标路径中已经存在同名文件,并且与ansible主机中的文件内容不同时,是否对远程主机的文件进行备份,可选值有yes和no,当设置为yes时,会先备份远程主机中的文件,然后再将ansible主机中的文件拷贝到远程主机。

owner参数 : 指定文件拷贝到远程主机后的属主,但是远程主机上必须有对应的用户,否则会报错。

group参数 : 指定文件拷贝到远程主机后的属组,但是远程主机上必须有对应的组,否则会报错。

mode参数 : 指定文件拷贝到远程主机后的权限,如果你想将权限设置为"rw-r–r--",则可以使用mode=0644表示,如果你想要在user对应的权限位上添加执行权限,则可以使用mode=u+x表示。

file模块

file模块可以帮助我们完成一些对文件的基本操作,比如,创建文件或目录、删除文件或目录、修改文件权限等。

path参数 :必须参数,用于指定要操作的文件或目录,在之前版本的ansible中,使用dest参数或者name参数指定要操作的文件或目录,为了兼容之前的版本,使用dest或name也可以。

state参数 :此参数非常灵活,此参数对应的值需要根据情况设定,比如,当我们需要在远程主机中创建一个目录的时候,我们需要使用path参数指定对应的目录路径,假设,我想要在远程主机上创建/testdir/a/b目录,那么我则需要设置path=/testdir/a/b,但是,我们无法从"/testdir/a/b"这个路径看出b是一个文件还是一个目录,ansible也同样无法单单从一个字符串就知道你要创建文件还是目录,所以,我们需要通过state参数进行说明,当我们想要创建的/testdir/a/b是一个目录时,需要将state的值设置为directory,"directory"为目录之意,当它与path结合,ansible就能知道我们要操作的目标是一个目录,同理,当我们想要操作的/testdir/a/b是一个文件时,则需要将state的值设置为touch,当我们想要创建软链接文件时,需将state设置为link,想要创建硬链接文件时,需要将state设置为hard,当我们想要删除一个文件时(删除时不用区分目标是文件、目录、还是链接),则需要将state的值设置为absent,"absent"为缺席之意,当我们想让操作的目标"缺席"时,就表示我们想要删除目标。

src参数 :当state设置为link或者hard时,表示我们想要创建一个软链或者硬链,所以,我们必须指明软链或硬链链接的哪个文件,通过src参数即可指定链接源。

force参数 : 当state=link的时候,可配合此参数强制创建链接文件,当force=yes时,表示强制创建链接文件,不过强制创建链接文件分为两种情况,情况一:当你要创建的链接文件指向的源文件并不存在时,使用此参数,可以先强制创建出链接文件。情况二:当你要创建链接文件的目录中已经存在与链接文件同名的文件时,将force设置为yes,回将同名文件覆盖为链接文件,相当于删除同名文件,创建链接文件。情况三:当你要创建链接文件的目录中已经存在与链接文件同名的文件,并且链接文件指向的源文件也不存在,这时会强制替换同名文件为链接文件。

owner参数 :用于指定被操作文件的属主,属主对应的用户必须在远程主机中存在,否则会报错。

group参数 :用于指定被操作文件的属组,属组对应的组必须在远程主机中存在,否则会报错。

mode参数:用于指定被操作文件的权限,比如,如果想要将文件权限设置为"rw-r-x—",则可以使用mode=650进行设置,或者使用mode=0650,效果也是相同的,如果你想要设置特殊权限,比如为二进制文件设置suid,则可以使用mode=4700,很方便吧。

recurse参数:当要操作的文件为目录,将recurse设置为yes,可以递归的修改目录中文件的属性。

archive模块

实现打包压缩功能
ansible webserver -m archive -a ‘path=/var/log dest=/data/log.tar.bz2 format=bz2 ower=wang mode=0600’

hostname模块

此模块用来管理主机名。
ansible 192.168 -m hostname -a ‘name=node01’

cron模块

计划任务模块,分时日月周

ansible webserver -m cron -a ‘hour=2 minute=30 weekday=1-5 name=“backup mysql” job=/root/mysql_backup.sh’

minute参数:此参数用于设置计划任务中分钟设定位的值,比如,上述示例1中分钟设定位的值为5,即minute=5,当不使用此参数时,分钟设定位的值默认为"*"

hour参数:此参数用于设置计划任务中小时设定位的值,比如,上述示例1中小时设定位的值为1,即hour=1,当不使用此参数时,小时设定位的值默认为"*"

day参数:此参数用于设置计划任务中日设定位的值,当不使用此参数时,日设定位的值默认为"*"

month参数:此参数用于设置计划任务中月设定位的值,当不使用此参数时,月设定位的值默认为"*"

weekday参数:此参数用于设置计划任务中周几设定位的值,当不使用此参数时,周几设定位的值默认为"*"

special_time参数:在上述示例3与示例4中,计划任务的时间设定格式为@reboot或者@hourly,@reboot表示重启时执行,@hourly表示每小时执行一次,相当于设置成"0 * * * *" ,这种@开头的时间设定格式则需要使用special_time参数进行设置,special_time参数的可用值有reboot(重启后)、yearly(每年)、annually(每年,与yearly相同)、monthly(每月)、weekly(每周)、daily(每天)、hourly(每时)。

注意:当上述时间单位设定参数都未指定时,计划任务的时间设定默认会被设定为"* * * * *",这样表示每分钟都会执行一次计划任务,所以,在使用cron模块时,我们应该确定对应的时间参数设置正确。

user参数:此参数用于设置当前计划任务属于哪个用户,当不使用此参数时,默认为管理员用户

job参数:此参数用于指定计划的任务中需要实际执行的命令或者脚本,比如上例中的"echo test"命令。

name参数:此参数用于设置计划任务的名称,计划任务的名称会在注释中显示,当不指定计划任务的名称时,ansible会默认为计划任务加入注释,注释的内容为#Ansible: None,假设指定计划任务的名称为test,那么注释的内容为#Ansible: test,在一台机器中,计划任务的名称应该具有唯一性,方便我们以后根据名称修改或删除计划任务。

state参数:当计划任务有名称时,我们可以根据名称修改或删除对应的任务,当删除计划任务时,需要将state的值设置为absent

disabled参数:当计划任务有名称时,我们可以根据名称使对应的任务"失效"(注释掉对应的任务),注意,使用此参数时,除了需要指定任务的名称,还需要同时指定任务的job以及任务的时间设定,而且任务的时间设定必须和对应任务完全相同,否则在注释任务的同时,任务的时间设定会被修改,除非你确定这样做,如果你不明白这段话的意思,可以参考下文中的示例。

backup参数:如果此参数的值设置为yes,那么当修改或者删除对应的计划任务时,会先对计划任务进行备份,然后再对计划任务进行修改或者删除,cron模块会在远程主机的/tmp目录下创建备份文件,以crontab开头并且随机加入一些字符,具体的备份文件名称会在返回信息的backup_file字段中看到,推荐将此此参数设置为yes。

yum模块

管理软件包,只支持RHEL,centos,fedora,不支持ubuntu其他版本
ansible all -m yum -a “name=httpd”

name参数:必须参数,用于指定需要管理的软件包,比如nginx

state参数:用于指定软件包的状态 ,默认值为present,表示确保软件包已经安装,除了present,其他可用值有installed、latest、absent、removed,其中installed与present等效,latest表示安装yum中最新的版本,absent和removed等效,表示删除对应的软件包。

disable_gpg_check参数:用于禁用对rpm包的公钥gpg验证,默认值为no,表示不禁用验证,设置为yes表示禁用验证,即不验证包,直接安装,在对应的yum源没有开启gpg验证的情况下,需要将此参数的值设置为yes,否则会报错而无法进行安装。

enablerepo参数:用于指定安装软件包时临时启用的yum源,假如你想要从A源中安装软件,但是你不确定A源是否启用了,你可以在安装软件包时将此参数的值设置为yes,即使A源的设置是未启用,也可以在安装软件包时临时启用A源。

disablerepo参数:用于指定安装软件包时临时禁用的yum源,某些场景下需要此参数,比如,当多个yum源中同时存在要安装的软件包时,你可以使用此参数临时禁用某个源,这样设置后,在安装软件包时则不会从对应的源中选择安装包。

enablerepo参数和disablerepo参数可以同时使用。

service模块

管理服务模块
ansible all -m service -a “name=httpd state=started”

name参数:此参数用于指定需要操作的服务名称,比如nginx

state参数:此参数用于指定服务的状态,比如,我们想要启动远程主机中的nginx,则可以将state的值设置为started,如果想要停止远程主机中的服务,则可以将state的值设置为stopped,此参数的可用值有started、stopped、restarted、reloaded。

enabled参数:此参数用于指定是否将服务设置为开机 启动项,设置为yes表示将对应服务设置为开机启动,设置为no表示不会开机启动。

user模块

管理用户模块

name参数:必须参数,用于指定要操作的用户名称,可以使用别名user。

group参数:此参数用于指定用户所在的基本组

gourps参数:此参数用于指定用户所在的附加组,注意,如果说用户已经存在并且已经拥有多个附加组,那么如果想要继续添加新的附加组,需要结合append参数使用,否则在默认情况下,当再次使用groups参数设置附加组时,用户原来的附加组会被覆盖。

append参数:如果用户原本就存在多个附加组,那么当使用groups参数设置附加组时,当前设置会覆盖原来的附加组设置,如果不想覆盖原来的附加组设置,需要结合append参数,将append设置为yes,表示追加附加组到现有的附加组设置,append默认值为no。

shell参数:此参数用于指定用户的默认shell

uid参数:此参数用于指定用户的uid号

expires参数:此参数用于指定用户的过期时间,相当于设置/etc/shadow文件中的的第8列,比如,你想要设置用户的过期日期为2018年12月31日,那么你首先要获取到2018年12月31日的unix时间戳,使用命令"date -d 2018-12-31 +%s"获取到的时间戳为1546185600,所以,当设置expires=1546185600时,表示用户的过期时间为2018年12月31日0点0分,设置成功后,查看远程主机的/etc/shadow文件,对应用户的第八列的值将变成17895(表示1970年1月1日到2018年12月31日的天数,unix时间戳的值会自动转换为天数,我们不用手动的进行换算),目前此参数只支持在Linux和FreeBSD系统中使用。

comment参数:此参数用于指定用户的注释信息

state参数:此参数用于指定用户是否存在于远程主机中,可选值有present、absent,默认值为present,表示用户需要存在,当设置为absent时表示删除用户。

remove参数:当state的值设置为absent时,表示要删除远程主机中的用户,但是在删除用户时,不会删除用户的家目录等信息,这是因为remoove参数的默认值为no,如果设置为yes,在删除用户的同时,会删除用户的家目录,当state=absent并且remove=yes时,相当于执行"userdel --remove"命令

password参数:此参数用于指定用户的密码,但是这个密码不能是明文的密码,而是一个对明文密码"加密后"的字符串,相当于/etc/shadow文件中的密码字段,是一个对明文密码进行哈希后的字符串,你可以在python的命令提示符下输入如下命令,生成明文密码对应的加密字符串。

import crypt; crypt.crypt(‘666666’)

输入上述命令后,即可得到明文密码666666对应的加密字符串。

update_password参数:此参数有两个值可选,always和on_create,当此参数的值设置为always时表示,如果password参数设置的值与用户当前的加密过的密码字符串不一致,则直接更新用户的密码,默认值即为always,但是当此参数设置为on_create时,如果password参数设置的值与用户当前的加密过的密码字符串不一致,则不会更新用户的密码字符串,保持之前的密码设定,如果是新创建的用户,即使此参数设置为on_create,也会将用户的密码设置为password参数对应的值。

generate_ssh_key参数:此参数默认值为no,如果设置为yes,表示为对应的用户生成ssh密钥对,默认在用户家目录的./ssh目录中生成名为id_rsa的私钥和名为id_rsa.pub的公钥,如果同名的密钥已经存在与对应的目录中,原同名密钥并不会被覆盖(不做任何操作)。

ssh_key_file参数:当generate_ssh_key参数的值为yes时,使用此参数自定义生成ssh私钥的路径和名称,对应公钥会在同路径下生成,公钥名以私钥名开头,以".pub"结尾。

ssh_key_comment参数:当generate_ssh_key参数的值为yes时,在创建证书时,使用此参数设置公钥中的注释信息,但是如果同名的密钥对已经存在,则并不会修改原来的注释信息,即不做任何操作,当不指定此参数时,默认的注释信息为"ansible-generated on 远程主机的主机名"

ssh_key_passphrase参数:当generate_ssh_key参数的值为yes时,在创建证书时,使用此参数设置私钥的密码,但是如果同名的密钥对已经存在,则并不会修改原来的密码,即不做任何操作

ssh_key_type参数:当generate_ssh_key参数的值为yes时,在创建证书时,使用此参数设置密钥对的类型,默认密钥类型为rsa,但是如果同名的密钥对已经存在,并不会对同名密钥做任何操作

group模块

group模块可以帮助我们管理远程主机上的组。

name参数:必须参数,用于指定要操作的组名称。

state参数:用于指定组的状态,两个值可选,present,absent,默认为present,设置为absent表示删除组。

gid参数:用于指定组的gid

lineinfile模块

ansible在使用sed进行替换的时候,经常会出现需要转义的问题,而且ansible在遇到特殊符号进行替换的时候,存在问题,无法正常替换,所以在ansible在自身提供了两个模块:lineinfile模块和replace模块,可方便的进行替换操作,功能相当于sed,可修改文件内容。
ansible webserver -m lineinfile -a “path=/etc/selinux/config regexp=’^SELINUX=’ line=‘SELINUX=enforcing’”

path参数 :必须参数,指定要操作的文件。

line参数 : 使用此参数指定文本内容。

regexp参数 :使用正则表达式匹配对应的行,当替换文本时,如果有多行文本都能被匹配,则只有最后面被匹配到的那行文本才会被替换,当删除文本时,如果有多行文本都能被匹配,这么这些行都会被删除。

state参数:当想要删除对应的文本时,需要将state参数的值设置为absent,absent为缺席之意,表示删除,state的默认值为present

backrefs参数:默认情况下,当根据正则替换文本时,即使regexp参数中的正则存在分组,在line参数中也不能对正则中的分组进行引用,除非将backrefs参数的值设置为yes,backrefs=yes表示开启后向引用,这样,line参数中就能对regexp参数中的分组进行后向引用了,这样说不太容易明白,参考下面的示例命令比较直观一点,backrefs=yes除了能够开启后向引用功能,还有另一个作用,默认情况下,当使用正则表达式替换对应行时,如果正则没有匹配到任何的行,那么line对应的内容会被插入到文本的末尾,不过,如果使用了backrefs=yes,情况就不一样了,当使用正则表达式替换对应行时,同时设置了backrefs=yes,那么当正则没有匹配到任何的行时,则不会对文件进行任何操作,相当于保持原文件不变,如果没有理解,就按照下面的示例命令,动手操作一下吧,那样更加直观。

insertafter参数:借助insertafter参数可以将文本插入到“指定的行”之后,insertafter参数的值可以设置为EOF或者正则表达式,EOF为End Of File之意,表示插入到文档的末尾,默认情况下insertafter的值为EOF,如果将insertafter的值设置为正则表达式,表示将文本插入到匹配到正则的行之后,如果正则没有匹配到任何行,则插入到文件末尾,当使用backrefs参数时,此参数会被忽略。

insertbefore参数:借助insertbefore参数可以将文本插入到“指定的行”之前,insertbefore参数的值可以设置为BOF或者正则表达式,BOF为Begin Of File之意,表示插入到文档的开头,如果将insertbefore的值设置为正则表达式,表示将文本插入到匹配到正则的行之前,如果正则没有匹配到任何行,则插入到文件末尾,当使用backrefs参数时,此参数会被忽略。

backup参数:是否在修改文件之前对文件进行备份。

create参数 :当要操作的文件并不存在时,是否创建对应的文件。

replace模块

类似于sed命令,基于正则进行匹配和替换
ansible webserver -m replace -a “path=/etc/fstab regexp=’^(UUID.*)’ replace=’#\1’”

path参数 :必须参数,指定要操作的文件,2.3版本之前,只能使用dest, destfile, name指定要操作的文件,2.4版本中,仍然可以使用这些参数名,这些参数名作为path参数的别名使用。

regexp参数 : 必须参数,指定一个python正则表达式,文件中与正则匹配的字符串将会被替换。

replace参数 : 指定最终要替换成的字符串。

backup参数 :是否在修改文件之前对文件进行备份,最好设置为yes

setup模块

setup模块来收集主机的系统信息,这些facts信息可以直接以变量的形式使用,但是如果主机较多,会影响执行速度,可以使用gather_facts:no 来禁止ansible收集facts信息。
可以加filter参数来查看特定的信息。

playbook剧本

playbook剧本是由一个或多个“play”组成的列表,play的主要功能在于将预定的一组主机,装扮成事先通过ansible中task定义好的角色,task实际是调用ansible的一个module,将多个play组织在一个playbook中,即可以让它们联合起来,按事先编排的机制执行预定义的动作,playbook文件是采用YAML语言编写的,YAML语言即是键值语言。

YAML语言介绍

YAML语言是一个可读性高的用来表达资料序列的格式,YAML参考了其他多种语言,包括XML、c语言、python、perl以及电子邮件格式RFC2822等。
语言特性: YAML可读性好
YAML和脚本语言的交互性好
YAML使用实现语言的数据类型
YAML有一个一致的信息模型

语法
● 在第一个文件的第一行,用三个连续字号“-”开始,还有选择性的连续三个号点(…)用来表示文件的结尾。
● 次行开始正常写playbook的内容,一般建议写明该playbook的功能。
● 缩进必须一致,不能tab和空格混用,同样的缩进表示同一级别。
● k/v的值均需大小写敏感。
● 多个k/v可同行也可换行写,同行写的时候要使用英文逗号分隔。
● v可以是字符串,也可以是另一个列表。
● 一个完整的代码块功能需最少元素要包括name和task。
● 一个name只能包括一个task。
● YAML文件扩展名通常为yml或yaml。

list列表
列表由多个元素组成,且所有元素均使用“-”打头
	- A
	- B
	- C
dictionary字典
字典通常是kv在组成的。
	name: A
	Job:  B
	skill:C
{name: "A",Job: "B",skill: "C"}

playbook核心元素

hosts :执行远程主机列表
tasks :任务集
variables: 内置变量或自定义在playbook中调用
templates模板: 可替换模板文件中的变量并实现一些简单逻辑的文件
handlers和notify结合使用:由特定条件触发的操作,满足条件方才执行,否则不执行(见下文示例)一般在需要重启服务并且重新加载配置文件的时候使用。
tags标签:指定某条任务执行,用于选择运行playbook中的部分代码

ansible-playbook --tags=t2 nginx.yml

ansible具有幂等性,因此会自动调过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常的长,此时,如果确信其没有变化,就可以通过tags跳过这些代码片段。

hosts:playbook中的每一个play的目的都是为了让特定主机以某个指定用户身份执行任务。hosts用于指定要执行任务的主机,需要事先定义在主机清单中。

- hosts: webserver:appserver

remote_user组件:可用于host和task中,也可以通过指定其通过速冻的方式在远程主机上执行任务,其可用于play全局或某任务。

task列表和action组件:play的主体部分是task list,task list中有一个或多个task,各个task按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个task后,再开始第二个task。task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量,模块执行时幂等的,这就意味着多次执行是安全的,因为其结果均一致。每个task都应该有其name,用于playbook的执行结果输出,建议其内容能清晰的描述任务执行步骤,如果未提供name,则action的结果将用于输出。

task一般格式使用 module:arguments(模块名:参数)

例子:

---
	- hosts: webserver
	  yum: name=httpd
	- name: start httpd
	  service: name=httpd state=started enabled=yes

YAML文件写好之后就可以使用playbook命令运行

ansible-playbook FILE.yml … [options]

在用不到收集硬件信息的时候,一般在playbook中把facts禁用,gather_facts=no,以加快运行速度。

常用选项
–check -c #只检测可能会发生的改变,但不真正的执行操作
–list-hosts #列出运行任务的主机
–list-tags #列出tag
–list-tasks #列出task
–limit 主机列表 #只针对主机列表中的主机执行
-v -vv -vvv #显示过程

ansible-playbook -C FILE.yml #对写好的yml文件做语法检查。

playbook剧本安装nginx示例


---
#install nginx
- hosts: all
  remote_user: root
  gather_facts: no

  tasks:
    - name: creat group
      user: name=nginx state=present
    - name: add user
      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

---
- hosts: all
  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
    - name: ensure apache is running
      service: name=httpd state=started enabled=yes

  handlers:
    - name: restart httpd
      service: name=httpd state=restarted

playbook中使用变量

再ansible中使用变量,可以使工作变得更加灵活,变量的使用方式有很多种,首先变量应该由字母、数字、下划线组成,变量名需要以字母开头,ansible内置的关键字不能作为变量名。

变量的定义: variable=value

例如 http_port=80

变量的调用方式:通过{{ variable_name }}调用变量,且变量名前后建议加空格,有时用"{{ variable_name }}"才生效。

变量来源

​ 1,ansible的setup facts远程主机的所有变量可直接调用

​ 2,通过命令行指定变量,优先级最高

使用setup模块中变量

使用setup变量(相当于系统自带的变量)

---
#var.yml
- hosts: all
  remote_user: root
  
  tasks:
    - name: create log file
      file: name=/data/{{ ansible_nodename }}.log state=touch owner=wang mode=600
      
      
ansible-playbook var.yml
在playbook命令行中定义变量

在ansible-playbook命令中有一个-e选项,相当于传参,可以把定义的变量在命令行赋值之后传到yml文件中。

---
- hosts: all
  remote_user: root
  gather_facts: no
  
  tasks:
    - name: install package
      yum: name{{ pkname }} state=present
      
 
ansible-playbook -e pkname=mysql
在playbook文件中定义变量

在yml文件中使用vars关键字,对变量进行定义。

---
- hosts: all
  remote_user: root
  vars:
    - username: user1
    - groupname: group1
    
  tasks:
    - name: creat group
      group: name={{ groupname }} state=present
    - name: create user
      user: name={{ username }} state=present
使用变量文件

可以在一个独立的playbook文件中定义变量,在另一个playbook文件中引用变量文件中的变量,比playbook中定义的变量优先级高。

vim vars.yml
---
#variables file
pkg_name:vsftpd
srv_name:vsftpd


vim install_app.yml
---
#install app and config
- hosts: appsrvs
  remote_user: root
  gather_facts: no
  
  tasks:
    - name: install pkg
      yum : name={{ pkg_name }}
      tags: install
    - name: start srv
      service: name={{ srv_name }} state=started enabled=yes
主机清单文件中定义变量

在inventory主机清单文件中为指定的主机定义变量以便于在playbook中使用。

#针对单一的主机进行变量的设置
[websrvs]
192.168.1.1 http_port=80 maxRequestsPerChild=808
192.168.1.2 http_port=8080 maxRequestsPerChild=909
#针对主机组进行变量的设置
[websrvs]
192.168.1.1
192.168.1.2
[websrvs:vars]
test_var1='group var1'
http_port=8090

针对单一主机的变量优先级高(一般来说,范围越小,优先级越高)

template模板

template是ansible的一个模块,其功能是根据模板文件动态生成配置文件。

模板是一个文本文件,可以做为生成文件的模板,并且模板文件中还可以嵌套jinja语法。

template功能:可以根据和参考模块文件,动态生成相类似的配置文件

template文件必须存放在template目录下,且命名为.j2结尾

yaml/yml文件需和template目录平级,这样template模块会自动去找template目录下的模板文件,就不用在yml文件中写模板路径了。

template变更替换

示例

mkdir templates  #在存放yml文件的目录下创建templates目录
cp /etc/nginx/nginx.conf templates/nginx.conf.j2 #在templates目录下生成j2文件
vim  nginx.conf.j2
worker_processes 4;

vim templngx.yml
---
- hosts: all
  remote_user: root
  gather_facts: no

  tasks:
    - name: install ngx
      yum: name=nginx
    - name: template config to remote hosts
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
    - name: start srv
      service: name=nginx state=started enabled=yes
template中使用流程控制for和if

template中也可以使用流程控制for循环和if条件判断,实现动态生成文件功能

vim templngx2.yml
---
- hosts: all
  remote_user: root
  vars:
    nginx_vhosts:
      - 81
      - 82
      - 83
   tasks:
    - name: template config
      template: src=nginx.conf2.j2 dest=/etc/nginx/nginx.conf
      
vim templates/nginx.conf2.j2
{% for vhost in nginx_vhosts %}
server {
    linten {{ vhost }}
}
{% endfor %}

#得到的结果
cat /etc/nginx/nginx.conf
server {
    linten 81
}
server {
    linten 82
}
server {
    linten 83
}

#templngx3.yml
---
- hosts: server1
  remote_user: root
  vars:
    nginx_vhosts:
      - listen: 8080
  tasks:
    - name: config file
      template: src=nginx.conf3.j2 dest=/etc/nginx/nginx3.conf
      
#templates/nginx.conf3.j2
{% for vhost in nginx_vhosts %}
server {
  listen {{ vhost.listen }}      #这里的使用.listen是因为vhost不是一个元素,而是一个字典,而.listen就表示字典中的Key,以此来取到字典中的值。
}
{% endfor %}

#得到的结果
cat /etc/nginx/nginx3.conf
server {
  listen 8080
}

在模板文件中还可以使用if条件判断,决定是否生成相关的配置信息

#tmpngx.yml
---
- hosts: server1
  remote_user: root
  vars:
    nginx_vhosts:
      - web1:
        listen: 8080
        root: "/var/www/nginx/web1/"
      - web2:
        listen: 8080
        server_name: "web2.zhang.com"
        root: "/var/www/nginx/web2/"
      - web3:
        listen: 8080
        server_name: "web3.zhang.com"
        root: "/var/www/nginx/web3/"
        
  tasks:
    - name: temple config to
      template: src=nginx.conf5.j2 dest=/etc/nginx/nginx.conf5
        
        
#templates/nginx.conf5.j2
{% for vhost in nginx_vhosts %}
server {
    listen {{ vhost.listen }}
    {% if vhost.server_name is defined %}   ##判断是否有server_name,如果有server_name则生成主机名语句块,如果没有则不生成。
server_name {{ vhost.server_name }}
    {% endif %}
root {{ vhost.root }}
}
{% endfor %}

#得到的结果
cat /etc/nginx/nginx.conf5
server {
    listen 8080
    root /var/www/nginx/web1/
}
server {
    listen 8080
    server_name web2.zhang.com
    root /var/www/nginx/web2/
}
server {
    listen 8080
    server_name web3.zhang.com
    root /var/www/nginx/web3/
}

playbook中使用when

when语句,可以实现条件测试,如果需要根据变量、facts或前任务执行的结果来做为某task执行与否的前提时要用到条件测试,通过在tasks后添加when子句即可使用条件测试,jinja2语法格式。

示例

#当系统版本为6的时候安装mysql,当系统版本为7的时候安装mariadb
---
- hosts: all

  tasks:
    - name: install mysql
      yum: name=mysql-server
      when: ansible_distribution_major_version == "6" 
    - name: install mariadb
      yum: name=mariadb-server
      when: ansible_distribution_major_version == "7"

playbook中使用迭代with_items

迭代:当有需要重复性的执行任务时,可以使用迭代机制,对迭代项的引用,固定变量名为“item”,要在task中使用with_items给定要迭代的元素列表。

示例

#这里的迭代相当于for循环中for i in a b c,item相当于是i,是一个变量,with_items的列表相当于要取的值和执行几次循环。
---
- hosts: all
  remote_user: root
  
  tasks:
    - name: add server users
      user: name={{ item }} state=present group=wheel
      with_items:
        - user1
        - user2

roles角色

ansible自1.2版本后引入的新特性,用于层次化,结构化的组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令引入即可。其实roles就是通过分别将变量、文件、任务、模板以及处理器放置于单独的目录中,并可以便捷的include他们的一种机制。

roles注意事项

1、编写任务(task)的时候,里面不需要写需要执行的主机,单纯的写某个任务是干什么的即可,装软件的就是装软件的,启动的就是启动的。单独做某一件事即可,最后通过main.yml将这些单独的任务安装执行顺序include进来即可,这样方便维护且一目了然。
2、定义变量时候直接安装k:v格式将变量写在vars/main.yml文件即可,然后task或者template直接调用即可,会自动去vars/main.yml文件里面去找。
3、定义handlers时候,直接在handlers/main.yml文件中写需要做什么事情即可,多可的话可以全部写在该文件里面,也可以像task那样分开来写,通过include引入一样的可以。在task调用notify时直接写与handlers名字对应即可(二者必须高度一直)。
4、模板文件一样放在templates目录下即可,task调用的时后直接写文件名字即可,会自动去到templates里面找。注意:如果是一个角色调用另外一个角色的单个task时后,那么task中如果有些模板或者文件,就得写绝对路径了。

roles的目录结构

roles
└── nginx
    ├── files
    │   └── main.yml
    ├── tasks
    │   ├── groupadd.yml
    │   ├── install.yml
    │   ├── main.yml
    │   ├── restart.yml
    │   └── useradd.yml
    └── vars
        └── main.yml


playbook调用角色

调用角色方法1:

---
- hosts: server1
  remote_user: root
  roles:
    - mysql
    - mamcached
    - nginx

调用角色方法2:

键role用于指定角色名称,后续的k/v用于传递变量给角色

---
- hosts: all
  remote_user: root
  roles:
    - mysql
    - { role: nginx,username: nginx }

调用角色方法3:

还可以基于条件测试实现角色调用

---
- hosts: all
  remote_user: root
  roles:
    - { role: nginx,username: nginx,when: ansible_distribution_major_version == "7"} 

示例:httpd的roles书写

#创建角色相关目录及文件
cd /etc/ansible/roles
mkdir -p httpd/{files,handlers,tasks}
#安装httpd
vim tasks/install.yml
- name: install httpd
  yum: name=httpd
#配置文件,http.conf文件在files目录下
vim tasks/config.yml
- name: config file
  copy: src=httpd.conf dest=/etc/httpd/conf backup=yes
  notify: restart
#配置主页,index文件在files目录下
vim tasks/index.yml
- name: index.yml
  copy: src=index.html dest=/var/www/html
#启动服务
vim tasks/service.yml
- name: start service
  service: name=httpd state=started enabled=yes
#调用其他yml文件的入口文件书写
vim tasks/main.yml
- include: install.yml
- include: config.yml
- include: index.yml
- include: service.yml
#书写handlers
vim handlers/mian.yml
- name: restart
  service: name=httpd state=restarted

#最后书写playbook,调用角色,这个playbok一定要是和roles平级的目录
vim /etc/ansible/role_httpd.yml
---
- hosts: server1
  remote_user: root

  roles:
    - httpd
  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值