Ansible變數
一、變數概述
變數提供了便捷的方式來管理Ansible playbook的每一個專案中的動態值,比如nginx-1.6.3這個軟體包的版本,在其他地方或許會反覆使用,
那麼如果講此值設定為變數,然後再在其他的playbook中呼叫,會方便許多。如此一來還方便維護,減少維護的成本。
1.透過命令列進行變數定義 2.在play檔案中進行變數定義 3.透過Inventory主機資訊檔案中進行變數定義 4.透過vars_files定義變數 5.透過host_vars和group_vars定義變數 如果在定義變數時,變數衝突了 在上述的三個地方分別設定了: 1.命令列中:age=11 2.play檔案中:age=12 3.Inventory中:age=13 那麼,最終的age結果一定是11 變數的讀取優先順序為:命令列 > playbook檔案 > Inventory檔案 #注意:變數命名,應該由字母、數字、下劃線組成,必須以字母開頭
- name: Install LNMP yum: name: "{{ packages }}" vars: packages: - nginx - php - mariadb-server
[root@m01 base]# vim install.yml - hosts: web_group vars: package: - httpd - mariadb-server - MySQL-python - php - nginx tasks: - name: Install Server yum: name: "{{ package }}"
[root@m01 base]# vim install.yml - hosts: web_group vars: web: - httpd - nginx db: - mariadb-server - MySQL-python tasks: - name: Install Server yum: name: "{{ web }}" - name: Install DB Server yum: name: "{{ db }}"
剛才我們學到在playbook中使用vars定義變數,有一個缺陷,就是其他的playbook無法使用該變數。
所以我們可以採取第二種定義變數的方式,在vars_file中定義變數。
#1.配置變數檔案 [root@m01 base]# vim vars.yml web_server: nginx db_server: mariadb-server #2.呼叫變數檔案再使用變數 [root@m01 base]# vim host.yml - hosts: db_group vars_files: /project/base/vars.yml tasks: - name: Install Mariadb Server yum: name: "{{ db_server }}" #3.定義多個變數檔案 [root@m01 base]# vim host.yml - hosts: db_group vars_files: - /project/base/vars.yml - /project/base/vars2.yml tasks: - name: Install Mariadb Server yum: name: "{{ nginx }}"
[root@m01 ~]# ansible "web01" -m setup #setup模組,獲取主機資訊(看內建變數) web01 | SUCCESS => { "ansible_facts": { "ansible_all_ipv4_addresses": [ "10.0.0.7", "172.16.1.7" ], ... # ansible_all_ipv4_addresses就是內建變數,檢視內建變數 [root@m01 ~]# ansible "web01" -m setup -a 'filter=ansible_all_ipv4_addresses' [root@m01 ~]# ansible "web01" -m setup -a 'filter=ansible_default_ipv4' #直接使用內建變數 [root@m01 ~]# vim mkdir.yml - hosts: web03 tasks: - name: Create DIR file: path: /tmp/{{ ansible_default_ipv4['address'] }}#路徑下變數可以不加引號,裡面也可以.address state: directory [root@m01 ~]# ansible-playbook mkdir.yml [root@web03 tmp]# ls 10.0.0.9 #可以把內建引數寫在vars_file中,也可以定義變數再使用 [root@m01 ~]# vim mkdir.yml - hosts: web03 vars: - remote_ip: "{{ ansible_default_ipv4['address'] }}" tasks: - name: Create IP DIR file: path: /tmp/{{ remote_ip }} state: directory #例項 [root@m01 ~]# vim mkdir.yml - hosts: web_group tasks: - name: Create Backup DIR file: path: /backup/{{ ansible_fqdn }}_{{ ansible_default_ipv4['address'] }}_{{ ansible_date_time.date }} #ansible_fqdn:主機名 state: directory [root@m01 ~]# ansible-playbook mkdir.yml [root@web01 backup]# ls web01_10.0.0.7_2024-03-27 [root@web02 backup]# ls web02_10.0.0.8_2024-03-27
#1.配置主機清單 [root@m01 ~]# vim /etc/ansible/hosts [web_group] web01 ansible_ssh_pass='admin123' web02 ansible_ssh_pass='admin123' [db_group] db01 ansible_ssh_pass='admin123' db02 ansible_ssh_pass='admin123' db03 ansible_ssh_pass='admin123' [web_group:vars] #對web_group組定義變數 web_server=nginx ------------------------------------------ #2.呼叫變數 [root@m01 base]# vim install.yml - hosts: web_group tasks: - name: Create WEB Dir file: path: /tmp/{{ web_server }} state: directory #檢查結果 [root@m01 base]# ansible-playbook install.yml [root@web01 tmp]# ls nginx ------------------------------------------ #3.對整合組定義變數 [root@m01 ~]# vim /etc/ansible/hosts [web_group] web01 ansible_ssh_pass='admin123' web02 ansible_ssh_pass='admin123' [db_group] db01 ansible_ssh_pass='admin123' db02 ansible_ssh_pass='admin123' db03 ansible_ssh_pass='admin123' [web_group:vars] web_server=nginx #優先順序高於整合組的優先順序 [nfs_client:children] #設定整合組 db_group web_group [nfs_client:vars] #對整合組定義變數 web_server=http ------------------------------------------ #4.呼叫變數 [root@m01 base]# vim mkdir.yml - hosts: nfs_client tasks: - name: Create Backup DIR file: path: /tmp/{{ web_server }} state: directory ------------------------------------------ #檢視建立目錄 [root@m01 base]# ansible 'all' -m shell -a 'ls /tmp' #注意: 主機組定義的變數優先順序比整合組呼叫的變數優先順序高 先讀取整合組的變數,後讀取組的變數,則組的變數將覆蓋整合組的變數
之前的幾種變數定義都不是很好用,比較好用的是在Ansible專案目錄下建立兩個變數目錄:
host_vars
group_vars
切記,目錄名字一定要一致,不能做任何修改(ansible會到yml同級目錄下去找這個名字,不需要呼叫)
#建立組變數的目錄,不能改名字 [root@m01 base]# mkdir group_vars #目錄下的名字要與主機清單裡面組名相同 [root@m01 base]# vim group_vars/web_group web_server: http #呼叫變數 [root@m01 base]# vi mkdir.yml - hosts: web_group # 會去yml同級目錄下group_vars裡找web_group tasks: - name: Create Backup DIR file: path: /tmp/{{ web_server }} state: directory
#建立主機變數的目錄,不能改名字 [root@m01 base]# mkdir host_vars #目錄下的名字要與主機清單裡面主機名相同 [root@m01 base]# vim host_vars/db01 web_server: host_vars #呼叫變數 [root@m01 base]# vim mkdir.yml - hosts: nfs_client tasks: - name: Create Backup DIR file: path: /tmp/{{ web_server }} state: directory
#注意: 主機組定義的變數優先順序比整合組呼叫的變數優先順序高,主機定義的變數優先順序比主機組定義的變數優先順序高
[root@m01 base]# vim mkdir.yml - hosts: nfs_client tasks: - name: Create Backup DIR file: path: /tmp/{{ web_server }} state: directory #命令列指定變數的值 [root@m01 base]# ansible-playbook mkdir.yml -e "web_server=commond" #遠端檢視檔案 [root@m01 base]# ansible 'all' -m shell -a 'ls /tmp' #指定多個變數 [root@m01 base]# vim mkdir.yml - hosts: nfs_client tasks: - name: Create Backup DIR file: path: /tmp/{{ web_server }} state: directory - name: Create db DIR file: path: /tmp/{{ db_server }} state: directory [root@m01 base]# ansible-playbook mkdir.yml -e "web_server=commond" -e "db_server=mysql"
#配置playbook變數 [root@m01 base]# vim mkdir.yml - hosts: nfs_client vars: web_server: playbook_vars vars_files: - ./vars_file.yml tasks: - name: Create Backup DIR file: path: /opt/{{ web_server }} state: directory #配置var_file變數 [root@m01 base]# vim var_file.yml web_server: vars_files #主機清單定義變數 [root@m01 base]# vim /etc/ansible/hosts [web_group:vars] web_server=inventory_vars #host_vars定義變數 [root@m01 base]# vim host_vars/web01 web_server: host_vars #group_vars定義變數 [root@m01 base]# vim group_var/web_group web_server: group_vars #命令列變數 [root@m01 base]# ansible-playbook mkdir.yml -e "web_server=command" #測試後優先順序結果: 命令列 > var_files > playbook_vars > host_vars > group_vars配置組變數 > group_vars配置整合組變數 > 主機清單定義組變數 > 主機清單定義整合組變數
[root@m01 ~]# vim vars_file.yml lamp: framework: web_package: httpd db_package: mariadb-server php_package: php lnmp: framework: web_package: nginx db_package: mysql php_package: php lnmt: framework: web_package: nginx db_package: mysql php_package: tomcat #編輯playbook檔案 [root@m01 ~]# vim test.yml - hosts: web_group vars_files: ./vars_file.yml tasks: - name: Install LAMP httpd yum: name: "{{ lamp.framework.web_package }}" #不能寫lamp.framework,不認 - name: Install LAMP mariadb-server yum: name: "{{ lamp.framework.db_package }}" - name: Install LAMP php yum: name: "{{ lamp.framework.php_package }}" #官方推薦寫法 [root@m01 ~]# vim test.yml - hosts: web_group vars_files: ./vars_file.yml tasks: - name: Install LAMP httpd yum: name: "{{ lamp['framework']['web_package'] }}" - name: Install LAMP mariadb-server yum: name: "{{ lamp['framework']['db_package'] }}" - name: Install LAMP php yum: name: "{{ lamp['framework']['php_package'] }}"
當ansible的模組在執行之後,其實都會返回一些result結果,就像是執行指令碼,我們有的時候需要指令碼給我們一些return返回值,我們才知道,
上一步是否可以執行成功,但是...預設情況下,ansible的result並不會顯示出來,所以,我們可以把這些返回值'儲存'到變數中,
這樣我們就能透過'呼叫'對應的變數名,從而獲取到這些result,這種將模組的返回值,寫入到變數中的方法被稱為變數註冊
#建立目錄獲取過程 [root@m01 ~]# vim test.yml - hosts: web01 tasks: - name: Create Dir file: path: /tmp/{{ ansible_fqdn }} state: directory register: get_mkdir_status #register獲取上面建立的過程放到自己定義的變數中 - name: Get register debug: #用於輸出內容 msg: "{{ get_mkdir_status }}" [root@m01 ~]# ansible-playbook test.yml #檢視目錄,執行得不到想要的結果 [root@m01 ~]# vim test.yml - hosts: web01 tasks: - name: List Dir /tmp shell: "ls -l /tmp" #使用變數註冊獲取想要的結果 [root@m01 ~]# vim test.yml - hosts: web01 tasks: - name: List Dir /tmp shell: "ls -l /tmp" register: list_dir - name: Get list_dir debug: msg: "{{ list_dir }}" #只輸出我們想要的內容 - hosts: web01 tasks: - name: List Dir /tmp shell: "ls -l /tmp" register: list_dir - name: Get list_dir debug: msg: "{{ list_dir.stdout_lines }}" #msg: "{{ list_dir['stdout_lines'] }}" #官方寫法也可以
[root@m01 ~]# vim status.yml - hosts: web01 tasks: - name: Install Httpd Server yum: name: httpd - name: Check httpd Status shell: systemctl is-active httpd ignore_errors: yes #忽略報錯(如果不寫,返回錯誤就結束了,不會往下走) register: check_httpd - name: Http Restart #返回啟動,就重啟 systemd: name: httpd state: restarted when: check_httpd.rc == 0 - name: Http Start #返回異常,就啟動 systemc: name: httpd state: started when: check_httpd.rc != 0
Ansible facts是在被管理主機上透過Ansible自動採集發現的變數。facts包含每臺特定的主機資訊。比如:
被控端的主機名、IP地址、系統版本、CPU數量、記憶體狀態、磁碟狀態等等。
setup模組獲取的資訊都是因為 facts快取
1.透過facts快取檢查CPU,來生成對應的nginx配置檔案 2.透過facts快取檢查主機名,生成不同的zabbix配置檔案 3.透過facts快取檢索物理機的記憶體大小來生成不通的mysql配置檔案 綜上所述的Ansible facts類似於saltstack中的grains對於做自動化的小夥伴是非常有用的。
#如果使用ansible內建變數的話,不能關閉facts快取 [root@m01 base]# vim mkdir.yml - hosts: nfs_client gather_facts: false #跳過gather_facts步驟,速度變快,但是無法獲取內建變數 tasks: - name: Create Backup DIR file: path: /tmp/{{ ansible_fqdn }} state: directory [root@m01 base]# ansible-playbook mkdir.yml #報錯,無法獲取ansible_fqdn變數 #如果不使用ansible內建變數的話,關閉facts會提高ansible管理其他機器的速度 [root@m01 base]# vim mkdir.yml - hosts: nfs_client gather_facts: false #跳過gather_facts步驟,速度變快,但是無法獲取內建變數 tasks: - name: Create Backup DIR file: path: /tmp/{{ web_server }} state: directory
[root@m01 base]# vim redis.yml bind {{ ansible_default_ipv4['address'] }} [root@m01 base]# vim conf.yml - hosts: all tasks: - name: Config Redis Conf template: #識別內建變數要用template模組,copy模組無法識別 src: ./redis.conf dest: /tmp/ #遠端檢視 [root@web01 tmp]# cat redis.conf bind 10.0.0.7