# ansible的安装方式有多种,好比编译安装、git方式和pip安装等,这里使用yum方式安装,此种方式须要现有epel源 [root@ansible ~]#yum install epel-release -y [root@ansible ~]#yum install ansiblei -y
[root@ansible ~]#ansible --version ansible 2.9.1 config file = /etc/ansible/ansible.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, Aug 7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
[defaults] #inventory = /etc/ansible/hosts # 主机列表配置文件 #library = /usr/share/my_modules/ # 库文件存放目录 #remote_tmp = $HOME/.ansible/tmp #临时py命令文件存放在远程主机目录 #local_tmp = $HOME/.ansible/tmp # 本机的临时命令执行目录 #forks = 5 # 默认并发数 #sudo_user = root # 默认sudo 用户 #ask_sudo_pass = True #每次执行ansible命令是否询问ssh密码 #ask_pass = True #remote_port = 22 #host_key_checking = False # 检查对应服务器的host_key,建议取消注释 #log_path=/var/log/ansible.log #日志文件,建议启用 #module_name = command #默认模块,能够修改成shell模块
ntp.aliyun.com [webservers] www1.abc.com:2222 www2.abc.com [dbservers] db1.abc.com db2.abc.com [websrvs] www[1:100].example.com [dbsrvs] db-[a:f].example.com [appsrvs] 10.0.0.[1:100]
ansible-doc [options] [module...] -l, --list #列出可用模块 -s, --snippet #显示指定模块的playbook片断
#列出全部模块 ansible-doc -l #查看指定模块帮助用法 ansible-doc ping #查看指定模块帮助用法 ansible-doc -s ping
ansible <host-pattern> [-m module_name] [-a args]
--version #显示版本 -m module #指定模块,默认为command -v #详细过程 –vv -vvv更详细 --list-hosts #显示主机列表,可简写 --list -k, --ask-pass #提示输入ssh链接密码,默认Key验证 -C, --check #检查,并不执行 -T, --timeout=TIMEOUT #执行命令的超时时间,默认10s -u, --user=REMOTE_USER #执行远程执行的用户 -b, --become #代替旧版的sudo 切换 --become-user=USERNAME #指定sudo的runas用户,默认为root -K, --ask-become-pass #提示输入sudo时的口令
用于匹配被控制的主机的列表 All :表示全部Inventory中的全部主机
# all ansible all -m ping # *:通配符 ansible "*" -m ping ansible 192.168.1.* -m ping # 或关系 ansible "websrvs:appsrvs" -m ping ansible "192.168.1.1:192.168.1.2" -m ping # 逻辑与 #在websrvs组而且在dbsrvs组中的主机 ansible "websrvs:&dbsrvs" –m ping #逻辑非 #在websrvs组,但不在dbsrvs组中的主机 #注意:此处为单引号 ansible 'websrvs:!dbsrvs' –m ping #综合逻辑 ansible 'websrvs:dbsrvs:&appsrvs:!ftpsrvs' –m ping #正则表达式 ansible "websrvs:&dbsrvs" –m ping ansible "~(web|db).*\.abc\.com" –m ping
1.加载本身的配置文件 默认/etc/ansible/ansible.cfg 2.加载本身对应的模块文件,如:command 3.经过ansible将模块或命令生成对应的临时py文件,并将该文件传输至远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY文件 4.给文件+x执行 5.执行并返回结果 6. 删除临时py文件,退出
[root@ansible ~]#grep -A 14 '\[colors\]' /etc/ansible/ansible.cfg [colors] #highlight = white #verbose = blue #warn = bright purple #error = red #debug = dark gray #deprecate = purple #skip = cyan #unreachable = red #ok = green #changed = yellow #diff_add = green #diff_remove = red #diff_lines = cyan 绿色:执行成功而且不须要作改变的操做 黄色:执行成功而且对目标主机作变动 红色:执行失败
#以zhangsan用户执行ping存活检测 ansible all -m ping -u zhangsan -k #以zhangsan sudo至root执行ping存活检测 ansible all -m ping -u zhangsan -k -b #以zhangsan sudo至lisi用户执行ping存活检测 ansible all -m ping -u zhangsan -k -b --become-user=lisi #以zhangsan sudo至root用户执行ls ansible all -m command -u zhangsan -a 'ls /root' -b --become-user=root -k -K
#列出全部已安装的galaxy ansible-galaxy list #安装galaxy ansible-galaxy install geerlingguy.redis #删除galaxy ansible-galaxy remove geerlingguy.redis
ansible-playbook hello.yml cat hello.yml --- # hello world yml file - hosts: websrvs remote_user: root tasks: - name: hello world command: /usr/bin/wall hello world
ansible-vault [create|decrypt|edit|encrypt|rekey|view]
ansible-vault encrypt hello.yml #加密 ansible-vault decrypt hello.yml #解密 ansible-vault view hello.yml #查看 ansible-vault edit hello.yml #编辑加密文件 ansible-vault rekey hello.yml #修改口令 ansible-vault create new.yml #建立新文件
可交互执行命令,支持tab补全,ansible 2.0+新增
执行用户@当前操做的主机组 (当前组的主机数量)[f:并发数]$
设置并发数: forks n 例如: forks 10 切换组: cd 主机组 例如: cd web 列出当前组主机列表: list 列出全部的内置命令: ?或help
[root@ansible ansible]#ansible-console Welcome to the ansible console. Type help or ? to list commands. root@all (3)[f:5]$ list 192.168.7.71 192.168.7.72 192.168.7.73 root@all (3)[f:5]$ cd websrvs root@websrvs (3)[f:5]$ list 192.168.7.71 192.168.7.72 192.168.7.73 root@websrvs (3)[f:5]$ yum name=httpd state=present
[root@ansible ~]#ansible websrvs -m command -a 'echo 123.com | passwd --stdin zhangsan' [root@ansible ~]#ansible websrvs -a 'wall echo hello'
[root@ansible ~]#ansible websrvs -m shell -a 'echo 123.com | passwd --stdin zhangsan'
[root@ansible ~]#ansible websrvs -m script -a '/data/test.sh'
#如目标存在,默认覆盖,此处指定先备份 [root@ansible ~]#ansible websrvs -m copy -a "src=/data/test.sh dest=/tmp/test2.sh owner=zhangsan mode=600 backup=yes" #指定内容,直接生成目标文件 [root@ansible ~]#ansible websrvs -m copy -a "content='test content\n' dest=/tmp/test.txt" #复制/etc/下的文件,不包括/etc/目录自身 ansible srv -m copy -a "src=/etc/ dest=/backup" # 注:若是目标目录不存在会自动建立
[root@ansible ~]#ansible websrvs -m fetch -a 'src=/tmp/test.txt dest=/data'
# 建立空文件 [root@ansible ~]#ansible websrvs -m file -a 'path=/data/test.sh state=touch owner=hechunping mode=755' # 建立目录 [root@ansible ~]#ansible websrvs -m file -a 'path=/data/dir1 state=directory owner=hechunping group=hechunping' # 建立软链接 [root@ansible ~]#ansible websrvs -m file -a 'src=/data/test.sh dest=/data/test.sh-link state=link'
实现有两种用法: 1.将ansible主机上的压缩包传到远程主机后解压缩至特定目录,设置copy=yes 2.将远程主机上的某个压缩包解压缩到指定路径下,设置copy=no
# 将ansible服务器上的压缩文件解压缩到被控机上 [root@ansible ~]#ansible websrvs -m unarchive -a 'src=/data/test.sh.tar.gz dest=/usr/local' # 解压被控机上的压缩文件到它本地 [root@ansible ~]#ansible 192.168.7.72 -m unarchive -a 'src=/data/test.sh.tar.gz dest=/usr/local copy=no mode=0777' # 解压网络压缩文件到被控机 [root@ansible ~]#ansible websrvs -m unarchive -a 'src=https://nginx.org/download/nginx-1.14.2.tar.gz dest=/usr/local copy=no'
[root@ansible ~]#ansible websrvs -m archive -a 'path=/var/log/ dest=/data/log.tar.bz2 format=bz2 owner=hechunping mode=0600'
[root@ansible ~]#ansible 192.168.7.71 -m hostname -a 'name=web'
支持时间:minute,hour,day,month,weekday
# 建立任务,周一至周五天天2:30执行mysql_backup.sh脚本 ansible dbsrvs -m cron -a 'hour=2 minute=30 weekday=1-5 name="backup mysql" job=/root/mysql_backup.sh' # 禁用计划任务 ansible dbsrvs -m cron -a 'hour=2 minute=30 weekday=1-5 name="backup mysql" job=/root/mysql_backup.sh disabled=yes' # 启用计划任务 ansible dbsrvs -m cron -a 'hour=2 minute=30 weekday=1-5 name="backup mysql" job=/root/mysql_backup.sh disabled=no' # 删除任务 ansible dbsrvs -m cron -a "name='backup mysql' state=absent"
# 安装 [root@ansible ~]#ansible websrvs -m yum -a 'name=redis state=present' # 删除 [root@ansible ~]#ansible websrvs -m yum -a 'name=redis state=absent'
# 启动,并设置开机启动 [root@ansible ~]#ansible websrvs -m service -a 'name=redis state=started enabled=yes' # 中止 [root@ansible ~]#ansible websrvs -m service -a 'name=redis state=stopped' # 重启 [root@ansible ~]#ansible websrvs -m service -a 'name=redis state=restarted'
# 建立 [root@ansible ~]#ansible websrvs -m user -a 'name=user1 comment="test user" uid=2048 home=/app/user1 group=root' # 删除用户及其及目录等数据 [root@ansible ~]#ansible websrvs -m user -a 'name=user1 state=absent remove=yes'
# 建立 [root@ansible ~]#ansible websrvs -m group -a 'name=nginx gid=88 system=yes' # 删除 [root@ansible ~]#ansible websrvs -m group -a 'name=nginx state=absent'
ansible websrvs -m setup ansible websrvs -m setup -a "filter=ansible_nodename" ansible websrvs -m setup -a "filter=ansible_hostname" ansible websrvs -m setup -a "filter=ansible_domain" ansible websrvs -m setup -a "filter=ansible_memtotal_mb" ansible websrvs -m setup -a "filter=ansible_memory_mb" ansible websrvs -m setup -a "filter=ansible_memfree_mb" ansible websrvs -m setup -a "filter=ansible_os_family" ansible websrvs -m setup -a "filter=ansible_distribution_major_version" ansible websrvs -m setup -a "filter=ansible_distribution_version" ansible websrvs -m setup -a "filter=ansible_processor_vcpus" ansible websrvs -m setup -a "filter=ansible_all_ipv4_addresses" ansible websrvs -m setup -a "filter=ansible_architecture"
1.playbook 剧本是由一个或多个“play”组成的列表 2.play的主要功能在于将预约义的一组主机,装扮成事先经过ansible中的task定义好的角色。Task实际是调用ansible的一个module,将多个play组织在一个playbook中,便可以让它们联合起来,按事先编排的机制执行预约义的动做 3.Playbook文件是采用YAML语言编写的
one.example.com one.example.com:two.example.com 192.168.1.50 192.168.1.* Websrvs:dbsrvs #或者,两个组的并集 Websrvs:&dbsrvs #与,两个组的交集 websrvs:!dbsrvs #在websrvs组,但不在dbsrvs组
- hosts: websrvs:dbsrvs
- hosts: websrvs remote_user: root tasks: - name: test connection ping: remote_user: zhangsan sudo: yes #默认sudo为root sudo_user: lisi #sudo为lisi
1.play的主体部分是task list,task list中有一个或多个task,各个task按次序逐个在hosts中指定的全部主机上执行,即在全部主机上完成第一个task后,再开始第二个task 2.task的目的是使用指定的参数执行模块,而在模块参数中可使用变量。模块执行是幂等的,这意味着屡次执行是安全的,由于其结果均一致 3.每一个task都应该有其name,用于playbook的执行结果输出,建议其内容能清晰地描述任务执行步骤。若是未提供name,则action的结果将用于输出
1)action:module arguments 2)module:arguments (推荐使用)
--- - hosts: websrvs remote_user: root tasks: - name: install httpd yum: name=httpd - name: start httpd service: name=httpd state=started enabled=yes
某任务的状态在运行后为changed时,可经过"notify"通知给相应的handlers 任务能够经过"tags"打标签,可在ansible-playbook命令上使用-t指定进行调用
### 安装Apache ### #SHELL脚本实现 #!/bin/bash yum install --quiet -y httpd # 复制配置文件 cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf cp/tmp/vhosts.conf /etc/httpd/conf.d/ # 启动Apache,并设置开机启动 systemctl enable --now httpd #Playbook实现 --- - hosts: websrvs remote_user: root tasks: - name: "安装Apache" yum: name=httpd - name: "复制配置文件" copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/ - name: "复制配置文件" copy: src=/tmp/vhosts.conf dest=/etc/httpd/conf.d/ - name: "启动Apache,并设置开机启动" service: name=httpd state=started enabled=yes
ansible-playbook <filename.yml> ... [options]
--check -C #只检测可能会发生的改变,但不真正执行操做 --list-hosts #列出运行任务的主机 --list-tags #列出tag --list-tasks #列出task --limit 主机列表 #只针对主机列表中的主机执行 -v -vv -vvv #显示过程
ansible-playbook file.yml --check #只检测 ansible-playbook file.yml ansible-playbook file.yml --limit websrvs
#install_httpd.yml --- - hosts: websrvs remote_user: root tasks: - name: "安装httpd" yum: name=httpd state=present - name: "复制httpd.conf配置文件" copy: src=files/httpd.conf dest=/etc/httpd/conf - name: "启动httpd,并设置开机启动" service: name=httpd state=started enabled=yes
#remove_httpd.yml --- - 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
--- # 建立MySQL组和用户 - hosts: dbsrvs remote_user: root tasks: - {name: 建立组, group: name=mysql system=yes gid=306} - name: 建立用户 user: name=mysql shell=/sbin/nologin system=yes group=mysql uid=306 create_home=no
[root@ansible ~]#ll /data/ansible/files/mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz -rw-r--r-- 1 root root 403177622 Dec 4 13:05 /data/ansible/files/mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz [root@ansible ~]#cat /data/ansible/files/my.cnf [mysqld] socket=/tmp/mysql.sock user=mysql symbolic-links=0 datadir=/data/mysql innodb_file_per_table=1 log-bin [client] port=3306 socket=/tmp/mysql.sock [mysqld_safe] log-error=/var/log/mysqld.log [root@ansible ~]#cat /data/ansible/install_mysql.yml --- # install mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz - hosts: websrvs remote_user: root tasks: - name: "安装依赖包" yum: name=libaio,perl-Data-Dumper,perl-Getopt-Long - name: "建立mysql组" group: name=mysql gid=306 - name: "建立mysql用户" user: name=mysql uid=306 group=mysql shell=/sbin/nologin system=yes create_home=no home=/data/mysql - name: "将本地二进制安装包解压缩到目标主机的/usr/local目录下,并修改属主、属组为root" unarchive: src=/data/ansible/files/mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz dest=/usr/local owner=root group=root - name: "为解压缩的二进制包目录建立软链接" file: src=/usr/local/mysql-5.6.46-linux-glibc2.12-x86_64 dest=/usr/local/mysql state=link - name: "初始化数据库" shell: chdir=/usr/local/mysql ./scripts/mysql_install_db --datadir=/data/mysql --user=mysql tags: data - name: "复制本地my.cnf配置文件到被控主机" copy: src=/data/ansible/files/my.cnf dest=/etc/my.cnf - name: "复制本地的mysql服务脚本到被控主机的/etc/init.d目录下" shell: /bin/cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld - name: "启动mysql服务,而且设置开机启动" shell: /etc/init.d/mysqld start;chkconfig --add mysqld;chkconfig mysqld on tags: service - name: "将mysql的二进制可执行程序添加到PATH变量" copy: content='PATH=/usr/local/mysql/bin:$PATH' dest=/etc/profile.d/mysql.sh - name: "执行安全加固脚本" script: /data/ansible/files/secure_mysql.sh tags: script
Handlers本质是task list ,其中的task与前述的task并无本质上的不一样,用于当关注的资源发生变化时,才会采起必定的操做.Notify对应的action可用于在每一个play的最后被触发,这样可避免屡次有改变发生时每次都执行指定的操做,仅在全部的变化发生完成后一次性地执行指定操做。在notify中列出的操做称为handler,也即notify中调用handler中定义的操做
--- - hosts: websrvs remote_user: root tasks: - name: "安装httpd" yum: name=httpd state=present - name: "复制httpd.conf配置文件,而且重启httpd" copy: src=files/httpd.conf dest=/etc/httpd/conf notify: restart httpd - name: "启动httpd,并设置开机启动" service: name=httpd state=started enabled=yes handlers: - name: restart httpd service: name=httpd state=restarted
[root@ansible ansible]#cat install_httpd.yml --- - hosts: websrvs remote_user: root tasks: - name: "安装httpd" yum: name=httpd state=present - name: "复制httpd.conf配置文件,而且重启httpd" copy: src=files/httpd.conf dest=/etc/httpd/conf tags: conf - name: "启动httpd,并设置开机启动" service: name=httpd state=started enabled=yes tags: service [root@ansible ansible]#ansible-playbook -t conf,service install_httpd.yml
key=value
http_port=80
经过{{ variable_name }} 调用变量,且变量名先后建议加空格,有时用"{{ variable_name }}"才生效
ansible-playbook -e varname=value
vars: - var1: value1 - var2: value2
- hosts: all vars_files: - vars.yml
主机(普通)变量:主机组中主机单独定义,优先级高于公共变量 组(公共)变量:针对主机组中全部主机定义同一变量
[root@ansible ansible]#cat var.yml --- # var.yml - hosts: websrvs remote_user: root tasks: - name: "建立日志文件" file: name=/var/log/{{ ansible_fqdn }} state=touch [root@ansible ansible]#ansible-playbook var.yml
[root@ansible ansible]#cat var.yml --- # var.yml - hosts: websrvs remote_user: root tasks: - name: "安装包变量" yum: name={{ pkname }} state=absent [root@ansible ansible]#ansible-playbook -e pkname=httpd var.yml
[root@ansible ansible]#cat 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@ansible ansible]#ansible-playbook var.yml
能够在一个独立的playbook文件中定义变量,在另外一个playbook文件中引用变量文件中的变量,比playbook中定义的变量优化级高
[root@ansible ansible]#cat vars.yml --- # variables file var1: vsftpd var2: nginx [root@ansible ansible]#cat var2.yml --- - hosts: websrvs remote_user: root vars_files: vars.yml tasks: - name: "vsftpd日志文件" file: name=/data/{{ var1 }}.log state=touch - name: "nginx日志文件" file: name=/data/{{ var2 }}.log state=touch
在inventory主机清单文件中为指定的主机定义变量以便于在playbook中使用
[websrvs] www1.abc.com http_port=80 www2.abc.com http_port=8080
在inventory主机清单文件中赋予给指定组内全部主机在playbook中可用的变量
[websrvs] www1.abc.com www2.abc.com [websrvs:vars] ntp_server=ntp.aliyun.com
[root@ansible ansible]#vim /etc/ansible/hosts [websrvs] 192.168.7.71 hname=ansible 192.168.7.72 hname=web1 192.168.7.73 hname=web2 [websrvs:vars] http_port=808 mark="-" [root@ansible ansible]#ansible websrvs –m hostname –a 'name={{ hname }}{{ mark }}{{ http_port }}' # 命令行指定变量 [root@ansible ansible]#ansible websrvs -e http_port=8000 –m hostname –a 'name={{ hname }}{{ mark }}{{ http_port }}'
jinja2语言使用字面量,有下面形式: 字符串:使用单引号或双引号 数字:整数,浮点数 列表:[item1,item2,...] 元组:(item1,item2,...) 字典:{key1:value1,key2:value2,...} 布尔型:true/false 算术运算:+, -, *, /, //, %, ** 比较操做:==, !=, >, >=, <, <= 逻辑运算:and,or,not 流表达式:For,If,When jinja2相关说明: 字面量: 表达式最简单的形式就是字面量。字面量表示诸如字符串和数值的 Python 对象。如“Hello World” 双引号或单引号中间的一切都是字符串。不管什么时候你须要在模板中使用一个字符串(好比函数调用、过滤器或只是包含或继承一个模板的参数),如42,42.23 数值能够为整数和浮点数。若是有小数点,则为浮点数,不然为整数。在 Python 里, 42 和 42.0 是不同的 算术运算: Jinja 容许用计算值。支持下面的运算符 +:把两个对象加到一块儿。一般对象是素质,可是若是二者是字符串或列表,你能够用这 种方式来衔接它们。不管如何这不是首选的链接字符串的方式!链接字符串见 ~ 运算符。 {{ 1 + 1 }} 等于 2 -:用第一个数减去第二个数。 {{ 3 - 2 }} 等于 1 /:对两个数作除法。返回值会是一个浮点数。 {{ 1 / 2 }} 等于 {{ 0.5 }} //:对两个数作除法,返回整数商。 {{ 20 // 7 }} 等于 2 %:计算整数除法的余数。 {{ 11 % 7 }} 等于 4 *:用右边的数乘左边的操做数。 {{ 2 * 2 }} 会返回 4 。也能够用于重 复一个字符串屡次。 {{ ‘=’ * 80 }} 会打印 80 个等号的横条\ **:取左操做数的右操做数次幂。 {{ 2**3 }} 会返回 8 比较操做符 == 比较两个对象是否相等 != 比较两个对象是否不等 > 若是左边大于右边,返回 true >= 若是左边大于等于右边,返回 true < 若是左边小于右边,返回 true <= 若是左边小于等于右边,返回 true 逻辑运算符 对于 if 语句,在 for 过滤或 if 表达式中,它能够用于联合多个表达式 and 若是左操做数和右操做数同为真,返回 true or 若是左操做数和右操做数有一个为真,返回 true not 对一个表达式取反 (expr)表达式组 true / false true 永远是 true ,而 false 始终是 false
template功能:能够根据和参考模块文件,动态生成相相似的配置文件 template文件必须存放于templates目录下,且命名为 .j2 结尾 yaml/yml 文件需和templates目录平级,目录结构以下: ./ ├── temnginx.yml └── templates └── nginx.conf.j2
# 准备templates/nginx.conf.j2文件 [root@ansible ansible]#cat temnginx.yml --- - hosts: websrvs remote_user: root tasks: - name: "利用template模板文件配置被控主机" template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf [root@ansible ansible]#ansible-playbook temnginx.yml
#修改templates/nginx.conf.j2文件 [root@ansible ansible]#vim templates/nginx.conf.j2 worker_processes {{ ansible_processor_vcpus }}; [root@ansible ansible]#cat temnginx.yml --- - hosts: websrvs remote_user: root tasks: - name: "利用template模板文件配置被控主机" template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf [root@ansible ansible]#ansible-playbook temnginx.yml
[root@ansible ansible]#vim templates/nginx.conf.j2 worker_processes {{ ansible_processor_vcpus * 2}}; worker_processes {{ ansible_processor_vcpus + 2}};
[root@ansible ansible]#cat temnginx1.yml --- - hosts: websrvs remote_user: root vars: nginx_vhosts: - listen: 8081 server_name: www.hechunping.tech tasks: - name: "template模板文件配置被控主机" template: src=nginx.conf1.j2 dest=/data/nginx.conf [root@ansible ansible]#cat templates/nginx.conf1.j2 {% for vhost in nginx_vhosts %} server { listen {{ vhost.listen }}; server_name {{ vhost.server_name }}; } {% endfor %} # 生成结果 [root@ansible ansible]#ansible-playbook temnginx1.yml [root@ansible ansible]#cat /data/nginx.conf server { listen 8081; server_name www.hechunping.tech; }
[root@ansible ansible]#cat temnginx3.yml --- - hosts: websrvs remote_user: root vars: nginx_vhosts: - listen: 8081 server_name: "web1.hechunping.tech" root: "/var/www/nginx/web1" - listen: 8082 server_name: "web2.hechunping.tech" root: "/var/www/nginx/web2" - listen: 8083 server_name: "web3.hechunping.tech" root: "/var/www/nginx/web3" tasks: - name: "template模板文件配置被控主机" template: src=nginx.conf3.j2 dest=/data/nginx2.conf [root@ansible ansible]#cat templates/nginx.conf3.j2 {% for vhost in nginx_vhosts %} server { listen {{ vhost.listen }}; server_name {{ vhost.server_name }}; root {{ vhost.root }}; } {% endfor %} # 生成结果 [root@ansible ansible]#ansible-playbook temnginx3.yml [root@ansible ansible]#cat /data/nginx2.conf server { listen 8081; server_name web1.hechunping.tech; root /var/www/nginx/web1; } server { listen 8082; server_name web2.hechunping.tech; root /var/www/nginx/web2; } server { listen 8083; server_name web3.hechunping.tech; root /var/www/nginx/web3; }
[root@ansible ansible]#cat temnginx4.yml --- - hosts: websrvs remote_user: root vars: nginx_vhosts: - web1: listen: 8080 root: "/var/www/nginx/web1" - web2: listen: 8080 server_name: "web2.hechunping.tech" root: "/var/www/nginx/web2" tasks: - name: "template模板文件配置被控主机" template: src=nginx.conf2.j2 dest=/data/nginx3.conf [root@ansible ansible]#cat templates/nginx.conf2.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 %} #生成结果 [root@ansible ansible]#ansible-playbook temnginx4.yml [root@ansible ansible]#cat /data/nginx3.conf server{ listen 8080; root /var/www/nginx/web1 } server{ listen 8080; server_name web2.hechunping.tech; root /var/www/nginx/web2 }
[root@ansible ansible]#cat when.yml --- - hosts: websrvs remote_user: root tasks: - name: "打印hello redhat" command: /usr/bin/wall hello redhat when: ansible_os_family == "RedHat"
迭代:当有须要重复性执行的任务时,可使用迭代机制 对迭代项的引用,固定变量名为"item" 要在task中使用with_items给定要迭代的元素列表
--- - hosts: 192.168.7.71 remote_user: root tasks: - name: "备份文件" copy: src=/data/{{ item }} dest=/backup/{{ item }} with_items: - nginx.conf - nginx2.conf #上面语句的功能等同于下面的语句 - name: "备份/data/nginx.conf文件到/backup目录" copy: src=/data/nginx.conf dest=/backup - name: "备份/data/nginx2.conf文件到/backup目录" copy: src=/data/nginx2.conf dest=/backup
--- - hosts: websrvs remote_user: root tasks: - name: "建立组" group: name={{ item }} state=present with_items: - a1 - a2 - a3 - name: "建立用户" user: name={{ item.name }} group={{ item.group }} state=present with_items: - { name: 'a1',group: 'a1' } - { name: 'a2',group: 'a2' } - { name: 'a3',group: 'a3' }
角色是ansible自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles可以根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只须要在playbook中使用include指令便可。简单来说,roles就是经过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并能够便捷地include它们的一种机制。角色通常用于基于主机构建服务的场景中,但也能够是用于构建守护进程等场景中
roles ├── httpd ├── mysql ├── nginx └── redis
playbook.yml roles/ project/ tasks/ handlers/ files/ templates/ vars/ defaults/ meta/
/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文件
(1) 建立以roles命名的目录 (2) 在roles目录中分别建立以各角色名称命名的目录,如webservers等 (3) 在每一个角色命名的目录中分别建立files、handlers、meta、tasks、templates和vars目录;用不到的目录能够建立为空目录,也能够不建立 (4) 在playbook文件中,调用各角色
role_httpd.yml roles/ ├── httpd │ ├── files │ │ ├── httpd.conf │ │ └── index.html │ ├── handlers │ │ └── main.yml │ └── tasks │ ├── config.yml │ ├── index.yml │ ├── install.yml │ ├── main.yml │ └── service.yml
--- - hosts: websrvs remote_user: root roles: - mysql - memcached - nginx
--- - 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' ] } [root@ansible ansible]#ansible-playbook --tags="nginx,httpd,mysql" nginx-role.yml
[root@ansible ansible]#pwd /data/ansible [root@ansible ansible]#ls roles/httpd/ files handlers tasks # 建立角色 [root@ansible ansible]#cd roles/httpd/ [root@ansible httpd]#cat tasks/main.yml - include: install.yml - include: config.yml - include: index.yml - include: service.yml [root@ansible httpd]#cat tasks/install.yml - name : install httpd package yum: name: httpd [root@ansible httpd]#cat tasks/config.yml - name: config file copy: src: httpd.conf dest: /etc/httpd/conf backup: yes [root@ansible httpd]#cat tasks/index.yml - name: index.html copy: src: index.html dest: /var/www/html [root@ansible httpd]#cat tasks/service.yml - name: start service service: name: httpd state: started enabled: yes [root@ansible httpd]#cat handlers/main.yml - name: restart service: name: httpd state: restarted # 在files目录下准备两个文件 [root@ansible httpd]#ls files/ httpd.conf index.html [root@ansible httpd]#tree ./ ./ ├── files │ ├── httpd.conf │ └── index.html ├── handlers │ └── main.yml └── tasks ├── config.yml ├── index.yml ├── install.yml ├── main.yml └── service.yml 3 directories, 8 files # 在playbook中调用角色 [root@ansible httpd]#cat ../../role_httpd.yml --- # httpd role - hosts: appsrvs remote_user: root roles: - role: httpd # 运行playbook [root@ansible httpd]#ansible-playbook ../../role_httpd.yml
[root@ansible ~]#ls /data/ansible/roles/nginx/ files handlers tasks templates vars # 建立task文件 [root@ansible ~]#cd /data/ansible/roles/nginx/ [root@ansible nginx]#cat tasks/main.yml - include: install.yml - include: config.yml - include: file.yml - include: service.yml [root@ansible nginx]#cat tasks/install.yml - name: install yum: name=nginx [root@ansible nginx]#cat tasks/config.yml - name: config file for centos7 template: src: nginx7.conf.j2 dest: /etc/nginx/nginx.conf when: ansible_distribution_major_version=="7" notify: restart - name: config file for centos8 template: src: nginx8.conf.j2 dest: /etc/nginx/nginx.conf when: ansible_distribution_major_version=="8" notify: restart [root@ansible nginx]#cat tasks/file.yml - name: index.html copy: src: index.html dest: /usr/share/nginx/html [root@ansible nginx]#cat tasks/service.yml - name: start service service: name: nginx state: started enabled: yes # 建立handlers文件 [root@ansible nginx]#cat handlers/main.yml - name: restart service: name: nginx state: restarted # 建立两个template文件 [root@ansible nginx]#cat templates/nginx7.conf.j2 # For more information on configuration, see: # * Official English Documentation: http://nginx.org/en/docs/ # * Official Russian Documentation: http://nginx.org/ru/docs/ user {{user}}; #修改此行 worker_processes {{ansible_processor_vcpus**2}}; #修改此行 error_log /var/log/nginx/error.log; pid /run/nginx.pid; # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. include /usr/share/nginx/modules/*.conf; events { worker_connections 1024; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; # Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include # for more information. include /etc/nginx/conf.d/*.conf; server { listen 80 default_server; listen [::]:80 default_server; server_name _; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } } # Settings for a TLS enabled server. # # server { # listen 443 ssl http2 default_server; # listen [::]:443 ssl http2 default_server; # server_name _; # root /usr/share/nginx/html; # # ssl_certificate "/etc/pki/nginx/server.crt"; # ssl_certificate_key "/etc/pki/nginx/private/server.key"; # ssl_session_cache shared:SSL:1m; # ssl_session_timeout 10m; # ssl_ciphers HIGH:!aNULL:!MD5; # ssl_prefer_server_ciphers on; # # # Load configuration files for the default server block. # include /etc/nginx/default.d/*.conf; # # location / { # } # # error_page 404 /404.html; # location = /40x.html { # } # # error_page 500 502 503 504 /50x.html; # location = /50x.html { # } # } } [root@ansible nginx]#cat templates/nginx8.conf.j2 # For more information on configuration, see: # * Official English Documentation: http://nginx.org/en/docs/ # * Official Russian Documentation: http://nginx.org/ru/docs/ user nginx; worker_processes {{ansible_processor_vcpus+2}}; #修改此行 error_log /var/log/nginx/error.log; pid /run/nginx.pid; # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. include /usr/share/nginx/modules/*.conf; events { worker_connections 1024; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; # Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include # for more information. include /etc/nginx/conf.d/*.conf; server { listen 80 default_server; listen [::]:80 default_server; server_name _; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } } # Settings for a TLS enabled server. # # server { # listen 443 ssl http2 default_server; # listen [::]:443 ssl http2 default_server; # server_name _; # root /usr/share/nginx/html; # # ssl_certificate "/etc/pki/nginx/server.crt"; # ssl_certificate_key "/etc/pki/nginx/private/server.key"; # ssl_session_cache shared:SSL:1m; # ssl_session_timeout 10m; # ssl_ciphers HIGH:!aNULL:!MD5; # ssl_prefer_server_ciphers on; # # # Load configuration files for the default server block. # include /etc/nginx/default.d/*.conf; # # location / { # } # # error_page 404 /404.html; # location = /40x.html { # } # # error_page 500 502 503 504 /50x.html; # location = /50x.html { # } # } } # 建立变量文件 [root@ansible nginx]#cat vars/main.yml user: daemon # 在files目录下建立index.html文件 [root@ansible nginx]#cat files/index.html <h1>hello nginx </h1> # 目录结构以下 [root@ansible nginx]#tree ./ ./ ├── files │ └── index.html ├── handlers │ └── main.yml ├── tasks │ ├── config.yml │ ├── file.yml │ ├── install.yml │ ├── main.yml │ └── service.yml ├── templates │ ├── nginx7.conf.j2 │ └── nginx8.conf.j2 └── vars └── main.yml 5 directories, 10 files # 在playbook中调用角色 [root@ansible nginx]#cat ../../role_nginx.yml --- # nginx role - hosts: appsrvs roles: - role: nginx # 运行playbook [root@ansible nginx]#ansible-playbook /data/ansible/role_nginx.yml
[root@ansible nginx]#cat /data/ansible/role_httpd_nginx.yml --- - hosts: appsrvs roles: - { role: httpd,tags: [httpd,web], when: ansible_distribution_major_version=="7" } - { role: nginx,tags: [nginx,web], when: ansible_distribution_major_version=="8" } [root@ansible nginx]#ansible-playbook -t nginx /data/ansible/role_httpd_nginx.yml