Ansible 概述 Ansbile是一种IT自动化工具。它可以配置系统,部署软件以及协调更高级的IT任务,列如持续部署,滚动更新。
Ansible 适用于管理企业IT基础设施,从具有少数主机的小规模到数千个实例的企业环境。Ansible 也是一种简单的自动化语言,可以完美地描述IT应用程序基础结构。
具备以下三个特点:
简单:减少学习成本 强大:协调应用程序生命周期 无代理:可预测,可靠和安全
安装 Ansible:
[root@ops ~]# yum install epel-release [root@ops ~]# yum install ansible -y
Inventory:Ansible管理的主机信息,包括IP地址、SSH端口、账号、密码等 Modules:任务均有模块完成,也可以自定义模块,例如经常用的脚本。 Plugins:使用插件增加Ansible核心功能,自身提供了很多插件,也可以自定义插件。例如connection插件,用于连接目标主机。 Playbooks:“剧本”,模块化定义一系列任务,供外部统一调用。Ansible核心功能。 主机清单 [root@ops ~]# cat /etc/ansible/hosts [webservers] 192.168.1.101 192.168.1.102 192.168.1.103 命令行使用 连接远程主机认证 SSH密码认证:
[root@ops ~]# cat /etc/ansible/hosts [webservers] 192.168.1.101 ansible_ssh_user=root ansible_ssh_pass=’Admin@1234’ 192.168.1.102 ansible_ssh_user=root ansible_ssh_pass=’Admin@1234’ 192.168.1.103 ansible_ssh_user=root ansible_ssh_pass=’Admin@1234’ SSH密钥对认证:
[root@ops ~]# cat /etc/ansible/hosts [webservers] 192.168.1.101 ansible_ssh_user=root ansible_ssh_key=/root/.ssh/id_rsa 192.168.1.102 ansible_ssh_user=root ’ 192.168.1.103 ansible_ssh_user=root
也可以在配置文件中指定: [defaults] private_key_file = /root/.ssh/id_rsa # 默认路径 常用选项 选项 描述 -C, --check 运行检查,不执行任何操作 -e EXTRA_VARS,--extra-vars=EXTRA_VARS 设置附加变量 key=value -u REMOTE_USER, --user=REMOTE_USER SSH连接用户,默认None -k, --ask-pass SSH连接用户密码 -b, --become 提权,默认root -K, --ask-become-pass 提权密码 命令行使用
[root@ops ~]# ansible all -m ping 192.168.1.102 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } 192.168.1.103 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } 192.168.1.101 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" }
[root@ops ~]# ansible all -m shell -a "ls /root" -u root -k SSH password: 192.168.1.102 | CHANGED | rc=0 >> etcd-v3.4.13-linux-amd64 etcd-v3.4.13-linux-amd64.tar.gz 192.168.1.101 | CHANGED | rc=0 >> ca.cer cfssl-certinfo_linux-amd64 cfssljson_linux-amd64 cfssl_linux-amd64 components.yaml config.yaml istio-1.11.4 istio-1.11.4-linux-amd64.tar.gz transit.nolpay.ae.cer 192.168.1.103 | CHANGED | rc=0 >> 常用模块 ansible-doc –l 查看所有模块
ansible-doc –s copy 查看模块文档
shell 在目标主机执行shell命令
[root@ops ~]# ansible all -m shell -a "chdir='/var/log/' ls -l | grep log"
192.168.1.102 | CHANGED | rc=0 >>
-rw-------. 1 root root 0 Nov 4 03:17 boot.log
-rw-------. 1 root root 9219 Nov 4 03:17 boot.log-20211104
-rw-r--r--. 1 root root 292000 Nov 24 10:59 lastlog
-rw-------. 1 root root 0 Nov 21 03:16 maillog
-rw-------. 1 root root 198 Mar 31 2021 maillog-20211107
-rw-------. 1 root root 0 Nov 7 03:43 maillog-20211114
-rw-------. 1 root root 0 Nov 14 03:32 maillog-20211121
-rw-------. 1 root root 0 Mar 31 2021 tallylog
-rw-------. 1 root root 4480 Nov 4 14:21 yum.log
192.168.1.103 | CHANGED | rc=0 >>
-rw-------. 1 root root 0 Nov 5 03:45 boot.log
-rw-------. 1 root root 9305 Nov 4 03:14 boot.log-20211104
-rw------- 1 root root 8383 Nov 5 03:45 boot.log-20211105
-rw-r--r--. 1 root root 292000 Nov 24 10:59 lastlog
-rw------- 1 root root 0 Nov 21 03:40 maillog
-rw-------. 1 root root 424 Nov 4 14:27 maillog-20211107
-rw------- 1 root root 0 Nov 7 03:21 maillog-20211114
-rw------- 1 root root 0 Nov 14 03:49 maillog-20211121
-rw-------. 1 root root 0 Mar 31 2021 tallylog
-rw-------. 1 root root 4480 Nov 4 14:21 yum.log
192.168.1.101 | CHANGED | rc=0 >>
-rw-------. 1 root root 0 Nov 5 03:12 boot.log
-rw-------. 1 root root 9241 Nov 4 03:08 boot.log-20211104
-rw------- 1 root root 8294 Nov 5 03:12 boot.log-20211105
-rw-r--r--. 1 root root 292000 Nov 24 10:59 lastlog
-rw------- 1 root root 0 Nov 21 03:43 maillog
-rw-------. 1 root root 424 Nov 4 15:41 maillog-20211107
-rw------- 1 root root 0 Nov 7 03:31 maillog-20211114
-rw------- 1 root root 0 Nov 14 03:25 maillog-20211121
-rw-------. 1 root root 0 Mar 31 2021 tallylog
-rw-------. 1 root root 7792 Nov 4 14:43 yum.log
参数说明:
chdir参数 : 此参数的作用就是指定一个目录,在执行对应的命令之前,会先进入到 chdir 参数指定的目录中
**executable参数:**默认情况下,shell 模块会调用远程主机中的 /bin/sh 去执行对应的命令,通常情况下,远程主机中的默认 shell 都是 bash。如果你想要使用其他类型的 shell 执行命令,则可以使用此参数指定某种类型的 shell 去执行对应的命令。指定 shell 文件时,需要使用绝对路径
**removes参数 :**使用此参数指定一个文件,当指定的文件不存在时,就不执行对应命令
**creates参数 :**使用此参数指定一个文件,当指定的文件存在时,就不执行对应命令
**free_form参数 :**必须参数,指定需要远程执行的命令,但是并没有具体的一个参数名叫free_form,
copy 将文件复制到远程主机
[root@ops ~]# ansible all -m copy -a "src=ArmsAgent.tar.gz dest=/tmp/" 192.168.1.103 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "checksum": "0b0fed4f40a4bf83fe174309e17273cdeedb9c2e", "dest": "/tmp/ArmsAgent.tar.gz", "gid": 0, "group": "root", "md5sum": "08dcb6dbe63eeeb42628dfe9cc14e4e9", "mode": "0644", "owner": "root", "size": 46325347, "src": "/root/.ansible/tmp/ansible-tmp-1637724228.32-26808-199044113552898/source", "state": "file", "uid": 0 } 192.168.1.102 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "checksum": "0b0fed4f40a4bf83fe174309e17273cdeedb9c2e", "dest": "/tmp/ArmsAgent.tar.gz", "gid": 0, "group": "root", "md5sum": "08dcb6dbe63eeeb42628dfe9cc14e4e9", "mode": "0644", "owner": "root", "secontext": "unconfined_u:object_r:admin_home_t:s0", "size": 46325347, "src": "/root/.ansible/tmp/ansible-tmp-1637724228.61-26806-205389838720285/source", "state": "file", "uid": 0 } 192.168.1.101 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "checksum": "0b0fed4f40a4bf83fe174309e17273cdeedb9c2e", "dest": "/tmp/ArmsAgent.tar.gz", "gid": 0, "group": "root", "md5sum": "08dcb6dbe63eeeb42628dfe9cc14e4e9", "mode": "0644", "owner": "root", "size": 46325347, "src": "/root/.ansible/tmp/ansible-tmp-1637724228.5-26804-266077367101765/source", "state": "file", "uid": 0 }
[root@ops ~]# ansible all -m copy -a "src=ArmsAgent.tar.gz dest=/tmp/ owner=root group=root mode=777" 192.168.1.102 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "checksum": "0b0fed4f40a4bf83fe174309e17273cdeedb9c2e", "dest": "/tmp/ArmsAgent.tar.gz", "gid": 0, "group": "root", "mode": "0777", "owner": "root", "path": "/tmp/ArmsAgent.tar.gz", "secontext": "unconfined_u:object_r:admin_home_t:s0", "size": 46325347, "state": "file", "uid": 0 } 192.168.1.103 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "checksum": "0b0fed4f40a4bf83fe174309e17273cdeedb9c2e", "dest": "/tmp/ArmsAgent.tar.gz", "gid": 0, "group": "root", "mode": "0777", "owner": "root", "path": "/tmp/ArmsAgent.tar.gz", "size": 46325347, "state": "file", "uid": 0 } 192.168.1.101 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "checksum": "0b0fed4f40a4bf83fe174309e17273cdeedb9c2e", "dest": "/tmp/ArmsAgent.tar.gz", "gid": 0, "group": "root", "mode": "0777", "owner": "root", "path": "/tmp/ArmsAgent.tar.gz", "size": 46325347, "state": "file", "uid": 0 } 参数说明:
**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 管理文件和文件属性
创建文件
[root@ops ~]# ansible all -m file -a "path=/tmp/kubesre state=touch" 192.168.1.103 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dest": "/tmp/kubesre", "gid": 0, "group": "root", "mode": "0644", "owner": "root", "size": 0, "state": "file", "uid": 0 } 192.168.1.102 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dest": "/tmp/kubesre", "gid": 0, "group": "root", "mode": "0644", "owner": "root", "secontext": "unconfined_u:object_r:user_tmp_t:s0", "size": 0, "state": "file", "uid": 0 } 192.168.1.101 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dest": "/tmp/kubesre", "gid": 0, "group": "root", "mode": "0644", "owner": "root", "size": 0, "state": "file", "uid": 0 } [root@ops ~]# ansible all -m shell -a "ls -l /tmp/kubesre" 192.168.1.102 | CHANGED | rc=0 >> -rw-r--r--. 1 root root 0 Nov 24 11:37 /tmp/kubesre 192.168.1.103 | CHANGED | rc=0 >> -rw-r--r-- 1 root root 0 Nov 24 11:37 /tmp/kubesre 192.168.1.101 | CHANGED | rc=0 >> -rw-r--r-- 1 root root 0 Nov 24 11:37 /tmp/kubesre
创建目录
[root@ops ~]# ansible all -m file -a "path=/tmp/test state=directory" 192.168.1.103 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "gid": 0, "group": "root", "mode": "0755", "owner": "root", "path": "/tmp/test", "size": 6, "state": "directory", "uid": 0 } 192.168.1.102 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "gid": 0, "group": "root", "mode": "0755", "owner": "root", "path": "/tmp/test", "secontext": "unconfined_u:object_r:user_tmp_t:s0", "size": 6, "state": "directory", "uid": 0 } 192.168.1.101 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "gid": 0, "group": "root", "mode": "0755", "owner": "root", "path": "/tmp/test", "size": 6, "state": "directory", "uid": 0 }
[root@ops ~]# ansible all -m shell -a "ls -l /tmp"
192.168.1.102 | CHANGED | rc=0 >>
total 45240
drwx------. 2 root root 41 Nov 24 11:48 ansible_command_payload_ceyqUR
-rwxrwxrwx. 1 root root 46325347 Nov 24 11:23 ArmsAgent.tar.gz
-rw-r--r--. 1 root root 0 Nov 24 11:37 kubesre
drwxr-xr-x. 2 root root 6 Nov 24 11:48 test
192.168.1.103 | CHANGED | rc=0 >>
total 45240
drwx------ 2 root root 41 Nov 24 11:48 ansible_command_payload_IyoZG8
-rwxrwxrwx 1 root root 46325347 Nov 24 11:23 ArmsAgent.tar.gz
-rw-r--r-- 1 root root 0 Nov 24 11:37 kubesre
drwxr-xr-x 2 root root 6 Nov 24 11:48 test
192.168.1.101 | CHANGED | rc=0 >>
total 45240
drwx------ 2 root root 41 Nov 24 11:48 ansible_command_payload_guMhZe
-rwxrwxrwx 1 root root 46325347 Nov 24 11:23 ArmsAgent.tar.gz
-rw-r--r-- 1 root root 0 Nov 24 11:37 kubesre
drwxr-xr-x 2 root root 6 Nov 24 11:48 test
删除目录
[root@ops ~]# ansible all -m file -a "path=/tmp/test state=absent" 192.168.1.103 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "path": "/tmp/test", "state": "absent" } 192.168.1.102 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "path": "/tmp/test", "state": "absent" } 192.168.1.101 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "path": "/tmp/test", "state": "absent" }
修改属性
[root@ops ~]# ansible all -m file -a "path=/tmp/kubesre mode=777" 192.168.1.103 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "gid": 0, "group": "root", "mode": "0777", "owner": "root", "path": "/tmp/kubesre", "size": 0, "state": "file", "uid": 0 } 192.168.1.102 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "gid": 0, "group": "root", "mode": "0777", "owner": "root", "path": "/tmp/kubesre", "secontext": "unconfined_u:object_r:user_tmp_t:s0", "size": 0, "state": "file", "uid": 0 } 192.168.1.101 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "gid": 0, "group": "root", "mode": "0777", "owner": "root", "path": "/tmp/kubesre", "size": 0, "state": "file", "uid": 0 } 参数说明:
path:要操作的文件或目录
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,可以递归的修改目录中文件的属性。
**absent:**表示卸载
yum 软件包管理
安装Nginx
[root@ops ~]# ansible all -m yum -a "name=nginx.org/packages/rh… state=present"
卸载Nginx
[root@ops ~]# ansible all -m yum -a "name=nginx state=absent"
更新所有包
[root@ops ~]# ansible all -m yum -a "name='*' state=latest" service/systemd 管理服务
[root@ops ~]# ansible all -m systemd -a "name=nginx state=restarted enabled=yes" unarchive 解压到远程机器指定目录
[root@ops ~]# ansible all -m unarchive -a "src=ArmsAgent.tar.gz dest=/tmp" 192.168.1.103 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dest": "/tmp", "extract_results": { "cmd": [ "/usr/bin/gtar", "--extract", "-C", "/tmp", "-z", "-f", "/root/.ansible/tmp/ansible-tmp-1637734297.88-28601-94567791333261/source" ], "err": "", "out": "", "rc": 0 }, "gid": 0, "group": "root", "handler": "TgzArchive", "mode": "01777", "owner": "root", "size": 240, "src": "/root/.ansible/tmp/ansible-tmp-1637734297.88-28601-94567791333261/source", "state": "directory", "uid": 0 } 192.168.1.102 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dest": "/tmp", "extract_results": { "cmd": [ "/usr/bin/gtar", "--extract", "-C", "/tmp", "-z", "-f", "/root/.ansible/tmp/ansible-tmp-1637734298.15-28599-160150628668658/source" ], "err": "", "out": "", "rc": 0 }, "gid": 0, "group": "root", "handler": "TgzArchive", "mode": "01777", "owner": "root", "secontext": "system_u:object_r:tmp_t:s0", "size": 240, "src": "/root/.ansible/tmp/ansible-tmp-1637734298.15-28599-160150628668658/source", "state": "directory", "uid": 0 } 192.168.1.101 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dest": "/tmp", "extract_results": { "cmd": [ "/usr/bin/gtar", "--extract", "-C", "/tmp", "-z", "-f", "/root/.ansible/tmp/ansible-tmp-1637734298.01-28597-226262773743899/source" ], "err": "", "out": "", "rc": 0 }, "gid": 0, "group": "root", "handler": "TgzArchive", "mode": "01777", "owner": "root", "size": 240, "src": "/root/.ansible/tmp/ansible-tmp-1637734298.01-28597-226262773743899/source", "state": "directory", "uid": 0 } debug 执行过程中打印语句
-
debug: msg: System {{ inventory_hostname }} has uuid {{ ansible_product_uuid }}
-
name: 显示主机已知的所有变量 debug: var: hostvars[inventory_hostname] verbosity: 4 变量 变量是应用于多个主机的便捷方式,际在主机执行之前,变量会对每个主机添加,然后在执行中引用。
主机变量与组变量 [webservers] # 主机变量 192.168.1.101 hostname=web1 192.168.1.102 hostname=web2 192.168.1.103 hostname=web3
[webservers:vars] # 组变量 group=webservers Register变量
- shell: /usr/bin/uptime register: result
- debug: var: result verbosity: 2 Playbook Playbooks是Ansible的配置,部署和编排语言。他们可以描述您希望在远程机器做哪些事或者描述IT流程中一系列步骤。使用易读的YAML格式组织Playbook文件。
如果Ansible模块是您工作中的工具,那么Playbook就是您的使用说明书,而您的主机资产文件就是您的原材料。
与adhoc任务执行模式相比,Playbooks使用ansible是一种完全不同的方式,并且功能特别强大。
- hosts: webservers
vars:
http_port: 80
server_name: www.kubesre.com
remote_user: root
gather_facts: false
tasks:
- name: 安装nginx最新版 yum: pkg=nginx state=latest
- name: 写入nginx配置文件
template: src=/srv/httpd.j2 dest=/etc/nginx/nginx.conf
notify:
- restart nginx
- name: 确保nginx正在运行
service: name=httpd state=started
handlers:
- name: restart nginx service: name=nginx state=reloaded 主机和用户
- hosts: webservers remote_user: root become: yes become_user: nginx 解释说明:
become: 是否进行提权操作。如果需要,设置为yes become_user:设置为具有所需特权的用户-您想要成为的用户,而不是您登录时使用的用户 become_method : 权限工具,如sudo,su,pfexec,doas,pbrun,dzdo,ksu,runas,machinectl become_flags : play或task级别上,允许为任务或角色使用特定的标志。一种常见的用法是,当shell设置为no login时,将用户更改为nobody。此指令是在Ansible 2.2中添加。 定义变量 Ansible中的首选做法是不将变量存储在Inventory中。
除了将变量直接存储在Inventory文件之外,主机和组变量还可以存储在相对于Inventory文件的单个文件中。
- hosts: webservers vars: http_port: 80 server_name: www.kubesre.com 任务列表 每个play包含一系列任务。这些任务按照顺序执行,在play中,所有主机都会执行相同的任务指令。play目的是将选择的主机映射到任务。
tasks:
- name: 安装nginx最新版 yum: pkg=nginx state=latest 语法检查与调试 语法检查:ansible-playbook --check /path/to/playbook.yaml
测试运行,不实际操作:ansible-playbook -C /path/to/playbook.yaml
debug模块在执行期间打印语句,对于调试变量或表达式,而不必停止play。与'when:'指令一起调试更佳。
- hosts: webserver tasks:
- debug: msg: {{group_names}}
- debug: msg: {{inventory_hostname}}
- debug: msg: {{ansible_hostname}} 任务控制 如果你有一个大的剧本,那么能够在不运行整个剧本的情况下运行特定部分可能会很有用。
tasks:
- name: 安装nginx最新版 yum: pkg=nginx state=latest tags: install
- name: 写入nginx配置文件 template: src=/srv/httpd.j2 dest=/etc/nginx/nginx.conf tags: config 使用:
ansible-playbook example.yml --tags "install" ansible-playbook example.yml --tags "install,config" ansible-playbook example.yml --skip-tags "install" 流程控制 条件:
tasks:
- name: 只在192.168.1.100运行任务 debug: msg="{{ansible_default_ipv4.address}}" when: ansible_default_ipv4.address == '192.168.1.100' 循环:
tasks:
- name: 批量创建用户
user: name={{ item }} state=present groups=wheel
with_items:
- testuser1
- testuser2
- name: 解压
copy: src={{ item }} dest=/tmp
with_fileglob:
- "*.txt" 常用循环语句:
语句 描述 with_items 标准循环 with_fileglob 遍历目录文件 with_dict 遍历字典 模板 tasks:
- name: 写入nginx配置文件 template: src=/srv/httpd.j2 dest=/etc/nginx/nginx.conf 定义变量
{% set local_ip = inventory_hostname %} 条件和循环:
{% set list=['one', 'two', 'three'] %} {% for i in list %} {% if i == 'two' %} -> two {% elif loop.index == 3 %} -> 3 {% else %} {{i}} {% endif %} {% endfor %} 例如:生成连接etcd字符串
{% for host in groups['etcd'] %} https://{{ hostvars[host].inventory_hostname }}:2379 {% if not loop.last %},{% endif %} {% endfor %} 里面也可以用ansible的变量。
Roles Roles是基于已知文件结构自动加载某些变量文件,任务和处理程序的方法。按角色对内容进行分组,适合构建复杂的部署环境。
定义Roles Roles目录结构:
site.yml webservers.yml fooservers.yml roles/ common/ tasks/ handlers/ files/ templates/ vars/ defaults/ meta/ webservers/ tasks/ defaults/ meta/ tasks -包含角色要执行的任务的主要列表。 handlers -包含处理程序,此角色甚至在此角色之外的任何地方都可以使用这些处理程序。 defaults-角色的默认变量 vars-角色的其他变量 files -包含可以通过此角色部署的文件。 templates -包含可以通过此角色部署的模板。 meta-为此角色定义一些元数据。请参阅下面的更多细节。 通常的做法是从tasks/main.yml文件中包含特定于平台的任务:
roles/webservers/tasks/main.yml
- name: added in 2.4, previously you used 'include' import_tasks: redhat.yml when: ansible_facts['os_family']|lower == 'redhat'
- import_tasks: debian.yml when: ansible_facts['os_family']|lower == 'debian'
roles/webservers/tasks/redhat.yml
- yum: name: "httpd" state: present
roles/webservers/tasks/debian.yml
- apt: name: "apache2" state: present 使用角色
site.yml
- hosts: webservers
roles:
- common
- webservers
定义多个:
-
name: 0 gather_facts: false hosts: all roles:
- common
-
name: 1 gather_facts: false hosts: all roles:
- webservers 角色控制
-
name: 0.系统初始化 gather_facts: false hosts: all roles:
- common tags: common 定义变量 组变量: group_vars 存放的是组变量 group_vars/all.yml 表示所有主机有效,等同于[all:vars] grous_vars/etcd.yml 表示etcd组主机有效,等同于[etcd:vars]