ansible自动化运维(3)

本文详细介绍了如何在Ansible中管理变量和事实。内容包括变量的定义、命名规则、范围级别以及如何在playbook中使用变量。此外,还讲解了如何通过命令行覆盖变量、使用数组作为变量以及注册变量捕获命令输出。文章进一步探讨了Ansible Vault加密敏感数据的方法,并提供了管理事实的实践,包括查看和自定义事实,以及利用魔法变量在playbook中灵活运用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

4.管理变量和事实
将playbook中的某些值使用变量代替,从而
简化playbook的编写
######管理变量######
#ansible变量简介

变量可能包含下面这些值:
要创建的用户、
要安装的软件包、
要重启的服务、
要删除的文件、
要从互联网检索的文档


#命名变量

变量名称必须以字母开头,并且只能含有字母、数字和下划线
错误                  正确
web server     web_server
westos.file     remote_file

1stfile              file1

#定义变量

三个范围级别
全局范围:从命令行或ansible配置设置的变量
play范围:在play和相关结构中设置的变量
主机范围:由清单、事实收集或注册的任务,在主机组和个别主机上设置的变量
注意:如果多个级别上定义了相同名称的变量,优先采用级别最高的变量,窄范围优先于广范围

playbook中的变量
#在playbook中定义变量
1.常见方式:在playbook开头的vars块中:

- host: all
  vars:
    user: student
    home: /home/student

2.在外部文件定义playbook变量

- hosts: all
  vars_files:
    - vars/users.yml
在users.yml文件中写入
user: student
home: /home/student
#在playbook中使用变量
将变量名称放在花括号内即可
vars:
  user: westos
tasks:
  - name: Create user {{ user }}
    user:
      name: "{{ user }}"
'注意:当变量用作开始一个值的第一元素时,必须使用引号,否则会报错'

#主机变量和组变量

直接应用于主机的清单变量分为两大类:

1.主机变量:应用于特定主机
2.组变量:应用于一个主机组或一组主机组中的所有主机
主机变量优先于组变量,但是playbook中定义的变量比这两者更高

定义主机变量和组变量:
---方法一(比较旧,不建议采用):

定义server1.example.com的ansible_user主机变量:
[webservers]
server1.example.com ansible_user=student
定义dbservers主机组的user组变量:
[dbserver]
dbserver1.example.com
dbserver2.example.com
[dbservers:vars]
user=student
定义嵌套组user变量:
[servers1]
node1.example.com
node2.example.com

[servers2]
node3.example.com
node4.example.com
[servers:children]
servers1
servers2
[servers:vars]
user=student

注意:这种做法使的清单文件难以处理,在同一文件中混合提供主机和变量信息,语法也过时
---方法二:使用目录填充主机和组变量

定义主机和主机组变量的首选做法时与清单文件或目录相同的工作目录中,创建group_vars
和host_vars两个目录,这两个目录分别包含用于定义组变量和主机变量的文件
创建group_vars/servers的YAML文件,设置变量为值:
user:student
同样需要在host_vars目录中创建名称与主机匹配的文件来存放主机变量
所以一个项目目录中包含:
ansible.cfg、group_vars、host_vars、inventory、playbook.yml
#从命令行覆盖变量
清单变量可以被playbook中设置的变量覆盖
两者又可通过命令行参数覆盖
#使用数组作为变量

users:
  lilei:
    first_name: lei
    last_name: li
    home_dir: /home/lilei
  hanmeimei:
    first_name: meimei
    last_name: han
    home_dir: /home/hanmeimei

访问:

users.lilei.first_name
users.hanmeimei.home_dir

变量被定义为python字典,可以使用替代语法:

users['lilei']['first_name']

users['hanmeimei']['home_dir']

#使用已注册变量捕获命令输出
管理员可以使用register语句捕获命令输出

[root@workstationdeploy-adhoc]#catplaybook.yml

---
- name: Install a packages
  hosts: all
  tasks:
    - name: Install
      yum:
        name: httpd
        state: installed
      register: install_result
    - debug: var=install_result
... 

[root@workstationdeploy-adhoc]#ansible-playbook playbook.yml

TASK[debug]*******************************************************************
ok:[servera.lab.example.com]=>{
"install_result":{
"changed":false,
"failed":false,
"msg":"Nothingtodo",
"rc":0,
"results":[
"Installed:httpd"
]
}
}
PLAYRECAP*********************************************************************
servera.lab.example.com:ok=3changed=0unreachable=0
failed=0skipped=0rescued=0ignored=0

##管理变量的练习
创建playbook,来安装apache并开启,使可被访问,playbook查询web服务器并确认它
已经设置好并在运行

web_pkg                  #要安装的web服务器软件包
firewall_pkg             #要安装的防火墙软件包
web_service            #要管理的web服务
firewall_service       #要管理的防火墙服务
python_pkg             #uri模块所需软件包
rule                          #要打开的服务

[root@workstation~]#mkdir data-variables
[root@workstationdata-variables]#cat ansible.cfg

[defaults]
inventory=inventory

[root@workstationdata-variables]#cat inventory

[webservers]
servera.lab.example.com

[root@workstationdata-variables]#cat playbook.yml

---
- name: Deploy and start Apache service
  hosts: webservers
  vars:
    web_pkg: httpd
    firewall_pkg: firewalld
    web_service: httpd
    firewall_service: firewalld
    python_pkg: python3-PyMySQL
    rule: http
#确保安装软件包且是最新的
  tasks:
    - name: Required packages are installed and latest
      yum:
        name:
          - "{{ web_pkg }}"
          - "{{ firewall_pkg }}"
          - "{{ python_pkg }}"
        state: latest
#确保firewalld和apache开机启动
    - name: The {{ firewall_service }} service is started and enabled
      service:
        name: "{{ firewall_service }}"
        enabled: true
        state: started
    - name: The {{ web_service }} service is started and enabled
      service:
        name: "{{ web_service }}"
        enabled: true
        state: started
#配置默认发布页面
    - name: Webcontent is inplace
      copy:
        content: "HelloWestos!"
        dest: /var/www/html/index.html
#使防火墙允许http
    - name: The firewall port for {{ rule }} is open
      firewalld:
        service: "{{ rule }}"
        permanent: true
        immediate: true
        state: enabled

#验证apache服务
- name: Verify the Apache service
  hosts: localhost
  become: false       #在本机测试,不必更改身份
  tasks:
    - name: Ensure the webserver is reachable
      uri:
        url: http://servera.lab.example.com
        status_code: 200

#检测语法
[root@workstationdata-variables]#ansible-playbook --syntax-check playbook.yml
playbook:playbook.yml
#运行
[root@workstationdata-variables]#ansible-playbook playbook.yml

PLAY[DeployandstartApacheservice]*****************************************
...
PLAYRECAP*********************************************************************
localhost:ok=2changed=0unreachable=0failed=0
skipped=0rescued=0ignored=0
servera.lab.example.com:ok=6changed=4unreachable=0
failed=0skipped=0rescued=0ignored=0

5. 管理机密
##目标:使用ansible-vault加密敏感变量,并运行vault加密变量文件的playbook
##介绍ansible-vault

ansible可能需要访问密码或者api密钥等敏感数据,以便配置主机。
加密解密工具:ansible-vault命令
注意:ansible-vault不实施自有的加密函数,而使用外部python工具集

##创建加密文件
方法:ansible-vault create filename
##创建加密文件
[root@workstationdemo]#ansible-vault create secret.yml
需要输入密码
##创建加密文件同时将密码保存,westos文件中必须先写入密码
[root@workstationdemo]#ansible-vault create --vault-password-file=westos
secret.yml

##查看加密文件
方法:ansible-vault view filename
[root@workstationdemo]#ansible-vault view westos.yml
Vaultpassword:
awd
##编辑现有的加密文件

原理:将文件解密为一个临时文件,并编辑;保存时,复制内容并删除临时文件
'edit命令始终重写文件,因此只有在更改文件时使用,查看尽量使用view'

##加密现有的文件
方法:ansible-vault encrypt filename     #filename参数可以是多个

[root@workstationdemo]#ansible-vault encrypt site.yml webserver.yml
New Vault password: redhat
Confirm New Vault password: redhat
Encryption successful

'可以使用--output=filename将加密文件保存为新的名称,使用此参数时输入文件只能是一个'
##解密现有的文件
方法:ansible-vault decrypt filename

[root@workstationwsp]#ansible-vault decrypt westos.yml --output=redhat.yml
#解密的同时改名
Vault password:
Decryption successful
[root@workstationwsp]#ansible-vault decrypt westos.yml    #也可以不改
Vault password:
Decryption successful

##更改加密文件密码
方法:ansible-vault rekey filename
'可以一次更新多个文件密码'

[root@workstationwsp]#ansible-vault rekey westos.yml
Vault password:
New Vault password:
Confirm New Vault password:
Rekey successful

#使用vault密码文件时,最好使用--net-vault-password-file

[root@workstationwsp]#ansible-vault rekey --new-vault-password-file=wsp
westos.yml
Vault password:
Rekey successful
##playbook和ansiblevault

#运行加密的playbook,没有密码则报错

[root@workstationwsp]#ansible-playbook user.yml
ERROR! Attempting to decrypt but no vault secrets found

#交互式提供密码

[root@workstationwsp]#ansible-playbook --vault-id @prompt user.yml
Vault password (default):
...
PLAYRECAP*********************************************************************
servera.lab.example.com : ok=2 changed=0 unreachable=0
failed=0 skipped=0 rescued=0 ignored=0

'2.4之前的ansible,使用--ask-vault-pass提供交互式密码'
#也可以将秘密存在文件中(注意使用文件系统权限对文件进行保护)

[root@workstationwsp]#ansible-playbook --vault-password-file=password
user.yml


6. 管理事实

事实包括:主机名称、内核版本、网络借口、IP地址等

##描述ansible事实
#查看主机信息

[root@workstationwsp]#cat fact.yml
---
- name: Fact dump
  hosts: all
  tasks:
    - name: Print all facts
      debug:
        var: ansible_facts  #系统变量名
[root@workstationwsp]#ansible-playbook fact.yml
PLAY[Factdump]***************************************************************
TASK[GatheringFacts]*********************************************************
ok:[serverb.lab.example.com]
ok:[servera.lab.example.com]

TASK[Printallfacts]*********************************************************
ok:[servera.lab.example.com]=>{
"ansible_facts":{
"_facts_gathered":true,
"all_ipv4_addresses":[
"172.25.254.10"
],
...

#再将事实替换为动态的值
[root@workstationwsp]#cat fact.yml

---
 - name: Fact dump
   hosts: all
   tasks:
     - name: Print all facts
       debug:
       var: ansible_facts
- hosts: all
  tasks:
    - name: Print ansible facts
      debug:
        msg:
          The IPv4 address of {{ ansible_facts.fqdn }}   #使用字典的方式查询值
          is {{ ansible_facts.all_ipv4_addresses }}
##ansible事实作为变量注入 
#使用setup模块显示所有事实信息

[root@workstation~]#ansible servera.lab.example.com -m setup
#关闭事实收集,开提升执行速度
[root@workstation~]#cat user.yml

---
- name: Configure User
  hosts: servera.lab.example.com
  gather_facts:no
  tasks:
    - name: Student User
      user:
        name: student
        uid: 1000
        state: present
...

#运行

[root@workstation~]#ansible-playbook user.yml
PLAY[ConfigureUser]**********************************************************
TASK[StudentUser]************************************************************
ok:[servera.lab.example.com]

PLAYRECAP*********************************************************************
servera.lab.example.com:ok=1changed=0unreachable=0
failed=0skipped=0rescued=0ignored=0

##创建自定义事实
#可以使用INI格式或者JSON格式
#INI格式

[packages]
web_package=httpd
db_package=mariadb-server
[users]
user1=westos
user2=redhat

#JSON格式

{
  "packages": {
     "web_package": "httpd",
     "db_package": "mariadb-server"
  },
  "users": {
      "user1": "westos",
      "user2": "redhat"
  }
}

'自定义格式不能使用ymal格式,使用最为接近的json最好'
[root@workstation~]#mkdir /etc/ansible/facts.d
[root@workstationfacts.d]#vim custom.fact        #必须以.fact结尾

{
  "packages": {
    "web_package": "httpd",
    "db_package": "mariadb-server"
  },
  "users":{
    "user1": "westos",
    "user2": "redhat"
  }
}

[root@workstationfacts.d]#ansible localhost -m setup

...
"ansible_local":{
"custom":{
"packages":{
"db_package":"mariadb-server",
"web_package":"httpd"
},
"users":{

"user1":"westos",
"user2":"redhat"
}
}
},
...
'

自定义事实的使用方式和默认事实相同
##使用魔法变量
常用的有四个:

hostvars#包含受管主机的变量,可以用于获取另一台受管主机的变量的值
group_names#列出当前受管主机所属的所有组
groups#列出清单中的所有组和主机
inventory_hostname#包含清单中配置的当前受管主机的主机名称

#用途之一:使用debug模块报告特定主机的hostvars的值
[root@workstation~]#ansible localhost -m debug -a 'var=hostvars["servera.lab.example.com"]'
##管理事实:练习1
[root@workstation~]#mkdir data-facts
[root@workstationdata-facts]#cat ansible.cfg

[defaults]
inventory=./inventory

[root@workstationdata-facts]#cat inventory

[webservers]
servera.lab.example.com
serverb.lab.example.com

[root@workstationdata-facts]#ansible webservers -m setup     #显示信息
创建自定义变量
[root@workstationdata-facts]#vim custom.fact
[root@workstationdata-facts]#cat custom.fact

[westos]
package = httpd
service = httpd
state = started
enabled = true

创建playbook
[root@workstationdata-facts]#vimfacts.yml

---
- name: Install facts
  hosts :webservers
  vars:

    remote_dir: /etc/ansible/facts.d
    facts_file: custom.fact
  tasks:
    - name: Create directory
      file:
        state: directory
        recurse: yes
        path: "{{ remote_dir }}"
    - name: Install new facts
      copy:
        src: "{{ facts_file }}"
        dest: "{{ remote_dir }}"

'使用刚才的变量'
检测ansible_local变量,当前应该是没有的
[root@workstationdata-facts]#ansible webservers -m setup
...
"ansible_local":{},
...
语法检测

[root@workstationdata-facts]#ansible-playbook --syntax-check facts.yml
playbook:facts.yml

运行
[root@workstationdata-facts]#ansible-playbook facts.yml
编写主playbook
[root@workstationdata-facts]#cat playbook.yml

---
- name: Install Apache and starts
  hosts: webservers
  tasks:
    - name: Install Packages   #安装httpd
      yum:
        name: "{{ ansible_facts['ansible_local']['custom']['westos']['package'] }}"
        state: latest
    - name: Start httpd   #启动
      service:
        name: "{{ ansible_facts['ansible_local']['custom']['westos']['service'] }}"
        state:"{{ansible_facts['ansible_local']['custom']['westos']['state'] }}"
        enabled: "{{ ansible_facts['ansible_local']['custom']['westos']['enabled'] }}"

#验证httpd服务没有在servera上运行

[root@workstationdata-facts]#ansible servera.lab.example.com -m command -a 'systemctl status httpd'
servera.lab.example.com|FAILED|rc=4>>
Unithttpd.servicecouldnotbefound.non-zeroreturncode

#语法检测

[root@workstationdata-facts]#ansible-playbook --syntax-check playbook.yml
playbook:playbook.yml
#运行
[root@workstationdata-facts]#ansible-playbook playbook.yml
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值