ansible的浅谈

ansible

1ansibel的入门和安装

1.1安装

rpm包安装: EPEL源

  yum install ansible  -y

编译安装:

  yum -y install python-jinja2 PyYAML python-paramiko python-babel
    python-crypto
    tar xf ansible-1.5.4.tar.gz
    cd ansible-1.5.4
    python setup.py build
    python setup.py install
    mkdir /etc/ansible
    cp -r examples/* /etc/ansible

Git方式:

 git clone git://github.com/ansible/ansible.git --recursive
    cd ./ansible
    source ./hacking/env-setup

pip安装: pip是安装Python包的管理器,类似yum

yum install python-pip python-devel
yum install gcc glibc-devel zibl-devel rpm-bulid openssl-devel
pip install --upgrade pip
pip install ansible --upgrade

查看版本

ansible  --version
1.2相关配置文件

1.2.1配置文件

/etc/ansible/ansible.cfg #著配置文件
/etc/ansible/hosts #主机清单
/etc/ansible/roles #存放角色的目录

1.2.2主配置文件

[root@ansible ansible]# cat /etc/ansible/ansible.cfg
[defaults]
#inventory      = /etc/ansible/hosts   #主机列表配置文件
#library        = /usr/share/my_modules/  #库文件存放目录
#module_utils   = /usr/share/my_module_utils/  
#remote_tmp     = ~/.ansible/tmp   #临时py命令文件存放在远程主机目录
#local_tmp      = ~/.ansible/tmp   # 本机的临时命令执行目录
#plugin_filters_cfg = /etc/ansible/plugin_filters.yml
#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模块

1.2.3
主机清单格式

[root@ansible ansible]# vim /etc/ansible/hosts [appsrvs]
192.168.39.131
192.168.39.62
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
[websrvs]
192.168.39.[132:133]
192.168.39.134
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
[dbsrvs]
db-[a:f].example.com
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
[webservers]
www1.linux.com:2222 #可以指定端口
www[1:100].example.com
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
ntp.linux.com #不分组,直接加

1.3相关工具

/usr/bin/ansible 主程序,临时命令执行工具 /usr/bin/ansible-doc 查看配置文档,模块功能查看工具
/usr/bin/ansible-galaxy 下载/上传优秀代码或Roles模块的官网平台
/usr/bin/ansible-playbook 定制自动化任务,编排剧本工具 /usr/bin/ansible-pull
远程执行命令的工具 /usr/bin/ansible-vault 文件加密工具 /usr/bin/ansible-console
基于Console界面与用户交互的执行工具

利用ansible实现管理的主要方式:
Ad-Hoc 即利用ansible命令,主要用于临时命令使用场景
Ansible-playbook 主要用于长期规划好的,大型项目的场景,需要有前期的规划过程

1.3.1 ansible-doc

用来显示模块帮助
格式:
ansible-doc [options] [module…]
-l, --list #列出可用模块
-s, --snippet #显示指定模块的playbook片段
范例:
#列出所有模块
ansible-doc -l
#查看指定模块帮助用法
ansible-doc ping
#查看指定模块帮助用法
ansible-doc -s ping
#列出所有主机
ansible all --list

1.3.2ansible 基于key验证

ansible通过ssh协议,实现对远程主机的配置管理、应用部署、任务执行等功能
建议:使用此工具前,先配置ansible主控端能基于密钥认证的方式联系各个被管理节点
实现基于key验证 将公钥ssh-copy-id到被管理的主机上 , 实现免密登录
[root@7-1 ~]# ssh-keygen
[root@7-1 ~]# ssh-copy-id -i ~./ssh/id_rsa.pub root@192.168.39.132
[root@7-1 ~]# ssh-copy-id -i ~./ssh/id_rsa.pub root@192.168.39.133
[root@7-1 ~]# ssh-copy-id -i ~./ssh/id_rsa.pub root@192.168.39.131

利用sshpass批量实现基于key验证

ssh-keygen -f /root/.ssh/id_rsa -P ''
NET=192.168.100
export SSHPASS=magedu
for IP in {1..200};do
    sshpass -e ssh-copy-id $NET.$IP
done
1.3.3 格式和选项说明

格式:

ansible [-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时的口令

host-pattern
用于匹配被控制的主机的列表

All :表示所有Inventory中的所有主机
ansible all -m ping ansible websrvs -m ping
通配符
ansible "" -m ping #所有主机
ansible 192.168.39.
-m ping
ansible “websrvs” -m ping
或关系
ansible “websrvs:appsrvs” -m ping
ansible “192.168.39.10:192.168.39.20” -m ping
逻辑与
#在websrvs组并且在dbsrvs组中的主机
ansible “websrvs:&dbsrvs” –m ping
逻辑非
#在websrvs组,但不在dbsrvs组中的主机
#注意:此处为单引号
ansible ‘websrvs:!dbsrvs’ –m ping
正则表达式
ansible “websrvs:&dbsrvs” –m ping
ansible “~(web|db).*.magedu.com” –m ping

1.3.4ansible的执行过程

(1) 加载自己的配置文件 默认/etc/ansible/ansible.cfg
(2) 加载自己对应的模块文件,如command
(3) 通过ansible将模块或命令生成对应的临时py文件,并将该文件传输至远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY文件
(4) 给文件+x执行
(5) 执行并返回结果
(6) 删除临时py文件,退出

1.4常用模块
1.4.1command模块

在远程主机执行命令,默认模块,可忽略-m选项

chdir: 进入到被管理主机目录
creates: 如果有一个目录是存在的,步骤将不会运行Command命令

ansible websrvs -a 'chdir=/data/ ls'
ansible srvs -m command -a 'service httpd start'
ansible srvs -m command -a 'echo centos |passwd --stdin yu'
1.4.2Shell模块

与command相似,用shell执行命令
可修改shell为默认模块

vim /etc/ansible/ansible.cfg
module_name = shell #可修改默认模式为shell

ansible all -m shell  -a 'getenforce'  查看SELINUX状态  
ansible all -m shell  -a "sed -i 's/SELINUX=.*/SELINUX=disabled'    /etc/selinux/config"
ansible srv -m shell  -a 'echo magedu |passwd –stdin zhang'
1.4.3Script模块

在远程主机上运行ansible服务器上的脚本

ansible websrvs -m script -a /data/test.sh

1.4.4Copy模块

从主控端复制文件到远程主机
常见参数:
src : 源文件 指定拷贝文件的本地路径 (如果有/ 则拷贝目录内容,没有则拷贝目录本身)
dest: 指定目标路径
mode: 设置权限
backup: 备份源文件
content: 代替src 指定本机文件内容,生成目标主机文件

 ansible all -m copy -a "src=/data/f1.txt dest=/data/test1.txt owner=zhang mode=600 backup=yes"
 [root@ks7 ~]# ll /data
 -rw------- 1 zhang root 0 Nov 27 20:57 test1.txt
1.4.5fetch模块

从远程主机提取文件至主控端,与copy模块相反,目前不支持目录

ansible all -m fetch -a"src=/data/test1.sh dest=/data/t1.sh"

1.4.6file模块

设置文件属性

常见参数:
path: 要管理的文件路径 (强制添加)
recurse: 递归,文件夹要用递归
src: 创建硬链接,软链接时,指定源目标,配合’state=link’ ‘state=hard’ 设置软链接,硬链接
state: 状态
absent 缺席,删除

#创建文件        
ansible websrvs -m file -a 'path=/app/test.txt state=touch'  
#创建目录         
ansible websrvs -m file -a "path=/data/testdir state=directory"  
#设置权限755 
ansible websrvs -m file -a "path=/root/test.sh owner=wang mode=755"  
#创建软链接
ansible websrvs -m file -a 'src=/data/testfile dest=/data/testfile-link state=link'  
1.4.7unarchive模块

解包解压缩,有两种用法:
1、将ansible主机上的压缩包传到远程主机后解压缩至特定目录,设置copy=yes.
2、将远程主机上的某个压缩包解压缩到指定路径下,设置copy=no

常见参数:
copy:默认为yes,当copy=yes,拷贝的文件是从ansible主机复制到远程主机上,如果设置为copy=no,会在远程主机上寻找src源文件
src: 源路径,可以是ansible主机上的路径,也可以是远程主机上的路径,
如果是远程主机上的路径,则需要设置copy=no
dest:远程主机上的目标路径
mode:设置解压缩后的文件权限

ansible websrvs -m unarchive -a 'src=foo.tgz dest=/var/lib/foo'  
      #默认copy为yes ,将本机目录文件解压到目标主机对应目录下
ansible websrvs -m unarchive -a 'src=/tmp/foo.zip dest=/data copy=no mode=0777'
      # 解压被管理主机的foo.zip到data目录下, 并设置权限777
ansible websrvs -m unarchive -a 'src=https://example.com/example.zip dest=/data copy=no'
1.4.8Archive:打包压缩

将远程主机目录打包

常见参数:
path: 指定路径
dest: 指定目标文件
format: 指定打包格式
owner: 指定所属者
mode: 设置权限

 ansible all -m archive -a 'path=/etc/sysconfig dest=/data/sysconfig.tar.bz2 format=bz2 owner=wang mode=0777'
1.4.9Hostname:管理主机名
 ansible appsrvs -m hostname -a "name=net.yu.com"   
 #更改一组的主机名
 ansible 192.168.39.62 -m hostname -a "name=ks8-2"  
 #更改单个主机名

hostname app_81.magedu.com
hostname 不支持"",认为""是非法字符
hostnamectl set-hostname app_80.magedu.com 可以更改主机名

1.4.10Cron模块

计划任务
支持时间:minute,hour,day,month,weekday

> #备份数据库脚本
> [root@centos8 ~]#cat mysql_backup.sh mysqldump -uroot -pcentos -A -F  --single-transaction --master-data=2 -q |gzip > /data/mysql_backup`date +%F_%T`.sql.gzip
> #创建任务 
> ansible appsrvs -m cron -a 'hour=2 minute=30 weekday=1-5 name="mysqlbackup" job=/root/mysql_backup.sh' 
> ansible appsrvs -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.20.0.1 &> /dev/null' name=synctime"
> #禁用计划任务 
> ansible appsrvs -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.20.0.1 &>/dev/null' name=Synctime disabled=yes"
> #启用计划任务 
> ansible appsrvs -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.20.0.1 &>/dev/null' name=Synctime disabled=no"
> #删除任务 
> ansible appsrvs -m cron -a "name='mysql_backup' state=absent" ansibel appsrvs -m crom -a "name=synctime state=absent"
1.4.11 yum模块

软件包管理

ansible srv -m yum -a ‘name=httpd state=present’ #安装
ansible srv -m yum -a ‘name=httpd state=absent’ #删除

1.4.12 Service模块

服务管理

ansible all -m service -a 'name=httpd state=started enabled=yes'
ansible all -m service -a 'name=httpd state=stopped'
ansible all -m service -a 'name=httpd state=reload'
ansible all -m shell -a "sed -i 's/^Listen 80/^Listen 8080/' /etc/httpd/conf/httpd.conf"
ansibel all -m service -a 'name=httpd state=restarted'
1.4.13user模块

管理用户

#创建用户     
ansible srv -m user -a 'name=user1 comment=“test user” uid=2048 home=/app/user1 group=root‘ 
ansible srv -m user -a 'name=nginx comment=nginx uid=88 group=nginx groups="root,daemon" shell=/sbin/nologin system=yes create_home=no home=/data/nginx non_unique=yes'
#删除用户及家目录等数据  
ansible srv -m user -a 'name=nginx state=absent remove=yes'
1.4.14group模块

管理组

#创建组 ansible websrvs -m group -a 'name=nginx gid=88 system=yes'
#删除组 ansible websrvs -m group -a 'name=nginx state=absent'
1.4.15setup模块

返回系统信息
ansible 192.168.39.131 -m setup |less

ansible_all_ipv4_addresses        #IP地址 
ansible_architecture": "x86_64"   #架构 
ansible_distribution": "CentOS"   #操作系统版本          ansible_distribution_file_variety": "RedHat" #判断是否是红帽 ansible_distribution_major_version": "7"    #操作系统主版本号 ansible_domain": ""           #域名 
ansible_memfree_mb: 83   #内存的剩余
ansible_memtotal_mb": 1490,  #内存总大小
ansible_nodename":node18.magedu.com  #hostname
ansible_processor_vcpus:4  #虚拟cpu个数

#过滤,使用setup模块实现


```bash
[root@CENTOS8 files]# ansible 192.168.39.132 -m setup -a 'filter="ansible_distribution_file_variety"'
192.168.39.132 | SUCCESS => {
    "ansible_facts": {
        "ansible_distribution_file_variety": "RedHat",
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false
}
[root@CENTOS8 ansible]# ansible 192.168.39.131 -m setup  -a 'filter="ansible_fqdn"'
192.168.39.131 | SUCCESS => {
    "ansible_facts": {
        "ansible_fqdn": "ks7-1",
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false
}
1.5ansible命令
1.5.1可以通过网上写好的ansible-galaxy
> 连接 https://galaxy.ansible.com 
  下载相应的roles

> 列出所有已安装的galaxy
    ansible-galaxy list

> 安装galaxy
    ansible-galaxy install geerlingguy.redis

> 删除galaxy
    ansible-galaxy remove geerlingguy.redis
1.5.2ansible-playbook 可以引用按照标准的yml语言写的脚本
执行playbook
示例: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

2playbook

2.1yaml语言

YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构。其结构(Structure)通过空格来展示,
序列(Sequence)里的项用"-“来代表,Map里的键值对用”:"分隔,下面介绍常见的数据结构。

2.1.1 List列表

列表由多个元素组成,且所有元素前均使用“-”打头

A list of tasty fruits

  • Apple
  • Orange
  • Strawberry
  • Mango
2.1.2 Dictionary字典

字典通常由多个key与value构成

name: Example Developer
job: Developer
skill: Elite

#也可以将key:value放置于{}中进行表示,用,分隔多个key:value

{name: Example Developer, job: Developer, skill: Elite}

2.2playbook核心元素

Hosts # 执行的远程主机列表(应用到哪些主机上)
Tasks # 任务集
Variables # 内置变量或自定义变量在playbook中调用
Templates # 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
Handlers 和 notify #结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
tags #标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断 ansible-playbook -t tagsname useradd.yaml

2.2.1hosts组件

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

  • hosts: websrvs:appsrvs
2.2.2remote_user组件

remote_user: 可用于Host和task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,
其可用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户

- hosts: websrvs   remote_user: root   tasks:
    - name: test connection
      ping:
      remote_user: magedu
      sudo: yes      #默认sudo为root
      sudo_user:wang #sudo为wang
2.2.3task列表和action组件

play的主体部分是task list,task list中有一个或多个task,各个task 按次序逐个在hosts中指定的所有主机上执行。task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致。
(1) action: module arguments
(2) module: arguments 建议使用
注意:shell和command模块后面跟命令,而非key=value

---
- hosts: websrvs
  remote_user: root
  tasks:
    - name: install httpd
      yum: name=httpd
    - name: start httpd
      service: name=httpd state=started enabled=yes

使用ignore_errors来忽略错误信息

  tasks:
    - name: run this command and ignore the result
      shell: /usr/bin/somecommand
      ignore_errors: True  忽略错误	     
 
2.2.4ShellScripts VS Playbook
#SHELL脚本实现
#!/bin/bash
# 安装Apache
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
2.2.5handlers和notify结合使用触发条件

Handlers
是task列表,这些task与前述的task并没有本质上的不同,用于当关注的资源发生变化时,才会采取一定的操作。
Notify此action可用于在每个play的最后被触发,这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。
在notify中列出的操作称为handler,也即notify中调用handler中定义的操作

2.2.6 tags

tage: 添加标签
可以指定某一个任务添加一个标签,添加标签以后,想执行某个动作可以做出挑选来执行

vim httpd.yml
- hosts: websrvs
  remote_user: root
  tasks:
    - name: Install httpd
      yum: name=httpd state=present
      tage: install 
    - name: Install configure file
      copy: src=files/httpd.conf dest=/etc/httpd/conf/
      tags: conf
    - name: start httpd service
      tags: service
      service: name=httpd state=started enabled=yes
 ansible-playbook –t install,conf httpd.yml   #指定执行install,conf 两个标签
2.3playbook实例:安装httpd服务
vim install_httpd.yaml
---
#install httpd and config httpd
- hosts: websrvs
  remote_user: root
  tasks:
    - name: install httpd
      yum: name=httpd
    - name: modfiy config
      copy: src=/data/ansible/files/httpd.conf dest=/etc/httpd/conf/httpd.conf mode=644 owner=root group=root
      notify: restart httpd  #指定modfiy config 之后触发执行handlers
    - name: start service
      service: name=httpd state=started enabled=yes
  handlers:   #通过notify来触发执行
    - name:  restart httpd  #handlers的name名字必须同notify的名字相同
      service: name=httpd state=restarted
2.4playbook实例:卸载httpd服务
[root@CENTOS8 ansible]#vim remove_httpd.yaml
---
- hosts: websrvs
  remote_user: root
  tasks:
    - name: remove httpd package
      yum: name=httpd state=absent
    - name: remove apache user
      user: name=apache state=absent          #查看家目录路径  getent passwd apache   ll /usr/share/httpd/
    - name: remove data file
      file: path=/etc/httpd state=absent
2.5playbook中变量的使用

变量名:仅能由字母、数字和下划线组成,且只能以字母开头

变量来源:
1> ansible setup facts 远程主机的所有变量都可直接调用 (系统自带变量)
setup模块可以实现系统中很多系统信息的显示
可以返回每个主机的系统信息包括:版本、主机名、cpu、内存
ansible all -m setup -a ‘filter=“ansible_nodename”’ 查询主机名
ansible all -m setup -a ‘filter=“ansible_memtotal_mb”’ 查询主机内存大小
ansible all -m setup -a ‘filter=“ansible_distribution_major_version”’ 查询系统版本
ansible all -m setup -a ‘filter=“ansible_processor_vcpus”’ 查询主机cpu个数
2> 在/etc/ansible/hosts(主机清单)中定义变量
普通变量:主机组中主机单独定义,优先级高于公共变量(单个主机 )
公共(组)变量:针对主机组中所有主机定义统一变量(一组主机的同一类别)
3> 通过命令行指定变量,优先级最高
ansible-playbook –e varname=value
4> 在playbook中定义
vars:
- var1: value1
- var2: value2
5> 在独立的变量YAML文件中定义
6> 在role中定义

变量命名:
变量名仅能由字母、数字和下划线组成,且只能以字母开头
变量定义:key=value
示例:http_port=80
变量调用方式:

1>  通过{{ variable_name }} 调用变量,且变量名前后必须有空格,有时用“{{ variable_name }}”才生效
2>  ansible-playbook –e 选项指定
    ansible-playbook test.yml -e "hosts=www user=magedu"
2.5.1在主机清单中定义变量,在ansible中调用变量
[root@ansible ~]# vim /etc/ansible/hosts 
[appsrvs]
192.168.39.131 http_port=817 name=www
192.168.39.62 http_port=827 name=web
调用变量
ansible appsrvs -m hostname -a'name={{name}}'  #更改主机名为各自被定义的变量 

针对组设置变量

[root@ansible ~]#vim /etc/ansible/hosts
[appsrvs]
192.168.39.131 http_port=817 name=www
192.168.39.62 http_port=827 name=web
[appsrvs:vars]
mark="-"
[root@ansible ~]# ansible all -m hostname -a 'name={{name}}{{mark}}{{http_port}}'
[root@ansible ~]# ansible all -e http_port=8000 -m hostname -a 'name={{name}}{{mark}}{{http_port}}' #优先级8000
测试
[root@ks7-1 ~]# hostname
www-817
2.5.2将变量写进单独的配置文件中引用
[root@ansible ~]#vim vars.yml
pack: vsftpd
service: vsftpd

#引用变量文件
[root@ansible ~]#vim yuan.yaml
vars_files:
  - vars.yml 
2.5.3使用setup变量

查看setup变量

[root@ansible ~]#ansible 192.168.39.131 -m setup |less
[root@ansible ~]#var.yml
- hosts: websrvs
  remote_user: root
  tasks:
    - name: create log file
      file: name=/var/log/ {{ ansible_fqdn }} state=touch
[root@ansible ~]#ansible-playbook var.yml
2.5.4实例:yaml文件中直接引用变量
[root@ansible ~]#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-playbook var.yml
[root@ansible ~]#ansible-playbook -e "username=xiaoming groupname=xiaoming” var.yml

2.5.5实例:使用变量文件

[root@ansible ~]#cat vars.yml
var1log: httpd
var2log: nginx
[root@ansible ~]#cat var.yml
---
- hosts: all
  remote_user: root
  vars_files:
    - vars.yml
  tasks:
    - name: create httpd log
      file: name=/data/ansible/{{varlog}}.log state=touch
	- name: create nginx log
	  file: name=/data/ansible/{{var2log}}.log state=touch
2.6模板template
文本文件,嵌套有脚本(使用模板编程语言编写) 借助模板生成真正的文件

Jinja2语言,使用字面量,有下面形式

字符串:使用单引号或双引号
数字:整数,浮点数
列表:[item1, item2, …]
元组:(item1, item2, …)
字典:{key1:value1, key2:value2, …}
布尔型:true/false
算术运算:+, -, *, /, //, %, **
比较操作:==, !=, >, >=, <, <=
逻辑运算:and,or,not
流表达式:For,If,When

Jinja2:

#算术运算 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

2.6.1利用template同步nginx的配置文件
首先准备好/data/ansible/templates/nginx.conf.j2文件
[root@ansible ansible]#vim /data/ansible/template.yml
---
- hosts: all
  remote_user: root
  tasks:
    - name: templates config 
	  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
[root@ansible ansible]#ansible-playbook template.yml

#修改替换变量
[root@ansible ansible]#vim  /data/ansible/templates/nginx.conf.j2	  
worker_processes {{ ansible_processor_vcpu*2 }}
2.6.2when 实现条件判断

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

tasks:
  - name: "shutdown rehat flavored systems"
    command: /sbin/shutdown -h now
	when: ansible_os_family == "RedHat" 
	#当系统属于红帽系列,执行command模块
playbook中的when的条件判断
---
- hosts: websrvc
  remote_user: root
  tasks: 
    - name: install conf file to 7
	  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
	  when: ansible_distribution_major_version == "7"
	- name: install conf file to 6
	  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
	  when: ansible_distribution_major_version == "6"
2.6.3迭代: with_items

迭代: 当有需要重复执行的任务时,可以使用迭代机制

对迭代的应用,固定变量名为“item”
要在task中使用with_items给定要迭代的元素列表
列表格式
字符串
字典

实列1:

- name: create serveral users
  user: name={{ item }} state=present group=wheel  #{{item}}系统自定义变量   
  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

实例2:

- name: add serveral users
  user: name={{ item.name }} state=present groups={{ item.groups }}
  with_items:
    - { name: 'testuser1', groups: 'wheel' }
	- { name: 'testuser2', groups: 'root' }
2.6.4迭代
[root@ansible ansible]# vim copy.yml	
---
- hosts: all
  remote_user: root
  tasks:
    - name: copy file
      copy: src={{ item }} dest=/tmp/{{ item }}.bak
      with_items:
        - file1
        - file2
        - file3
    - name: install apache
      yum: name={{ item }} state=present
      with_items:
        - apr
        - apr-util
        - httpd
2.6.5迭代嵌套子变量
[root@ansible ansible]# vim items_user.yml
---
- hosts: all
  remote_user: root
  tasks:
    - name: add serveral groups
      group: name={{ item }} state=present
      with_items:
        - group1
        - group2
        - group3
    - name: add some users
      user: name={{ item.name }} group={{ item.group }} state=present
      with_items:
        - { name: 'user11', group: 'group1' }
        - { name: 'user12', group: 'group2' }
        - { name: 'user13', group: 'group3' }
2.6.6实例: playbook with_items管理端口
[root@ansible ansible]# vim items_port.yml
---
- hosts: all
  remote_user: root
  tasks:
    - name: Use UFW module management port to open
      ufw:
      rule: "{{ item.rule }}"
      port: "{{ item.port }}"
      proto: "{{ item.proto }}"
      with_items:
        - { rule: 'allow', port: 22, proto: 'tcp' }
        - { rule: 'allow', port: 80, proto: 'tcp' }
        - { rule: 'allow', port: 123, proto: 'udp'}
    - name: Configure default rules for network in and out
      ufw:
      direction: "{{ item.direction }}"
      polocy: "{{ item.policy }}"
      state: enabled
      with_items:
        - { direction: outgoing, policy: allow }
        - { direction: incoming, policy: deny }   
2.6.7 template中使用流程控制 fro 和 if
#temnginx1.yml
---
- hosts: websrvs
  remote_user: root
  vars:
    nginx_vhosts:
      - listen: 8080
  tasks:
    - name: config file
      template: src=nginx2.conf.j2 dest=/data/nginx2.conf
#templates/nginx.conf1.j2
{% for vhost in nginx_vhosts %}
server {
  listen {{ vhost.listen }}
}
{% endfor %}
#生成的结果
server {
listen 8080
}

3roles角色

roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。
角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中

3.1roles目录结构

每个角色,以特定的层级目录结构进行组织

roles目录结构: playbook.yml 调用角色 roles/ project/ (角色名称)
tasks/
files/
vars/
templates/
handlers/
default/ #不常用
meta/ #不常用

3.1.1roles个目录的作用
/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文件
roles/example_role/files/             
#所有文件,都将可存放在这里
roles/example_role/templates/         
#所有模板都存放在这里
roles/example_role/tasks/main.yml   
#主函数,包括在其中的所有任务将被执行
roles/example_role/handlers/main.yml
#所有包括其中的 handlers 将被执行
roles/example_role/vars/main.yml    
#所有包括在其中的变量将在roles中生效
roles/example_role/meta/main.yml    
#roles所有依赖将被正常登入
3.2创建httpd角色

1.创建roles目录

[root@ansible data]# mkdir -pv /data/ansible/roles/{httpd,mysql,redis}/{files,handlers,tasks,templates}
#查看创建目录结构
[root@ansible data]# tree
[root@ansible ansible]# tree
.
├── role_httpd.yml
└── roles
    ├── httpd
    │   ├── files
    │   │   ├── httpd.conf
    │   │   └── index.html
    │   ├── handlers
    │   │   └── main.yml
    │   ├── tasks
    │   │   ├── config.yml
    │   │   ├── index.yml
    │   │   ├── install.yml
    │   │   ├── main.yml
    │   │   └── service.yml
    │   └── templates

2.创建角色

[root@ansible ~]# cd /data/ansible/roles/httpd/tasks/

#创建主控文件,调用单独的yml文件,定义了执行的先后顺序
[root@ansible tasks]# vim main.yml  
- include: install.yml
- include: config.yml
- include: index.yml
- include: service.yml 

#创建安装的yaml文件
[root@ansible tasks]# cat install.yml 
- name: install httpd
  yum: name=httpd 

#创建配置文件的yaml文件
[root@ansible tasks]# cat config.yml 
- name: config file
  copy: src=httpd.conf dest=/etc/httpd/conf/ backup=yes
  notify: restart
 
#创建网页的yaml文件
[root@ansible tasks]# cat index.yml 
- name: index.html
  copy: src=index.html dest=/var/www/html 

#创建启动的yaml文件
[root@ansible tasks]# cat service.yml 
- name: start service
  service: name=httpd state=started enabled=yes 

2在handlers目录下创建handler文件mian.yml 对应config文件的notify

[root@ansible ~]# cd /data/ansible/roles/httpd/handlers/
[root@ansible handlers]# cat main.yml 
- name: restart
  service: name=httpd state=restarted

3准备httpd.conf文件,放到httpd的文件目录下

[root@ansible ~]# cp /etc/httpd/conf/httpd.conf  /data/ansible/roles/httpd/files/

4创建一个网页

[root@ansible ~]# cd /var/www/html/index.html /data/ansible/roles/httpd/files/
[root@ansible ~]# vim  /data/ansible/roles/httpd/files/index.html
<h1>hello linux!<\h1>

5创建文件调用httpd角色

[root@ansible ~]# cd /data/ansible/
[root@ansible ansible]# cat role_httpd.yml 
---
- hosts: all
  remote_user: root
  
  roles:
    - role: httpd

6运行playbook

[root@ansible ansible]# ansible-playbook role_httpd.yml
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值