• Ansible之Playbook中使用变量


    Playbook中同样也支持变量
    变量名:仅能由字母、数字和下划线组成,且只能以字母开头

    变量定义:

    variable=value
    variable: value
    

    范例:

    http_port=80
    http_port: 80
    

    变量调用方式:

    通过{{ variable_name }} 调用变量,且变量名前后建议加空格,有时用"{{ variable_name }}"才生效

    变量来源:

    1. ansible 的 setup facts 远程主机的所有变量都可直接调用
    2. 通过命令行指定变量,优先级最高
    [root@centos8 ~]# ansible-playbook -e varname=value test.yml
    
    1. 在playbook文件中定义
    vars:
      var1: value1
      var2: value2
    
    1. 在独立的变量YAML文件中定义
    - hosts: all
      vars_files:
        - vars.yml
    
    1. 在主机清单文件中定义
      主机(普通)变量:主机组中主机单独定义,优先级高于公共变量
      组(公共)变量:针对主机组中所有主机定义统一变量
    2. 在项目中针对主机和主机组定义
      在项目目录中创建 host_vars和group_vars目录
    3. 在role中定义

    变量的优先级从高到低如下

    -e 选项定义变量 -->playbook中vars_files --> playbook中vars变量定义 -->host_vars/主机名文件 -->主机清单中主机变量--> group_vars/主机组名文件-->group_vars/all文件--> 主机清单组 变量
    

    使用 setup 模块中变量

    本模块自动在playbook调用,不要用ansible命令调用,生成的系统状态信息, 并存放在facts变量中
    facts 包括的信息很多,如: 主机名,IP,CPU,内存,网卡等

    facts 变量的实际使用场景案例

    通过facts变量获取被控端CPU的个数信息,从而生成不同的Nginx配置文件
    通过facts变量获取被控端内存大小信息,从而生成不同的memcached的配置文件
    通过facts变量获取被控端主机名称信息,从而生成不同的Zabbix配置文件
    ....
    

    案例:使用setup变量

    [root@centos8 ~]# ansible 172.31.0.28 -m setup -a 'filter="ansible_default_ipv4"'
    172.31.0.28 | SUCCESS => {
        "ansible_facts": {
            "ansible_default_ipv4": {
                "address": "172.31.0.28",
                "alias": "eth0",
                "broadcast": "172.31.255.255",
                "gateway": "172.31.0.254",
                "interface": "eth0",
                "macaddress": "00:0c:29:ac:f5:a4",
                "mtu": 1500,
                "netmask": "255.255.0.0",
                "network": "172.31.0.0",
                "type": "ether"
            },
            "discovered_interpreter_python": "/usr/libexec/platform-python"
        },
        "changed": false
    }
    
    [root@centos8 ~]# ansible 172.31.0.28 -m setup -a 'filter="ansible_nodename"'
    172.31.0.28 | SUCCESS => {
        "ansible_facts": {
            "ansible_nodename": "centos8.longxuan.vip",
            "discovered_interpreter_python": "/usr/libexec/platform-python"
        },
        "changed": false
    }
    

    范例:

    ---
    # var1
    - hosts: websrvs
      remote_user: root
      gather_facts: yes
      tasks:
        - name: create log file
          file: name=/data/{{ ansible_nodename }}.log state=touch owner=long mode=600
    

    执行

    [root@centos8 ~]# ansible-playbook var1.yml
    

    范例: 显示 eth0 网卡的 IP 地址

    - hosts: websrvs
      tasks:
        - name: show eth0 ip address {{ ansible_facts["eth0"]["ipv4"]["address"]}}
          debug:
            msg: ip address {{ ansible_eth0.ipv4.address }}
    

    执行

    [root@centos8 ~]# ansible-playbook -v show_ip.yml 
    Using /etc/ansible/ansible.cfg as config file
    
    PLAY [websrvs] *********************************************************************************
    
    TASK [Gathering Facts] *************************************************************************
    ok: [172.31.0.48]
    ok: [172.31.0.38]
    
    TASK [show eth0 ip address 172.31.0.38] ********************************************************
    ok: [172.31.0.38] => {
        "msg": "ip address 172.31.0.38"
    }
    ok: [172.31.0.48] => {
        "msg": "ip address 172.31.0.48"
    }
    
    PLAY RECAP *************************************************************************************
    172.31.0.38                : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    172.31.0.48                : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
    

    范例:

    ---
    - hosts: websrvs
      tasks:
        - name: test var
          file: path=/data/{{ ansible_facts["eth0"]["ipv4"]["address"]}}.log state=touch
          #file: path=/data/{{ ansible_eth0.ipv4.address }}.log state=touch  #和上面效果一样
    

    执行

    [root@centos8 ~]# ansible-playbook  test.yml 
    
    [root@centos8 ~]# ll /data/172.31.0.38.log 
    -rw-r--r-- 1 root root 0 May 26 01:37 /data/172.31.0.38.log
    

    在playbook 命令行中定义变量

    范例:

    ---
    - hosts: websrvs
      remote_user: root
      tasks:
        - name: install package
          yum: name={{ pkname }} state=present
    

    执行安装任意一个软件包

    [07 root@centos8 ~]# ansible-playbook -e pkname=httpd var2.yml
    # 执行安装任意多个软件包
    [root@centos8 ~]# ansible-playbook -e pkname=zip,unzip var2.yml
    

    范例:

    [root@centos8 ~]# cat vars 
    pkname1: memcached
    pkname2: vsftpd
    
    root@centos8 ~]# cat var3.yml
    ---
    - hosts: websrvs
      remote_user: root
      tasks:
        - name: install package {{ pkname1 }}
          yum: name={{ pkname1 }} state=present
        - name: install package {{ pkname2 }}
          yum: name={{ pkname2 }} state=present
    

    执行:两条命令效果一样

    [root@centos8 ~]# ansible-playbook -e pkname1=memcached -e pkname2=vsftpd var3.yml
    
    [root@centos8 ~]# ansible-playbook -e '@vars' var3.yml
    

    在playbook文件中定义变量

    范例:

    ---
    - hosts: websrvs
      remote_user: root
      vars:
        username: user1
        groupname: group1
      tasks:
        - name: create group {{ groupname }}
          group: name={{ groupname }} state=present
        - name: create user {{ username }}
          user: name={{ username }} group={{ groupname }} state=present
    

    执行

    [root@centos8 ~]# ansible-playbook -e 'username=user1 groupname=group1' var4.yml
    

    范例:变量的相互调用

    ---
    - hosts: websrvs
      remote_user: root
      vars:
        collect_info: "/data/test/{{ansible_default_ipv4['address']}}/"
        
      tasks:
        - name: create ip directoty
          file: name="{{collect_info}}" state=directory
    

    执行:

    [root@centos8 ~]# ansible-playbook var5.yml
    

    执行之后的目标主机的结果如下

    [root@centos8 ~]# tree /data/test/
    /data/test/
    └── 172.31.0.48
    
    1 directory, 0 files
    

    范例: 变量的相互调用

    ---
    - hosts: websrvs
      vars:
        suffix: "txt"
        file: "{{ ansible_nodename }}.{{suffix}}"
      tasks:
        - name: test var
          file: path="/data/{{file}}" state=touch
    

    执行:

    [root@centos8 ~]# ansible-playbook var6.yml 
    

    范例: 安装多个包

    - hosts: websrvs
      vars:
        web: httpd
        db: mariadb-server
      tasks:
        - name: install {{ web }} {{ db }}
          yum:
            name:
              - "{{ web }}"
              - "{{ db }}"
            state: latest
    
    - hosts: websrvs
      tasks:
        - name: install package
          yum: name={{ pack }}
          vars:
            pack: 
              - httpd
              - memcached
    

    范例: 安装指定版本的MySQL

    [root@centos8 ~]# cat install_mysql.yml 
    ---
    # install mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz
    - hosts: dbserver
      remote_user: root
      gather_facts: no
      vars:
        version: "mysql-5.6.46-linux-glibc2.12-x86_64"
        suffix: "tar.gz"
        file: "{{version}}.{{suffix}}"
    
      tasks:
        - name: install package
          yum: name=libaio,perl-Data-Dumper,perl-Getopt-Long
        - name: create mysql group
          group: name=mysql gid=306
        - name: create mysql user
          user: name=mysql uid=306 group=mysql shell=/sbin/nologin system=yes create_home=no home=/data/mysql
        - name: copy tar to remove host and file mode
          unarchive: src=/data/ansible/files/{{file}} dest=/usr/local/ owner=root group=root
        - name: create linkfile /usr/local/mysql
          file: src=/usr/local/{{version}} dest=/usr/local/mysql state=link
        - name: data dir
          shell: chdir=/usr/local/mysql/ ./scripts/mysql_install_db --datadir=/data/mysql --user=mysql
          tags: data
        - name: config my.cnf
          copy: src=/data/ansible/files/my.cnf dest=/etc/my.cnf
        - name: service script
          shell: /bin/cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
        - name: enable servcie
          shell: /etc/init.d/mysqld start;chkconfig --add mysqld;chkconfig mysqld on
          
          tags: service
        - name: PATH variable
          copy: content='PATH=/usr/local/mysql/bin:$PATH' dest=/etc/profile.d/mysql.sh
        - name: secure script
          script: /data/ansible/files/secure_mysql.sh
          tags: script
    

    使用变量文件

    可以在一个独立的playbook文件中定义变量,在另一个playbook文件中引用变量文件中的变量,比playbook中定义的变量优化级高

    [root@centos8 ~]# vim var7.yml
    ---
    # variable file
    package_name: mariadb-server
    service_name: mariadb
    
    # 这个yml文件调用上面的var7.yml文件
    [root@centos8 ~]# vim var8.yml
    ---
    # install package and start service
    - hosts: dbserver
      remote_user: root
      vars_files:
        - var7.yml
      tasks:
        - name: install package
          yum: name={{ package_name }}
          tags: install
        - name: start service
          service: name={{service_name}} state=started enabled=yes
    

    执行

    [root@centos8 ~]# ansible-playbook var8.yml
    

    范例:

    [root@centos8 ~]# cat vars2.yml
    ---
    var1: httpd
    var2: nginx
    
    [root@centos8 ~]# cat var9.yml
    ---
    - hosts: web
      remote_user: root
      vars_files:
        - vars2.yml
      tasks:
        - name: create httpd log
          file: name=/app/{{ var1 }}.log state=touch
        - name: create nginx log
          file: name=/app/{{ var2 }}.log state=touch
    

    针对主机和主机组的变量

    在主机清单中针对所有项目的主机和主机分组的变量

    所有项目的主机变量

    在inventory 主机清单文件中为指定的主机定义变量以便于在playbook中使用
    范例:

    [websrvs]
    www1.longxuan.vip http_port=80 maxRequestsPerChild=808
    www2.longxuan.vip http_port=8080 maxRequestsPerChild=909
    

    所有项目的组(公共)变量

    在inventory 主机清单文件中赋予给指定组内所有主机上的在playbook中可用的变量,如果和主机变是同名,优先级低于主机变量

    范例:

    [websrvs:vars]
    http_port=80
    ntp_server=ntp.longxuan.vip
    nfs_server=nfs.longxuan.vip
    [all:vars]
    # --------- Main Variables ---------------
    # Cluster container-runtime supported: docker, containerd
    CONTAINER_RUNTIME="docker"
    # Network plugins supported: calico, flannel, kube-router, cilium, kube-ovn
    CLUSTER_NETWORK="calico"
    # Service proxy mode of kube-proxy: 'iptables' or 'ipvs'
    PROXY_MODE="ipvs"
    # K8S Service CIDR, not overlap with node(host) networking
    SERVICE_CIDR="192.168.0.0/16"
    # Cluster CIDR (Pod CIDR), not overlap with node(host) networking
    CLUSTER_CIDR="172.16.0.0/16"
    # NodePort Range
    NODE_PORT_RANGE="20000-60000"
    # Cluster DNS Domain
    CLUSTER_DNS_DOMAIN="longxuan.local."
    

    范例:

    [root@ansible ~]# vim /etc/ansible/hosts
    [websrvs]
    172.31.0.8 hname=www1 domain=longxuan.io
    172.31.0.7 hname=www2
    [websrvs:vars]
    mark="-"
    [all:vars]
    domain=longxuan.org
    [root@ansible ~]# ansible websrvs -m hostname -a 'name={{ hname }}{{ mark }}{{ domain }}'
    #命令行指定变量:
    [root@ansible ~]# ansible websrvs -e domain=longxuan.cn -m hostname -a 'name={{ hname }}{{ mark }}{{ domain }}'
    

    范例: k8s 的ansible 变量文件

    [etcd]
    172.31.0.104 NODE_NAME=etcd1
    172.31.0.105 NODE_NAME=etcd2
    172.31.0.106 NODE_NAME=etcd3
    [kube-master]
    172.31.0.103 NEW_MASTER=yes
    172.31.0.101
    172.31.0.102
    [kube-node]
    172.31.0.109 NEW_NODE=yes
    172.31.0.107
    172.31.0.108
    [harbor]
    
    [ex-lb]
    
    172.31.0.111 LB_ROLE=master EX_APISERVER_VIP=172.31.0.100 EX_APISERVER_PORT=8443
    172.31.0.112 LB_ROLE=backup EX_APISERVER_VIP=172.31.0.100 EX_APISERVER_PORT=8443
    [chrony]
    [all:vars]
    CONTAINER_RUNTIME="docker"
    CLUSTER_NETWORK="calico"
    PROXY_MODE="ipvs"
    SERVICE_CIDR="192.168.0.0/16"
    CLUSTER_CIDR="172.16.0.0/16"
    NODE_PORT_RANGE="20000-60000"
    CLUSTER_DNS_DOMAIN="longxuan.local."
    bin_dir="/usr/bin"
    ca_dir="/etc/kubernetes/ssl"
    base_dir="/etc/ansible"
    

    针对当前项目的主机和主机组的变量

    上面的方式是针对所有项目都有效,而官方更建议的方式是使用ansible特定项目的主机变量和组变量
    生产建议在项目目录中创建额外的两个变量目录,分别是host_vars和group_vars
    host_vars下面的文件名和主机清单主机名一致,针对单个主机进行变量定义,格式:host_vars/hostname
    group_vars下面的文件名和主机清单中组名一致,针对单个组进行变量定义,格式:
    gorup_vars/groupname
    group_vars/all文件内定义的变量对所有组都有效

    范例: 特定项目的主机和组变量

    [root@ansible ansible]# pwd
    /data/ansible
    [root@ansible ansible]# mkdir host_vars
    [root@ansible ansible]# mkdir group_vars
    [root@ansible ansible]# cat host_vars/172.31.0.8
    id: 2
    [root@ansible ansible]# cat host_vars/172.31.0.7
    id: 1
    [root@ansible ansible]# cat group_vars/websrvs
    name: web
    [root@ansible ansible]# cat group_vars/all
    domain: longxuan.org
    [root@ansible ansible]# tree host_vars/ group_vars/
    host_vars/
    ├── 172.31.0.7
    └── 172.31.0.8
    group_vars/
    ├── all
    └── websrvs
    0 directories, 4 files
    [root@ansible ansible]# cat test.yml
    - hosts: websrvs
      tasks:
        - name: get variable
          command: echo "{{name}}{{id}}.{{domain}}"
          register: result
        - name: print variable
          debug:
            msg: "{{result.stdout}}"
            
    [root@ansible ansible]# ansible-playbook test.yml
    

    register 注册变量

    在playbook中可以使用register将捕获命令的输出保存在临时变量中,然后使用debug模块进行显示输出

    范例: 利用debug 模块输出变量

    [root@centos8 ~]# cat register1.yml
    - hosts: dbsrvs
      tasks:
        - name: get variable
          shell: hostname
          register: name
        - name: "print variable"
            debug:
              msg: "{{ name }}" #输出register注册的name变量的全部信息,注意
    变量要加" "引起来
    #msg: "{{ name.cmd }}"    #显示命令
    #msg: "{{ name.rc }}"     #显示命令成功与否
    #msg: "{{ name.stdout }}" #显示命令的输出结果为字符串形式
    #msg: "{{ name.stdout_lines }}"    #显示命令的输出结果为列表形式
    #msg: "{{ name.stdout_lines[0] }}" #显示命令的输出结果的列表中的第一个元素
    #msg: "{{ name['stdout_lines'] }}" #显示命令的执行结果为列表形式
    #说明
    第一个 task 中,使用了 register 注册变量名为 name ;当 shell 模块执行完毕后,会将数据放到该变量中。
    第二给 task 中,使用了 debug模块,并从变量name中获取数据。
    

    范例:使用 register 注册变量创建文件

    - hosts: websrvs
      tasks:
        - name: get variable
          shell: hostname
          register: name
        - name: create file
          file: dest=/tmp/{{name.stdout}}.log state=touch
    

    执行

    [root@centos8 ~]# ansible-playbook register2.yml 
    

    范例: register和debug模块

    ---
    - hosts: websrvs
      tasks:
        - shell: echo hello world
          register: say_hi
        - shell: "awk -F: 'NR==1{print $1}' /etc/passwd"
          register: user
        - debug: var=say_hi.stdout  #自定义输出变量代替msg
        - debug: var=user.stdout    #自定义输出变量代替msg
    

    执行

    [root@centos8 ~]# ansible-playbook debug_test.yml
    

    范例: 安装启动服务并检查

    ---
    - hosts: websrvs
      vars:
        package_name: nginx
        service_name: nginx
      tasks:
        - name: install {{package_name}}
          yum: name={{package_name}}
        - name: start {{service_name}}
          service: name={{service_name}}
        - name: check
          shell: ps axu | grep {{service_name}}
          register: check_service
        - name: debug
          debug:
            msg: "{{check_service.stdout_lines}}"
    

    执行

    [root@centos8 ~]# ansible-playbook service.yml
    

    范例: 批量修改主机名

    - hosts: websrvs
      vars:
        host: web
        domain: longxuan.vip
      tasks:
        - name: get variable
          shell: echo $RANDOM | md5sum | cut -c 1-8
          register: get_random
        - name: print variable
          debug:
            msg: "{{get_random.stdout}}"
        - name: set hostname
          hostname: name={{host}}-{{get_random.stdout}}.{{domain}}
    

    执行

    [04:06:55 root@centos8 ~]# ansible-playbook hostname.yml 
    
    PLAY [websrvs] *********************************************************************************
    
    TASK [Gathering Facts] *************************************************************************
    ok: [172.31.0.48]
    ok: [172.31.0.38]
    
    TASK [get variable] ****************************************************************************
    changed: [172.31.0.48]
    changed: [172.31.0.38]
    
    TASK [print variable] **************************************************************************
    ok: [172.31.0.38] => {
        "msg": "453e7750"
    }
    ok: [172.31.0.48] => {
        "msg": "b89111a1"
    }
    
    TASK [set hostname] ****************************************************************************
    changed: [172.31.0.38]
    changed: [172.31.0.48]
    
    PLAY RECAP *************************************************************************************
    172.31.0.38                : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    172.31.0.48                : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
    
  • 相关阅读:
    解决问题,别扩展问题
    Hystrix 配置参数全解析
    请求合并哪家强
    在Spring-Boot中实现通用Auth认证的几种方式
    Java高级特性之泛型
    一键部署进化史
    JavaScript Alert 函数执行顺序问题
    新版的 Springsecurity request.getRequestDispatcher).forward(request, response); 404 问题,已解决
    maridb 10.3 主从复制,待机情况下从库 cpu 占用率高的处理方法
    springboot 2.0 mariadb hikari-cp连接池
  • 原文地址:https://www.cnblogs.com/xuanlv-0413/p/14815179.html
Copyright © 2020-2023  润新知