ansible自定义变量、获取hosts中主机ip

变量的定义:

变量名应该由字母、数字下划数组成

变量名必须以字母开头

ansible内置关键字不能作为变量名

一、在Inventory中定义变量

 1、 定义主机变量(在主机清单里定义)

1.1 内置主机变量

所谓内置变量其实就是ansible.cfg配置文件中的选项,在其前加上ansible_即成为内置变量。当然内置变拥有比ansible.cfg中选项更高的优先级,而且针对不同的主机,可以定义不同的值。

# 一般连接
ansible_ssh_host     #用于指定被管理的主机的真实IP
ansible_ssh_port     #用于指定连接到被管理主机的ssh端口号,默认是22
ansible_ssh_user     #ssh连接时默认使用的用户名

# 特定ssh连接
ansible_connection     #SSH连接的类型:local, ssh, paramiko,在ansible 1.2 之前默认是paramiko,后来智能选择,优先使用基于ControlPersist的ssh(如果支持的话)

ansible_ssh_pass     #ssh连接时的密码
ansible_ssh_private_key_file  #秘钥文件路径,如果不想使用ssh-agent管理秘钥文件时可以使用此选项

ansible_ssh_executable  #如果ssh指令不在默认路径当中,可以使用该变量来定义其路径

# 特权升级
ansible_become  #相当于ansible_sudo或者ansible_su,允许强制特权升级
ansible_become_user #通过特权升级到的用户,相当于ansible_sudo_user或者ansible_su_user
ansible_become_pass  # 提升特权时,如果需要密码的话,可以通过该变量指定,相当于ansible_sudo_pass或者ansible_su_pass

ansible_sudo_exec     #如果sudo命令不在默认路径,需要指定sudo命令路径

# 远程主机环境参数
ansible_shell_executable # 设置目标机上使用的shell,默认为/bin/sh

ansible_python_interpreter  #用来指定python解释器的路径,默认为/usr/bin/python 同样可以指定ruby 、perl 的路径
ansible_*_interpreter     #其他解释器路径,用法与ansible_python_interpreter类似,这里"*"可以是ruby或才perl等其他语言

实例:

[test]
192.168.1.1 ansible_ssh_user=root ansible_ssh_pass='P@ssw0rd'
192.168.1.2 ansible_ssh_user=breeze ansible_ssh_pass='123456'
192.168.1.3 ansible_ssh_user=bernie ansible_ssh_port=3055 ansible_ssh_pass='456789'

1.2 定义主机组变量

变量也可以通过组名,应用到组内的所有成员:

[wuhan]
web1
web2

[suizhou]
web4
web3

[hubei:children]
wuhan
suizhou

[hubei:vars]
ntp_server=192.168.1.10
zabbix_server=192.168.1.10

二、在Playbook中定义变量

2.1 变量的定义方式

2.1.1 通过vars关键字定义

- name: use vars define invrionmemnt
  hosts: test
  user: ansible
  vars: 
    http_port: 80
    server_name: localhost
    conf_file: /etc/nginx/conf/default.conf

2.1.2  通过vars_files关键字引入变量文件

- hosts: all
  remote_user: root
  vars:
    favcolor: blue
  vars_files:
    - vars/external_vars.yml
    - vars/user_vars.yml

# vars/user_vars.yml示例:
users:
  bjones:
    first_name: Bob
    last_name: Jones
    home_dirs: /users/bjones
  acook:
    first_name: Anne
    last_name: Cook
    home_dirs: /users/acook

2.1.3  在playbook中通过host_vars和group_vars目录定义变量

下面这是一个项目的playbook目录结构。这个项目中,包含一个ansible.cfg文件,一个inventory文件,一个playbook.yml文件,一个group_vars目录和一个host_vars目录:

# tree /etc/ansible/playbooks/project
/etc/ansible/playbooks/project
├── ansible.cfg
├── group_vars
│   ├── datacenter1
│   ├── datacenter2
│   └── datacenters
├── host_vars
│   ├── demo1.example.com
│   ├── demo2.example.com
│   ├── demo3.example.com
│   └── demo4.example.com
├── inventory
└── playbook.yml

其中inventory文件的示例如下:

[datacenter1]
demo1.example.com
demo2.example.com

[datacenter2]
demo3.example.com
demo4.example.com

[datacenters:children]
datacenter1
datacenter2

可以看到group_vars目录中,定义了三个文件,分别以inventory文件中的三个主机组命名,所以这三个文件中定义的就分别是这三个组可以使用的变量。

此种自定义变量比较常见,inventory.ini主机清单中主机组的[datacenter1]对应group_vars下的datacenter1.yml文件

在host_vars目录中,定义了三个文件,分别以inventory文件中的四个主机命名,所以这四个文件中定义的就分别是这四个主机可以使用的变量。

# cat demo1.example.com 
package: httpd

# cat demo2.example.com 
package: apache

# cat demo3.example.com 
package: mariadb-server

# cat demo4.example.com 
package: mysql-server

假如主机组定义的变量与主机冲突,主机变量优先级最高

2.1.4 注册变量

在有些时候,可能需要将某一条任务执行的结果保存下来,以便在接下的任务中调用或者做些判断。可以通过register关键字来实现将某一任务结果保存为一个变量。

- name: register variables
  hosts: test
  tasks:
    - name: capture output of whoami command
      command: whoami
      register: login

注册变量的应用场景:

  1. 在一台远端的服务器获取一个目录下的一列表的文件,然后下载这些文件
  2. 在handler执行之前,发现前面一个task发生了changed,然后执行一个指定的task
  3. 获取远端服务器的ssh key的内容,构建出known_hosts文件

2.1.5 设置变量set_fact

---
- hosts: 192.168.40.132
  remote_user: root
  tasks:
  - set_fact:
      testvar: "2022-1-9"
  - debug:
      msg: "{{testvar}}"

---
- hosts: 192.168.40.133
  remote_user: root
  tasks:
    - name: test vars
      set_fact:
        _consul_data: '{{ consul.local_dir | default("/root/zjz" ~ "/consul") }}/data'
        _consul_config: '{{ consul.local_dir | default("/root/test" ~ "/consul") }}/config'
    - name: print vars
      debug:
        var: "_consul_data, _consul_config"

此处~的作用:拼接

 "/root/zjz" ~ "/consul" 等价于 "/root/zjz/consul"

+号运算符:可以完成数字相加,字符串相加,列表相加。但是并不推荐使用+运算符来操作字符串,字符串相加应该使用~运算符。
-号运算符:只能针对两个数字相减。
/号运算符:对两个数进行相除。
%号运算符:取余运算。
*号运算符:乘号运算符,并且可以对字符进行相乘。
**号运算符:次幂运算符,比如2**3=8。
in操作符:跟python中的in一样使用,比如{{1 in [1,2,3]}}返回true。
~号运算符:拼接多个字符串,比如{{"Hello" ~ "World"}}将返回HelloWorld。

2.1.6  通过命令行设置变量

---
- hosts: '{{ hosts }}'
  remote_user: '{{ user }}'
  tasks:
     - ...
ansible-playbook release.yml --extra-vars "hosts=vipers user=starbuck"

或者
--extra-vars '{"hosts":"vipers","user":"starbuck"}'

三、获取主机ip案例

1、背景:

需要在特定的主机上设置定时任务,且里面涉及ip变量。如何拿到ip地址是重点

{{ hostvars[groups['master'][0]]['ansible_host'] }}:

  • hostvars是一个特殊的变量,它包含了Ansible在当前Playbook运行过程中,关于所有主机的所有变量,可以理解为一个大字典。关于每一台主机的具体信息,你可以通过hostvars[hostname]的方式进行访问。

  • groups是一个包含了所有分组及其成员主机的字典。比如在你的inventory文件中存在一个叫做'master'的组,你可以通过groups['master']来获取到这个组下的所有主机清单。

  • groups['master'][0]表示你要获取'master'这个分组中的第一台主机。

  • ['ansible_host']接在hostvars[groups['master'][0]]后面,表示你要获取传入主机的ansible_host属性,也就是主机的地址。

因此,{{ hostvars[groups['master'][0]]['ansible_host'] }}的含义是:获取'master'组里的第一台主机的IP地址或者主机名。 

2、代码

- hosts: all
  vars:
    registry_ip: "{{ hostvars[groups['master'][0]]['ansible_host'] }}" 
    es2_ip: "{{ hostvars[groups['es2'][0]]['ansible_host'] }}"
  tasks:
  - name: Configure cron file
    copy:
      content: |
        #0 18 * * 6 /bin/bash /healsci/scripts/archive_cluster.sh  /var/log/backup/image.log  2>&1
        #20 18 * * 6 /bin/bash /healsci/scripts/archive_image.sh  -b  /var/log/backup/image.log  2>&1
        #40 18 1 * * /bin/bash /healsci/scripts/archive_es.sh  -h${{ es2_ip }}  -r${{  registry_ip }}  backup  /var/log/backup/es.log  2>&1
        #40 18 2 * * /bin/bash /healsci/scripts/archive_minio.sh  -b  /var/log/backup/minio.log  2>&1
        #0 18 3 * * /usr/bin/ansible-playbook /healsci/scripts/archive_config_playbook.yml   /var/log/backup/config.log  2>&1
      dest: /var/spool/cron/root
      owner: root
      group: root
      mode: '0600'
    when: "inventory_hostname == groups['docker_swarm_worker'][-1]"

3、补充:拼接用法

docker_swarm_interface: "{{ ansible_default_ipv4['interface'] }}"

docker_registry: "{{hostvars[groups['docker_swarm_manager'][0]]['ansible_' + docker_swarm_interface]['ipv4']['address'] }}:5000"

  1. 'ansible_' + docker_swarm_interface**:

    • 假设 docker_swarm_interface 的值为 "eth0",那么这个表达式会动态生成字符串 'ansible_eth0'。这是一个键名,通常在 Ansible Playbook 中定义的主机变量中存储网络接口信息。
  2. **hostvars[swarm-01]['ansible_eth0']**:

    • 通过上面的动态键名,获取存储在 swarm-01 主机中的 ansible_eth0 变量。这通常是一个字典,包含关于 eth0 接口的信息。
  3. **['ipv4']['address']**:

    • 'ipv4' 是一个嵌套字典,通常包含该网络接口的 IPv4 地址等信息。
    • ['address'] 获取这个字典中的 address 字段,它包含实际的 IP 地址。

四、变量优先级 

1、ansible中变量的优先级

  • -e (--extra-vars 选项指定的变量)最高
  • inventory 主机清单中定义的变量(ansible_ssh_user等)
  • play剧本中vars、vars_files定义的变量
  • 系统的facts变量
  • 角色定义的默认变量 最低

从上到下优先级逐渐降低,高优先级会覆盖掉低优先级的变量

extra vars (always win precedence)

task vars (only for the task)

block vars (only for tasks in block)

role and include vars

set_facts

registered vars

play vars_files

play vars_prompt

play vars

host facts

playbook host_vars

playbook group_vars

inventory host_vars

inventory group_vars

inventory vars

role defaults

  

 




 

https://www.cnblogs.com/mauricewei/p/10054300.html   很详细

 

posted @ 2022-01-10 00:16  凡人半睁眼  阅读(939)  评论(0编辑  收藏  举报