[TOC]
基础概念 什么是ansible? 答:它是一个”配置管理工具”,它是一个Linux系统上的”自动化运维工具”;
ansible能做什么? 正如其他配置管理工具一样,ansible可以帮助我们完成一些批量任务,或者完成一些需要经常重复的工作。
ansible优秀的特性:
其他的一些运维配置管理工具还有puppet或者saltstack而ansible相比较于他们的优点:
参考文档帮助:https://docs.ansible.com/ansible/latest/index.html
环境设置:采用VMWARE-player模拟环境实现;
10.10.107.222 Master-Ansible管理端 10.10.107.234 Slave-Ansible 受控端(Ubuntu) 10.20.172.235 Slave-Ansible 受控端(Centos)
Ansible安装:
#Step1.我使用yum源的方式安装ansible,因为安装ansible需要epel源,所以我配置了阿里的epel源和centos7系统镜像源, $ pwd /etc/yum.repos.d # cat aliBase.repo [aliBase] name=aliBase baseurl=https://mirrors.aliyun.com/centos/$releasever/os/$basearch/ enabled=1 gpgcheck=1 gpgkey=https://mirrors.aliyun.com/centos/$releasever/os/$basearch/RPM-GPG-KEY-CentOS-$releasever # cat aliEpel.repo [aliEpel] name=aliEpel baseurl=https://mirrors.aliyun.com/epel/$releasever\Server/$basearch/ enabled=1 gpgcheck=0 #Step2.yum源配置完成后,安装ansible yum install ansible #此时yum源中对应的版本为ansible-2.8.1-1.el7.noarch.rpm #Step3.验证安装 $ansible 127.0.0.1 -m ping #使用ansible去ping本机, 127.0.0.1 | SUCCESS => { "changed": false, "ping": "pong" }
安装成功后如果想要通过ansible管理某主机,使用ansible管理必须同时满足两个最基本的条件如下
ansible提供一个默认的”清单”文件 /etc/ansible/hosts并且采用ini风格里面有默认的配置示例使用提示;
#由于ansible工作方式,需要将受管主机的IP地址、ssh端口号等信息添加到一个被称作为"清单(Inventory)"的配置文件中 # ansible_port 用于配置对应主机上的sshd服务端口号默认的22号端口, # ansible_user 用于配置连接到对应主机时所使用的用户名称。 # ansible_ssh_pass 用于配置对应用户的连接密码。 echo "10.10.107.234 ansible_port=22 ansible_user=root ansible_ssh_pass=ubuntu" >> /etc/ansible/hosts #通过ansible主机管理234主机 #当为主机配置别名时,主机的IP地址必须使用anible_host关键字进行指明,否则ansible将无法正确的识别对应的主机。 echo "test ansible_host=10.20.172.104 ansible_port=22 ansible_user=root ansible_ssh_pass=2019" >> /etc/ansible/hosts #设置别名的方式 #注意:上述配置参数都是ansible2.0版本以后的写法,2.0版本之前,应遵从如下写法 ansible_port #应该写成ansible_ssh_port ansible_user #应该写成ansible_ssh_user/pass ansible_host #应该写成ansible_ssh_host #验证清单配置(两台机器都是OK的) $ansible 10.10.107.234 -m ping 10.10.107.234 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } ansible test -m ping test | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" }
ansible主控端如何采用密匙来登录受控端?
#首先,生成默认格式的密钥对,私钥与公钥。 ssh-keygen #然后将生成的公钥加入到10.10.107.234的认证列表 ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected] #好了公钥认证的相关操作配置完成,此刻,我们已经可以通过ansible主机免密码连接到主机60中了。
因为配置了密钥认证,所以可以实现免密码创建ssh连接,既然已经能够免密码创建ssh连接,那么在配置”主机清单”时,就没有必要再提供对应主机的用户名与密码了,所以在完成了密钥认证的相关配置后,我们可以将清单中的配置精简为如下格式。
10.10.107.234 ansible_port=22 #精简模式(默认也是的22号端口,所以可以忽略) test ansible_host=10.10.107.234 ansible_port=22 #别名模式
安装总结:
我们可以在ansible提供的清单配置文件中进行配置我们以该文件进行讲解
$vim /etc/ansible/hosts # This is the default ansible 'hosts' file. # It should live in /etc/ansible/hosts # 示例1.清单支持"分组"功能,我们可以将某些主机分为一组,然后通过组名去管理组内的所有主机。 # 比如,主机234和主机235都属于A模块的服务器,主机221属于B模块的服务器,我们则可以在清单中进行如下配置 [A] 10.10.107.234 10.10.107.235 [B] 10.10.107.221 # 示例2.如果两台主机的IP地址是连续的我们可以使用更简洁的方法,配置A组中的受管主机,示例如下 [A] 10.10.107.[234:235] [B] 10.10.107.221 # 示例3. 使用主机名配置受管主机的前提是ansible主机可以正确解析对应的主机名,比如,我们想要通过主机名配置两台主机,示例如下。 [A] db01.weiyigeek.net db02.weiyigeek.net [B] db0[1:2].weiyigeek.net # 示例4.为了更加的灵活的管理受管主机,可能需要在组内嵌套组。 #比如,服务器环境从大类上可以分为"生产环境"和"测试环境",把主机分成了两组生产组和测试组,但是生产环境又包含很多业务模块, #比如,A模块生产组、B模块生产组,同理测试环境中也会有同样的问题,比如A模块测试环境组,B模块测试组,这时我们就需要更加细化的进行分组,示例如下 [testA] 10.10.107.1 [testB] 10.10.107.2 #而master组中包含"子组",没错,"children"关键字表示当前组中存在子组就是testA组和testB组 [Master:children] test[A:B]
验证配置结果:
#验证1.A组中包含主机60与61,B组中包含主机70,经过上述配置后,我们可以通过组名去管理组内的所有主机,示例如下。 ansible A -m ping ansible B -m ping ansible all -m ping #将配置文件中所有的主机进行ping操作 #验证4.如我们需要针对生产环境中的所有主机进行操作时,调用master组即可 ansible Master -m ping
WeiyiGeek.验证1
其实Ansible的清单文件/etc/ansible/hosts不仅能够识别INI的配置语法还能够识别”YAML”的配置语法。 注意,为了使缩进显得更加明显,此处每次缩进使用两个空格
$vim /etc/ansible/hosts #使用YAML语法配置的主机清单非常简单下面就是他的配置示例 #示例1.所有受管理组演示 all: #管理清单中的所有主机的一个组,这里的"all:"就是这个含义 hosts: #第二行开头使用一个空格作为缩进,使用hosts关键字,表示hosts属于all的下一级,(后面的都是采用两个空格) 10.10.107.1 10.10.107.2 #上例相当于如下INI配置 10.1.1.60 10.1.1.61 #示例2.ini风格对比yaml #先看一个INI风格的配置表示当前清单中有3台受管主机,主机61不属于任何组,主机60属于test1组,主机70属于test2组 10.1.1.61 [test1] 10.1.1.60 [test2] 10.1.1.70 #使用YAML语法进行同等效果的配置如下 #当直接在清单中创建组时,需要在all关键字内使用children关键字,而定义每个组时,有必须使用hosts关键字,指明组内的主机 all: hosts: 10.1.1.61: children: #分组都是children test1: hosts: 10.1.1.60: test2: hosts: 10.1.1.70: #从上例可以看出,
组中嵌套时候:
#仍然先写出INI风格的示例以作对比,如下 [proA] 10.1.1.60 [proB] 10.1.1.70 [pro:children] proA proB #对应YAML格式的配置如下pro组有两个子组,分别为proA组和proB组,而这两个组分别有自己组内的主机。 all: children: pro: children: proA: hosts: 10.1.1.60 proB: hosts: 10.1.1.70
当我们使用YAML语法配置清单时,无非是使用hosts、children
等关键字与我们的自定义名称进行排列组合罢了。
认证管理yaml配置:
#ini格式如下: 10.1.1.6 test7 ansible_host=10.1.1.7 ansible_port=22 localhost ansible_connection=local #yaml的配置语法 all: hosts: 10.1.1.6 test7: ansible_host: 10.1.1.7 #注意冒号后都有空格,注意yaml语法 ansible_port: 22 localhost: ansible_connection: local
综合示例:
#以下是如何立即部署到创建的容器的示例 - name: create jenkins container docker_container: docker_host: myserver.net:4243 name: my_jenkins image: jenkins - name: add container to inventory add_host: name: my_jenkins ansible_connection: docker ansible_docker_extra_args: "--tlsverify --tlscacert=/path/to/ca.pem --tlscert=/path/to/client-cert.pem --tlskey=/path/to/client-key.pem -H=tcp://myserver.net:4243" #设置守护进程 ansible_user: jenkins changed_when: false - name: create directory for ssh keys delegate_to: my_jenkins file: path: "/var/jenkins_home/.ssh/jupiter" state: directory
参考absible的yaml语法:https://docs.ansible.com/ansible/2.4/intro_inventory.html#id7
描述:主要是描述ansible命令与ansible-doc命令参数
语法参数:
ansible [主机] [选项] [主机连与认证] #[option] -a #用于传递模块所需要使用的参数 -a "src=/etc/fstab dest=/testdir/ansible/"表示为fetch模块传入了两个参数 -m #选项用于调用指定的模块,-m fetch"表示调用fetch模块; -e #指定参数变量以供模块使用
补充命令1:
ansible-doc #模板帮助以及模块命令作用查看 #参数 -l,--list 模块简介与全部模块 -s 模块详情
补充命令2:
ansible-playbook #运行剧本配置文件脚本 #参数 --syntax-check #语法验证 --check #模拟验证执行 --list-tags #概览一下playbook中都有哪些标签 --tags [tagname] #指定执行tagname的任务 --skip-tags [tagname] #跳过执行tagname的任务而执行其他任务; -e,--extra-vars #指定在play中使用的变量传入多/单个变量,还可以通过json字符串形式传入;
命令示例:
#ansible-playbook进行yml配置语法检查 ansible-playbook --syntax-check test.yml #ansible-playbook进行yml配置模拟执行 ansible-playbook --check test.yml #只有标签对应的任务会被执行,其他任务都不会被执行 ansible-playbook --tags task1 test.yml #指定"不执行的任务",task1标签的任务将不被执行 ansible-playbook --skip-tags task1 test.yml #指定在play中使用的变量(传入单个变量 / diphenhydramine变量) ansible-playbook cmdvar.yml --extra-vars "pass_var=cmdline pass var" ansible-playbook cmdvar.yml -e 'pass_var="test" pass_var1="test1"' ansible-playbook cmdvar.yml -e '{"testvar":"test","testvar1":"test1"}' ansible-playbook cmdvar.yml -e '{"countlist":["one","two","three","four"]}' #获取值使用如下两种语法引用变量 {{countlist[0]}} 或者 {{countlist.0}}
当我们使用ansible完成实际任务时,需要依靠ansible的各个模块,比如前的ping模块
#ping模块使用 $ansible all -m ping ansible-doc -l #获取到的模块信息比较概括(查看absible当前所有模块) ansible-doc -s ping #ping模块的详细使用 ansible-doc -s fetch #我们需要将受管主机中的文件拉取到ansible主机时则可以使用此模块
比如:查看fetch模块的使用帮助
# ansible-doc -s fetch - name: Fetch files from remote nodes fetch: dest: # (required - 必须参数) 指定存入到ansible主机上文件路径 src: # (required - 必须参数) 指定远程主机文件路径 validate_checksum: #Verify checksums fail_on_missing: #默认yes,只有再文件不存在的时候失败 flat: #文件重写覆盖
基础示例:
#主机清单-yaml文件 all: hosts: local: ansible_host: 10.10.107.222 ansible_user: root ansible_ssh_pass: [email protected] children: ops: children: testA: hosts: 10.10.107.221 testB: hosts: 10.20.172.179 #示例:拉取ops组中所有主机的/etc/fstab文件拉取到本地 ansible ops -m fetch -a "src=/etc/fstab dest=/tmp/ansible/" #初次拉取 #黄色提示,并且发生改变 10.10.107.221 | CHANGED => { "changed": true, #关键点 "checksum": "2b8323413e9c5a3067f61c27ca5ea21378bae582", #远程MD5校验 "dest": "/tmp/ansible/10.10.107.221/etc/fstab", #(会以主机名称建立文件夹,然后再存入) "md5sum": "edf31ba4fd10068f6310f4343855af89", #本地MD5 "remote_checksum": "2b8323413e9c5a3067f61c27ca5ea21378bae582", #远程MD5校验 "remote_md5sum": null }
WeiyiGeek.fetch
返回提示颜色来看幂等性
比如:这时候我把10.10.107.221的fstab进行更改
echo " " >> /etc/fstab #再次进行文件拉取查看效果 10.10.107.221 | CHANGED => { #对比点 "changed": true, #对比点 (Yellow) "checksum": "e0719b31dd9445c5da3dd5e04f13ed44855aacd0", "dest": "/tmp/ansible/10.10.107.221/etc/fstab", "md5sum": "631e37410fac691ead3c90e6938494ef", "remote_checksum": "e0719b31dd9445c5da3dd5e04f13ed44855aacd0", #比对点 "remote_md5sum": null } 10.20.172.179 | SUCCESS => { "changed": false, # 由于终端的问题我是白色的(Green) "checksum": "39ffc633a100c2b2d06a3d9d0e625dff1ca7043c", "dest": "/tmp/ansible/10.20.172.179/etc/fstab", "file": "/etc/fstab", "md5sum": "c63b434a7a09baea8b7b59fce8cb807b" }
WeiyiGeek.幂等性差别
_总结_:
描述:将我们前面所学到的模块的知识点应用到工作场景,进一步理解与使用ansible
假设,我们想要在test70主机上安装nginx并启动,我们可以在ansible主机中执行如下3条命令
#确定YUM源 使用yum模块安装nginx 返回再启动nginx服务 ansible test70 -m yum_repository -a 'name=aliEpel description="alibaba EPEL" baseurl=https://mirrors.aliyun.com/epel/$releasever\Server/$basearch/' ansible test70 -m yum -a 'name=nginx disable_gpg_check=yes enablerepo=aliEpel' ansible test70 -m service -a "name=nginx state=started"
但是在实际的工作环境中我们可能需要经常在新主机上安装nginx,难道每次有新的服务器加入工作环境,我们都要修改上述3条命令中的主机名并且重新将每一条命令执行一遍吗?
这样似乎有些麻烦,肯定有更好的办法,没错我们可以将上述命令写成脚本,每次修改一些变量然后执行脚本就行了,而ansible天生就提供了这种类似"脚本"的功能
,在ansible中类似”脚本”的文件被称作”剧本”,’剧本’的英文名称为’playbook’,我们只需要将要做的事情编写成playbook,把不同的模块按照顺序编排在剧本中,ansible就会按照剧本一步一步的执行,最终达到我们的目的,虽然playbook的功能与脚本类似,但是剧本并不是简单的将ad-hoc命令按照顺序堆砌在一个可执行文件中,编写剧本需要遵循YAML语法
;
一个’playbook’是由一个或多个’play’组成的,这样说可能不太容易理解,那么我们打个比方,一个'剧本'是由一个或多个'桥段'组成的,每个桥段都有不同的场景、人物、故事
,所有的桥段组合在一起,组成一个完整的剧本,剧本就是playbook桥段就是play;当然’桥段’只是我自己为了方便理解给’play’起的中文名,官方名称只叫\”play\”。
剧本初识-单个play 首先,我们需要创建一个YAML格式的playbook文件,playbook文件以”.yaml”或者”.yml”作为文件名后缀,此处我们创建一个名为”test.yml”的剧本文件。
#比如:对本地主机采用ping模块,然后采用file模块再主机上创建目录; ansible local -m ping ansible local -m file -a "path=/testdir/test state=directory" #yaml配置文件写法 test.yml --- - hosts: local,testA remote_user: root tasks: - name: ping The host ping: - name: make directory test file: path: /tmp/ansible-playbook state: directory
yml配置文件解析:
---
表示yml文档的开始-
作为开头表示一个块序列的节点;host关键字指定要操作的主机或者组,多台主机或者组采用,
分割采用'ansible-playbook'命令
测试运行剧本(脚本):
[[email protected] ~]# ansible-playbook test.yml
playbook执行后返回了一些信息,这些信息是这次剧本运行的概况:
WeiyiGeek.playbook
黄色的
,这是因为幂等性的缘故,比如这次local主机我们在playbook中明明只写了两个任务,为什么最后执行时却有三个任务呢? 答:因为每个play在执行时都会先执行一个默认任务,’Gathering Facts’任务会收集当前play对应的目标主机的相关信息,收集完这些基础信息后才会执行我们指定的任务,
补充说明:
剧本初识-多个play 比如我们把上面的主机或者组分别分成两个不同的场景:对于Local主机模块是不变化的,对于主机组B采用file模块以及user模块来创建文件和建立用户
demo.yml --- - hosts: local remote_user: root tasks: - name: ping The host ping: - name: make directory test file: path: /tmp/ansible-playbook state: directory - hosts: testB remote_user: root tasks: - name: touch file file: path: /tmp/file.txt state: touch - name: create user demo user: name: demo password: "$6$ygRbo7Fj.mMU2KY0$OEqihCCn5UfOsvMyzPNPBgx3bzAtwrOFyFvacgUmA374XOAEtUCrdjbW5Ip.Zqo491o3kD5I.HaC9nLhh6x741" uid: 1024 mode: 0700
脚本(剧本执行):ansible-playbook demo.yml
,执行后的结果验证:
WeiyiGeek.playbookdemo.yml
其他yml配置文件形式说明:
#形式1:使用了"等号",每个参数之间使用空格隔开这种格式也是完全正确的,0.8版本以后的ansible推荐的书写格式 tasks: - name: make testfile file: path=/testdir/testfile state=touch mode=0700 - name: make testfile file: path=/testdir/testfile #即使把多个参数分行写,也需要注意缩进 state=touch mode=0700 #形式2: #在0.8版本之前,使用action关键字调用模块,示例如下(2.8.1向下兼容): --- - hosts: local remote_user: root tasks: - name: make file action: file path=/tmp/test.yml state=touch mode=0700
WeiyiGeek.2.8.1向下兼容
在前面示例中我们对每个任务都指定了对应的名称,即每个task都有对应的name,当我们省略name时,默认以当前任务调用的模块的名称作为任务的名称,不过建议不要省略name
,因为当任务存在name时可读性比较高。
#写法一:(推荐方式) tasks: - name: make testfile file: path=/testdir/testfile state=touch mode=0700 #写法二: tasks: - file: path=/testdir/testfile state=touch mode=0700 name: make testfile
各属性顺序虽然没有要求,但是仍然需要严格按照缩进进行对齐。
描述:先来描述一个工作场景当我们修改了某些程序的配置文件以后,有可能需要重启应用程序,以便能够使新的配置生效,那么如果使用playbook来实现这个简单的功能该怎样编写playbook呢?
假设我们想要将nginx中的某个server的端口从8080改成8088,并且在修改配置以后重启nginx,那么我们可以编写如下剧本。
--- - hosts: test70 remote_user: root tasks: - name: Modify the configuration lineinfile: path=/etc/nginx/conf.d/test.conf regexp="listen(.*) 8080 (.*)" line="listen\1 8088 \2" backrefs=yes backup=yes - name: restart nginx service: name=nginx state=restarted
WeiyiGeek.restarnginx
那么问题来了?
解决问题的方法:采用 handlers 方法
只有当tasks中的任务"真正执行"以后(真正的进行实际操作,造成了实际的改变)
,handlers中被调用的任务才会执行,如果tasks中的任务并没有做出任何实际的操作,那么handlers中的任务即使被’调用’,也并不会执行。handlers示例:
--- - hosts: test70 remote_user: root tasks: - name: Modify the configuration lineinfile: path=/etc/nginx/conf.d/test.conf regexp="listen(.*) 8080(.*)" line="listen\1 8088\2" backrefs=yes backup=yes notify: restart nginx #我们使用notify关键字'调用'handlers中的任务,或者说通过notify关键字'通知'handlers中的任务 # 们使用handlers关键字,指明哪些任务可以被'调用',与tasks是平级的状态 handlers: - name: restart nginx #任务的名称为"restart nginx" service: name=nginx state=restarted
所以综上所述上例中的play表示,如果"Modify the configuration"
真正的修改了配置文件(实际的操作),那么则执行"restart nginx"任务
,如果"Modify the configuration"
并没有进行任何实际的改动,则不执行"restart nginx"
通常来说,任务执行后如果做出了实际的操作,任务执行后的状态为changed则会执行对应的handlers,
handlers是另一种任务列表并且可以有多个任务,被tasks中不同的任务notify,
并不是执行完某个task后,立即执行对应的handler
示例如下:
--- - hosts: local remote_user: root tasks: - name: make testfile1 file: path=/tmp/testfile1 state=directory notify: ht2 #调用handlers中的ht2的任务 - name: make testfile2 file: path=/tmp/testfile2 state=directory notify: ht1 #调用handlers中的ht1的任务 - meta: flush_handlers #设置在执行完前面某些task以后立即执行调用对应的handler - name: task3 file: path=/tmp/testfile3 state=directory notify: ht3 handlers: - name: ht1 #设置handlers任务名称(当tasks任务执行时候才出否) file: path=/tmp/testfile1/ht1 state=touch - name: ht2 file: path=/tmp/testfile2/ht2 state=touch - name: ht3 file: path=/tmp/testfile3/ht3 state=touch #执行流程如下: PLAY [local] TASK [Gathering Facts] TASK [make testfile1] TASK [make testfile2] RUNNING HANDLER [ht1] RUNNING HANDLER [ht2] #由于这里采用meta模块会把上面tasks中notify调用完成后执行,下面的tasks任务 TASK [task3] RUNNING HANDLER [ht3] PLAY RECAP
WeiyiGeek.meta模块与handler
在一个task中一次性notify多个handler,当多个handler的name相同时只有一个handler会被执行
,所以我们并不能通过这种方式notify多个handler,
如果想要一次notify多个handler就需要设置组名来进行handlers多任务的调用,则需要借助另一个关键字它就是'listen'理解成"组名",我们可以把多个handler分成"组"
,当我们需要一次性notify多个handler时,只要将多个handler分为”一组”,使用相同的”组名”即可,当notify对应的值"组名"时,"组"内的所有handler都会被notify
一个notify调用多个handler中的任务:
--- - hosts: test70 remote_user: root tasks: - name: task1 file: path=/tmp/test state=directory notify: handler group1 #关键点 当task1中notify的值为handler group1时,handler1与handler2都会被notify #andler1与handler2的listen的值都是handler group1 handlers: - name: handler1 listen: handler group1 #关键点(监听组) file: path=/tmp/test/ht1 state=touch - name: handler2 listen: handler group1 file: path=/tmp/test/ht2 state=touch
监测与执行:
$ansible-playbook --syntax-check notify.yml playbook: notify.yml ansible-playbook notify.yml
WeiyiGeek.notify-nutil-handlers
handler总结:
描述: 在实际使用这个剧本时你可能只是想要执行其中的一部分任务而已,或者你只想要执行其中一类任务而已,而并非想要执行整个剧本中的全部任务
这个时候我们该怎么办呢?
答:可以借助tags实现这个需求,见名知义tags可以帮助我们对任务进行'打标签'的操作
,当任务存在标签以后,我们就可以在执行playbook时,借助标签指定执行哪些任务,或者指定不执行哪些任务了
;
示例:play中有3个task每个task都有对应的tags,我只是简单的把tags的值写成了t1、t2、t3当然您也可以定义成为其他;
--- - hosts: local remote_user: root tasks: - name: task1 file: path: /tmp/t1 state: touch tags: t1 #标签1 - 执行task1任务 - name: task2 file: path=/tmp/t2 state=touch tags: t2 #标签2 - 执行task2任务 - name: task3 file: path=/tmp/t3 state=touch tags: t3 #标签3 - 执行task3任务
下面利用ansible-playbook中--tags选项
以及--skip-tags选项
来执行指定的task任务以及跳过任务执行:
#示例0.在调用标签之前,如果你想要概览一下playbook中都有哪些标签 ansible-playbook --list-tags testhttpd.yml #示例1.只执行标签为t2的task2任务,只有标签对应的任务会被执行,其他任务都不会被执行, ansible-playbook --tags=t2 testtag.yml #示例2.选项指定"不执行的任务",比如下面的命令task1和task3会执行跳过了task2不会执行, ansible-playbook --skip-tags='t2' testtag.yml
除了使用上例中的语法指定标签,我们可以为每个任务添加多个标签三种语法添加多个标签的示例:
#语法一: tags: - testtag - t1 #语法二: tags: tag1,tag2 #语法三: tags: ['tagtest','t2']
将上面所学知识的进行综合演示,实现标签的常规用法,当拥有共同的标签时候将主tags标签提取出来与tasks同级,还可以在tasks里面建立子标签:
--- - hosts: local remote_user: root tags: command #关键点-形式0 tasks: - name: show ip address tags: ['ip'] #关键点-形式1 shell: ifconfig > /tmp/ipaddr.txt #值得注意(shell模块在play中的使用) - name: mkdir directory tags: - createdir #关键点-形式2 file: path: /tmp/createdir state: directory - hosts: testA remote_user: root tags: nginx tasks: - name: install nginx package tags: ['package'] yum: name=httpd state=latest - name: start up nginx server tags: - startservices service: name: nginx state: started
当tags写在play中而非task中时,play中的所有task会继承当前play中的tags,而上例中两个任务都会继承httpd标签,同时还有拥有自己的标签
。
#示例1.概览一下playbook的yml脚本中都有哪些标签 ansible-playbook --list-tags tag.yml playbook: tag.yml play #1 (local): local TAGS: [command] TASK TAGS: [command, createdir, ip] play #2 (testA): testA TAGS: [nginx] TASK TAGS: [nginx, package, startservices] #示例2.在调用标签时,也可以一次性指定多个标签来调用多个标签需要用逗号隔开 #play执行顺序默认是从下到下执行 ansible-playbook --tags package,startservices testhttpd.yml ansible-playbook --tags command,nginx tag.yml
WeiyiGeek.tags-demo
ansible特殊预置5个tag:
#标签示例 tags: t3,always,nginx #--------------------分割线-------------------- * always : 把任务的tags的值指定为always时任务就总是会被执行,除非你使用'--skip-tags'选项明确指定不执行对应的任务 ansible-playbook --skip-tags always testtag.yml #只有这样才能跳过执行,如果play中有多个任务都有always标签将都不会被执行; ansible-playbook --skip-tags t3 testtag.yml #另外一种情况;只跳过task3其他带有always标签的任务不会跳过,前提是task3有除了always以外的自定义标签比如这里的t3。 #--------------------分割线-------------------- * never(2.5版本中新加入的特殊tag): 从字面上理解never的作用应该与always正好相反 ansible-playbook --tags never testtag.yml #指定才会被执行 #--------------------分割线-------------------- #剩下的三个特殊标签并非像always一样always作为标签值存在,而这三个特殊标签则是在调用标签时使用 * tagged ansible-playbook --tags tagged testtag.yml #只执行有标签的任务,没有任何标签的任务不会被执行 ansible-playbook --skip-tags tagged testtag.yml #表示跳过包含标签的任务,即使对应的任务包含always标签,也会被跳过。 * untagged ansible-playbook --tags untagged testtag.yml #只执行没有标签的任务,但是如果某些任务包含always标签,那么这些任务也会被执行。 ansible-playbook --skip-tags untagged testtag.yml #表示跳过没有标签的任务。 * all: 表示所有任务会被执行,不用指定,默认情况下就是使用这个标签。
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句