设为首页 收藏本站
查看: 1061|回复: 0

[经验分享] ansible基础三

[复制链接]

尚未签到

发表于 2018-7-29 07:11:40 | 显示全部楼层 |阅读模式
setup模块常用自带变量:  
匹配完整主机名变量
  
ansible_hostname  <主机名变量>
  
ansible_distribution_major_version <版本号变量>
  
ansible_all_ipv4_addresses <IP地址变量>
  

  
变量名:仅能由字母、数字和下划线组成,且只能以字母开头
  
变量来源:
  1 ansible setup facts 远程主机的所有变量都可直接调用
  2 在/etc/ansible/hosts中定义
  普通变量:主机组中主机单独定义,优先级高于公共变量
  公共(组)变量:针对主机组中所有主机定义统一变量
  3 通过命令行指定变量,优先级最高
  ansible-playbook –e varname=value
  4 在playbook中定义
  vars:
  - var1: value1
  - var2: value2
  5 在role中定义
  

  
变量命名:
  变量名仅能由字母、数字和下划线组成,且只能以字母开头
  变量定义:key=value
  示例:http_port=80
  变量调用方式:
  1)通过{{ variable_name }} 调用变量,且变量名前后必须有 空格,有时用“{{ variable_name }}”才生效
  2)ansible-playbook –e 选项指定
  示例:
  ansible-playbook test.yml -e "hosts=www user=mageedu"
  

  在palybook里面使用变量能让playboot更加灵活
  (一):在playbook里定义变量
  看下面的例子:
  

---  
- hosts: web
  remote_user: root
  

  tasks:
  - name: remove package
  yum: name={{ pkname }} state=absent
  - name: initall package
  yum: name={{ pkname }}
  - name: start service
  service: name={{ pkname }} state=started
  
[root@ansiblehost ansible.yaml]#ansible-playbook -e "pkname=httpd " install.ym
  

  上面这个playbook分为三步,
  第一步:卸包,
  第二步:装包,
  第三步:重启服务
  &quot;但是注意到没有,而这三步我用的是一个变量,也就是我只要在命令行定义一个变量就可以完成这三个动作&quot;
  但是这个还是需要自己手工制定变量,
  (二):将变量名与变量名内容直接定义到playboot里
  看下面的例子:
  

    ---  - hosts: web
  remote_user: root
  "#vars是专门用于在playboot定义变量的关键词"
  vars:
  "#username,gropname就是变量名冒号":"后面的就是变量内容"
  - username: user1
  - groupname: root
  

  tasks:
  #任务一创建组
  - name: create group
  group: name={{ groupname }}
  "#创建用户并把该用户加入上面创建的组里面,再创键家目录到/app下"
  - name: create user
  user: name={{ username }} group={{   groupname }} home=/app/{{ username }}
  
执行playbook的方法:"而这时候调用playboot就不需要用-e指定变量内容了"
  

  [root@ansiblehost 16:15:27  ansible.yaml]#"ansible-playbook useradd.yml"
  PLAY [web] *************************************************************************************************************************************
  

  TASK [Gathering Facts] *************************************************************************************************************************
  ok: [192.168.136.5]
  ok: [192.168.136.6]
  

  TASK [create group] ****************************************************************************************************************************
  ok: [192.168.136.6]
  ok: [192.168.136.5]
  

  TASK [create user] *****************************************************************************************************************************
  ok: [192.168.136.6]
  changed: [192.168.136.5]
  

  PLAY RECAP *************************************************************************************************************************************
  192.168.136.5              : ok=3    changed=1    unreachable=0    failed=0
  192.168.136.6              : ok=3    changed=0    unreachable=0    failed=0
  

  (三):使用setup中自带的变量
  看下面的例子:
  

---  
- hosts: web
  remote_user: root
  

  tasks:
  - name: create file
  file: name=/app/{{ ansible_hostname }}.txt state=touch
  [root@ansiblehost 16:27:44  ansible.yaml]#ansible web -a 'ls -l /app/'
  192.168.136.5 | SUCCESS | rc=0 >>
  total 0
  -rw-r--r-- 1 root  root  0 Jan 18 16:26 "localhost.txt" #利用变量创建的变量
  drwxr-xr-x 2 user1 root 62 Jan 18 07:05 user1
  

  192.168.136.6 | SUCCESS | rc=0 >>
  total 4
  -rw-r--r-- 1 root  root    0 Jan 14 09:40 "centos6-102.txt" #利用变量创建出的文件
  -rw-r--r-- 1 root  root    0 Jan 14 01:49 testsrv
  drwx------ 4 user1 root 4096 Jan 14 09:15 user1
  

  playbook中使用的变量ansible_hostname就是setpu模块中过滤出来的变量,这种方法让我们可以不用定义变量,直接所使用setup模块里自带的变量。
  (四):/etc/ansible/hosts主机清单配置文件中定义变量
  1)定义普通变量;普通变量就是对每一个主机单独定义一个变量只能这个主机使用
  请看下面的例子:
  

[web]  
192.168.136.6 hostname="httpd"
  
这个可以在命令行调用
  
#这个例子就是利用在主机清单中定义的变量修改主机名
  
[root@ansiblehost 17:06:29  ansible.yaml]#ansible 192.168.136.6 -m hostname  -a 'name={{ hostname }}'
  
192.168.136.6 | SUCCESS => {
  "ansible_facts": {
  "ansible_domain": "magedu.com",
  "ansible_fqdn": "centos6-102.magedu.com",
  "ansible_hostname": "httpd",
  "ansible_nodename": "httpd"
  
},
  
"changed": true,
  
"name": "httpd"
  

  }
  2)在/etc/ansible/hosts文件中定义公共变量;公共变量就是一个主机组定义一个共有的变量
  看下面的例子:
  

[web]  
192.168.136.6
  
192.168.136.5
  

  
"#中括号里的【web】表示上面的web组,重点是冒号后面的vars加上这个关键次就表示对上面的web组创建共有变量。变量可以有多个"
  
[web:vars]
  
hostname=websrvs
  
port=80
  

  利用变量更改主机名:
  

[root@ansiblehost 17:24:39  ansible.yaml]#ansible web -m hostname -C -a 'name="{{ hostname }}-{{ port }}"'  
192.168.136.6 | SUCCESS => {
  "ansible_facts": {
  "ansible_domain": "",
  "ansible_fqdn": "httpd",
  "ansible_hostname": "websrvs-80",
  "ansible_nodename": "websrvs-80"
  },
  "changed": true,
  "name": "websrvs-80"
  
}
  
192.168.136.5 | SUCCESS => {
  "ansible_facts": {
  "ansible_domain": "localdomain",
  "ansible_fqdn": "localhost.localdomain",
  "ansible_hostname": "websrvs-80",
  "ansible_nodename": "websrvs-80"
  },
  "changed": true,
  "name": "websrvs-80"
  
}
  

  4)在playbook里面调用在/etc/ansible/hosts文件中定义的变量
  

看下面的例子:  

  [web]
  192.168.136.6
  192.168.136.5
  

  [web:vars]
  host=websrvs
  port=8080
  

  ---
  - hosts: web
  remote_user: root
  

  tasks:
  - name: set hostname
  hostname: name={{ host }}-{{ port }}
  

  5),在一个单独的文件存放playbok变量与值
  创建一个文件:
  

   touch var.txt  vim var.txt
  文件格式:
  var1: xiaoming
  var2: xiaohang
  

  6)在playbook调用文件var.txt里的变量
  

    #变量文件内容  var1: xiaoming
  var2: httpd
  

  playboot内容
  ---
  - hosts: web
  remote_user: root
  vars_files:
  - var.yml
  

  tasks:
  - name: create user
  user: name={{ var1 }} shell=/bin/bash home=/app/{{ var1 }}
  - name: create file
  file: name=/app/{{ var2 }}.txt  state=touch mode=644 owner=wang
  

  #最后命令执行结果
  1)创建用户结果
  [root@ansiblehost 19:10:36  ansible.yaml]#ansible web -a 'tail -n1 /etc/passwd'
  192.168.136.6 | SUCCESS | rc=0 >>
  xiaoming2:x:503:503::/app/xiaoming:/bin/bash
  

  192.168.136.5 | SUCCESS | rc=0 >>
  xiaoming2:x:1002:1002::/app/xiaoming:/bin/bash
  

  2)创建文件的结果
  [root@ansiblehost 18:45:55  ansible.yaml]#ansible web -a 'ls -l /app'
  192.168.136.5 | SUCCESS | rc=0 >>
  total 0
  -rw------- 1 root     root      0 Jan 18 18:45 httpd.txt
  drwxr-xr-x 2 xiaoming xiaoming 62 Jan 18 07:05 xiaoming
  

  192.168.136.6 | SUCCESS | rc=0 >>
  total 4
  -rw------- 1 root     root        0 Jan 14 11:59 httpd.txt
  drwxr-xr-x 4 xiaoming xiaoming 4096 Dec 17 17:40 xiaoming
  

template模板模块
  

1)文本文件,嵌套有脚本(使用模板编程语言编写)  2)Jinja2语言,使用字面量,有下面形式  ①:字符串:使用单引号或双引号
  ②:数字:整数,浮点数
  ③:列表:[item1, item2, ...]
  ④:元组:(item1, item2, ...)
  ⑤:字典:{key1:value1, key2:value2, ...} ⑥:布尔型:true/false 
  
3)算术运算:+, -, *, /, //<整除>, %, **<次方>
  
4)比较操作:==, !=, >, >=, <, <=
  
5)逻辑运算:and, or, not
  
6)流表达式:For If  When
  

  功能:
  templates功能:根据模块文件动态生成对应的配置文件
  templates文件必须存放于templates目录下,且命名为 .j2 结尾
  

yaml/yml 文件需和templates目录平级,目录结构如下:  

  
./
  
├── temnginx.yml #调用temnginx模块的文件必须跟真正存放模板的文件属于平级关系
  
└── templates
  └── nginx.conf.j2 #模板文件
  

  使用templates模块功能需要创建一个目录名为templates,然后在这个目录下存放模板文件,而文件名推荐改下后缀<.j2>

示例:利用templates同步nginx配置文件
  

1)准备templates/nginx.conf.j2文件  

  
2)编辑playbook文件
  
vim temnginx.yml
  ---
  - hosts: web
  remote_user: root
  

  tasks:
  - name: install nginx
  yum: name=nginx
  #调用template模块,src表示本机的template目录下的某一个文件 ,dest表示远程被控主机的存放路径,做用类似copy模块,但是template模板文件里可以支持变量以及算数运算
  "- name: templates
  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf"
  - name: start nginx
  service: name=nginx state=started
  
这个例子作用就是:
  第一步:在远程被控主机安装nginx
  第二步:将本机template模板文件复制到远程被控主机上
  第三步:启动nginx服务
  

  可能有时候我们需要判断某一个版本,在复制某一个文件到对应的机器上,这时候可以加上when这个关键词,就可以帮我们来解决这个问题,

&quot;when关键字的用法,作用类似一判断当满足某一个条件时就执行这个动作&quot;
  看下面的例子
  

[root@ansiblehost 19:36:47  ansible.yaml]#ls templates/  
nginx-6.conf.j2  nginx-7.conf.j2
  

  
[root@ansiblehost 19:36:54  ansible.yaml]#cat temnginx.yml
  
---
  
- hosts: web
  remote_user: root
  

  tasks:
  - name: install nginx
  yum: name=nginx
  

  - name: templates 6
  template: src=nginx-6.conf.j2 dest=/etc/nginx/nginx.conf
  #这是setup模块里的一个存放主版本的变量"ansible_distribution_major_version" 而"=="就表示判断的意思,作用就是判断如果主版本号是否等于6
  when: ansible_distribution_major_version=="6"
  

  - name: templates 7
  template: src=nginx-7.conf.j2 dest=/etc/nginx/nginx.conf
  #同上面的when作用相同
  when: ansible_distribution_major_version=="7"
  

  - name: start nginx
  service: name=nginx state=started
  
上面这个例子:作用是在web这个主机组里面的所有主机上都安装nginx服务,并把判断如果系统是centos6是复制本机上的6的nginx配置文件,同时7也是一样,然后在启动nginx服务
  

迭代 with_item
  

迭代的作用就类似与shell里的for循环的作用,with_item会把它里面定义的所有值,每次都传递一个给item这个特殊的变量里面,而with_item理由几个值item就循环几次知道没有才会停止  

  请看下面的例子
  

  [root@ansiblehost 19:44:12  ansible.yaml]#cat user_with_items.yml
  ---
  - hosts: web
  remote_user: root
  

  tasks:
  - name: add several users
  #item特殊变量代表的就是with_items里面的每一个值
  user: name={{ "item" }} group=root
  #with_items下面的所有值都属于被循环的值
  "with_items":
  - xiaohong
  - xiaolan
  
执行结果:
  

  [root@ansiblehost 19:43:59  ansible.yaml]#ansible web -a 'tail -n2 /etc/passwd'
  192.168.136.6 | SUCCESS | rc=0 >>
  xiaohong:x:504:0::/home/xiaohong:/bin/bash
  xiaolan:x:505:0::/home/xiaolan:/bin/bash
  

  192.168.136.5 | SUCCESS | rc=0 >>
  xiaohong:x:1003:0::/home/xiaohong:/bin/bash
  xiaolan:x:1004:0::/home/xiaolan:/bin/bash
  
上面的例子作用就是创建两个普通用户,但是使用with_items关键词来完成的
  

  

迭代嵌套子变量
  看下面的例子:
  

   [root@ansiblehost 20:34:28  ansible.yaml]#cat user_with_items.yml  ---
  - hosts: web
  remote_user: root
  

  tasks:
  - name: add group
  group: name={{ item }}
  with_items:
  - group1
  - group2
  - group3
  

  - name: add users
  #item.name <.>后面的name以及group都属于item的自变量
  user: name={{ item.name }} group={{ item.group }}
  #这个写法,迭代里面嵌套了另外的子变量(name)(group)
  with_items:
  - { name: 'laifu3',group: group1 }
  - { name: 'laifu2',group: group2 }
  - { name: 'laifu3',group: group3 }
  

  [root@ansiblehost 20:38:10  ansible.yaml]#ansible web -m shell -a 'id laifu3'
  192.168.136.6 | SUCCESS | rc=0 >>
  uid=506(laifu3) gid=506(group3) groups=506(group3)
  

  192.168.136.5 | SUCCESS | rc=0 >>
  uid=1005(laifu3) gid=1005(group3) groups=1005(group3)
  

  [root@ansiblehost 20:34:01  ansible.yaml]#ansible web -a 'tail -n3 /etc/group'
  192.168.136.6 | SUCCESS | rc=0 >>
  group1:x:504:
  group2:x:505:
  group3:x:506:
  

  192.168.136.5 | SUCCESS | rc=0 >>
  group1:x:1003:
  group2:x:1004:
  group3:x:1005:
  
这个playbook作用就是创建组,再创键新用户,然后再把用户加到创建好的组里面去
  

playbook中使用template模板文件的for循环 if判断
  例子一:for循环
  

  模板文件  

  [root@ansiblehost 09:26:20  ansible.yaml]#cat templates/for1.conf.j2
  "#for循环的列表ports来自下面的文件中定义的vaes变量中的ports变量的值。而每一次循环都会把ports里的值赋给port这个 变量,因为ports只有3个值所以只会循环3三遍"
  语法要求:
  开头:双{%里面的格式与shell里的格式基本相同%}
  中间:循环内容
  结尾:双{%endfor%}
  {%for port in ports%}
  server {
  listen {{ port }}
  }
  {%endfor%}
  

  playbook文件
  [root@ansiblehost 09:26:31  ansible.yaml]#cat for.yml
  ---
  - hosts: web
  remote_user: root
  vars:
  ports:
  - 81
  - 82
  - 83
  

  tasks:
  - name: tesk for
  template: src=for1.conf.j2 dest=/app/for1.conf
  

  执行结果:
  

  [root@ansiblehost 09:25:48  ansible.yaml]#ansible web -a 'cat /app/for1.conf'
  192.168.136.6 | SUCCESS | rc=0 >>
  server {
  listen 81
  }
  server {
  listen 82
  }
  server {
  listen 83
  }
  

  192.168.136.5 | SUCCESS | rc=0 >>
  server {
  listen 81
  }
  server {
  listen 82
  }
  server {
  listen 83
  }
  

  例子二:for循环嵌套子变量
  

template模板文件  [root@ansiblehost 09:51:47  ansible.yaml]#cat templates/for2.conf.j2
  {%for port in ports%}
  server {
  listen {{ port.listen_port }}
  }
  {%endfor%}
  

  
playbook文件
  [root@ansiblehost 09:52:07  ansible.yaml]#cat for2.yml
  ---
  - hosts: web
  remote_user: root
  vars:
  ports:
  - listen_port: 81
  - listen_port: 82
  - listen_port: 83
  

  tasks:
  - name: tesk for
  template: src=for2.conf.j2 dest=/app/for2.conf
  

  
执行结果:
  [root@ansiblehost 09:51:11  ansible.yaml]#ansible web -a 'cat /app/for2.conf'
  192.168.136.6 | SUCCESS | rc=0 >>
  server {
  listen 81
  }
  server {
  listen 82
  }
  server {
  listen 83
  }
  

  192.168.136.5 | SUCCESS | rc=0 >>
  server {
  listen 81
  }
  server {
  listen 82
  }
  server {
  listen 83
  }
  

  

  例子三:for循环嵌套多个元素
  

template模板文件  [root@ansiblehost 10:13:41  ansible.yaml]#cat templates/for3.conf.j2
  {%for vhost in vhosts%}
  server {
  port {{ vhost.port }}
  webserver {{ vhost.name }}
  webdir {{ vhost.root }}
  }
  {%endfor%}
  

  
playbook文件
  [root@ansiblehost 10:13:43  ansible.yaml]#cat for3.yml
  ---
  - hosts: web
  remote_user: root
  vars:
  vhosts:
  - web1:
  port: 81
  name: web1.magedu.com
  root: /app/webroot1
  - web2:
  port: 82
  name: web1.magedu.com
  root: /app/webroot2
  - web3:
  port: 83
  name: web1.magedu.com
  root: /app/webroot3
  tasks:
  - name: tesk for
  template: src=for3.conf.j2 dest=/app/for3.conf
  
执行结果
  [root@ansiblehost 10:12:15  ansible.yaml]#ansible web -a 'cat /app/for3.conf'
  192.168.136.6 | SUCCESS | rc=0 >>
  server {
  port 81
  webserver web1.magedu.com
  webdir /app/webroot1
  }
  server {
  port 82
  webserver web1.magedu.com
  webdir /app/webroot2
  }
  server {
  port 83
  webserver web1.magedu.com
  webdir /app/webroot3
  }
  

  192.168.136.5 | SUCCESS | rc=0 >>
  server {
  port 81
  webserver web1.magedu.com
  webdir /app/webroot1
  }
  server {
  port 82
  webserver web1.magedu.com
  webdir /app/webroot2
  }
  server {
  port 83
  webserver web1.magedu.com
  webdir /app/webroot3
  }
  

  
例子四:for循环嵌套if判断
  

  

  template模板文件
  

[root@ansiblehost 10:23:29  ansible.yaml]#cat templates/for4.conf.j2  
{%for vhost in vhosts%}
  
server {
  port {{ vhost.port }}
  

  #判断循环列表中变量&quot;vhost.name&quot;是否定义,如果定义了就把它的值复制到目标主机,
  &quot;语法要求:
  开头:{%前面可以任意变量,后面必须写&quot;is defined关键词&quot;%}
  中间:执行的任务
  结尾:{%endif%}&quot;
  &quot;{%if vhost.name is defined %}&quot;
  webserver {{ vhost.name }}
  &quot;{%endif%}&quot;
  webdir {{ vhost.root }}
  }
  {%endfor%}

playbook文件
  [root@ansiblehost 10:23:50  ansible.yaml]#cat for4.yml
  

- hosts: web  remote_user: root
  vars:
  vhosts:
  - web1:
  port: 81
  root: /app/webroot1
  

  - web2:
  port: 82
  name: web1.magedu.com
  root: /app/webroot2
  

  - web3:
  port: 83
  root: /app/webroot3
  tasks:
  - name: tesk for
  template: src=for4.conf.j2 dest=/app/for4.conf
  

  执行结果:
  [root@ansiblehost 10:23:04  ansible.yaml]#ansible web -a 'cat /app/for4.conf'
  192.168.136.6 | SUCCESS | rc=0 >>
  server {
  port 81
  webdir /app/webroot1
  }
  server {
  port 82
  webserver web1.magedu.com
  webdir /app/webroot2
  }
  server {
  port 83
  webdir /app/webroot3
  }
  

192.168.136.5 | SUCCESS | rc=0 >>  
server {
  port 81
  webdir /app/webroot1
  
}
  
server {
  port 82
  webserver web1.magedu.com
  webdir /app/webroot2
  
}
  
server {
  port 83
  webdir /app/webroot3
  
}
  

  
```

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-542735-1-1.html 上篇帖子: 【转载】 屏蔽Ansible中的危险命令方法 下篇帖子: ansible基础一
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表