Ansible | 学习笔记
🌈安装配置 Ansible
🌟安装 Ansible 引擎
🔹yum
$ sudo yum -y install epel-release
$ sudo yum -y install ansible
🔹apt
$ sudo apt-get istall software-properties-common
$ sudo apt-add-repository ppa:ansible/ansible
$ sudo apt-get update
$ sudo apt-get install ansible
🔹Homebrew
$ brew update
$ brew install Ansible
🔹pip
$ sudo easy_install pip
$ sudo pip install absible
🌈Ansible 示例
🔶~/.vimrc
autocmd FileType yaml setlocal ai ts=2 sw=2 et
🔶Ad-Hoc example
ansible pattern [-i inventory] -m module -a argument
🔶Playbook example:
---
- name: Enable intranet services
hosts: servera.lab.example.com
become: yes
tasks:
- name: latest version of httpd and firewalld installed
yum:
name:
- httpd
- firewalld
state: latest
- name: test html page is installed
copy:
content: "welcome to the example.com intranet!\n"
dest: /var/www/html/index.html
- name: firewalld enabled and running
service:
name: firewalld
enabled: true
state: started
- name: firewalld permits access to httpd service
firewalld:
service: httpd
permanent: true
state: enabled
immediate: yes
- name: httpd enabled and running
service:
name: httpd
enabled: true
state: started
- name: Test intranet web server
hosts: localhost
become: no
uri:
url: http://servera.lab.example.com
return_content: yes
status_code: 200
...
🌈Ansible 变量和事实
🌟全局变量
ansible all -i localhost, -m debug -a "msg='my key is {{ key }}'" -e "key=value"
[admin@CentOS8 ~]$ cat a.json
{"name":"qfedu","type":"school"}
[admin@CentOS8 ~]$ ansible all -i localhost, -m debug -a "msg='name is {{ name }}, type is {{ type }}'" -e @a.json
[admin@CentOS8 ~]$ cat a.yml
---
name: qfedu
type: school
...
[admin@CentOS8 ~]$ ansible all -i localhost, -m debug -a "msg='name is {{ name }}, type is {{ type }}'" -e @a.yml
🌟剧本变量
🔶通过PLAY 属性 vars 定义
---
- name: test play vars
hosts: all
vars:
user: lilei
home: /home/lilei
🔶通过PLAY 属性 vars_fifiles 定义
---
- name: test play vars
hosts: all
vars_files:
- vars/users.yml
# cat vars/users.yml
---
user: lilei
home: /home/lilei
🔶如何在PlayBook中使⽤这些变量
---
- name: test play vars
hosts: all
vars:
user: lilei
home: /home/lilei
tasks:
- name: create the user {{ user }}
user:
name: "{{ user }}"
home: "{{ home }}"
当变量用作一个值的第一个元素时必须使用引号,这可以防止 Ansible 将变量引用视为 YAML 字典的开头。
🌟资产变量
🔶主机变量
[admin@CentOS8 ~]$ cat hostsandhostvars
[webservers]
172.18.0.3 user=lilei port=3309
172.18.0.4
// 获取定义的变量值
[admin@CentOS8 ~]$ ansible 172.18.0.3 -i hostsandhostvars -m debug -a "msg='{{user}} {{port}}'"
172.18.0.3 | SUCCESS => {
"user": "lilei"
}
🔶主机组变量
[admin@CentOS8 ~]$ cat hostsandgroupvars
[webservers]
172.18.0.3 user=lilei
172.18.0.4
[webservers:vars]
home="/home/lilei"
[admin@CentOS8 ~]$ ansible webservers -i hostsandgroupvars -m debug -a "var=home"
172.18.0.3 | SUCCESS => {
"home": "/home/lilei"
}
172.18.0.4 | SUCCESS => {
"home": "/home/lilei"
}
🔶使用目录填充主机和组变量
定义主机和主机组的变量的首选做法是在与清单文件或目录相同的工作目录中,创建 group_vars 和 host_vars 两个目录。这两个目录分别包含用于定义组变量和主机变量的文件。
建议的做法是使用 host vars 和 group_vars 目录定义清单变量,而不直接在清单文件中定义它们。
project
├── ansible.cfg
├── group_vars
│ ├── datacenters
│ ├── datacenters1
│ └── datacenters2
├── host_vars
│ ├── demo1.example.com
│ ├── demo2.example.com
│ ├── demo3.example.com
│ └── demo4.example.com
├── inventory
└── playbook.yml
🔶Inventory 内置变量的说明
变量 | 说明 |
---|---|
ansible_ssh_host | 远程主机名 |
ansible_ssh_port | ssh 端⼝号 |
ansible_ssh_user | ssh ⽤户名 |
ansible_ssh_pass | ssh 密码 |
ansible_sudo_pass | sudo 密码 |
ansible_sudo_exe | sudo 命令路径 |
ansible_ssh_private_key_file | ssh 使⽤的私钥⽂件 |
ansible_python_interpreter | ⽬标主机的 python 路径 |
🌟事实变量
🔶Ansible 事实的示例
事实 | 变量 |
---|---|
短主机名 | ansible_facts.hostname |
完全限定的域名 | ansible_facts.fqdn |
主要IPv4地址 | ansible_facts.deafult_ipv4.address |
所有网络接口的名称列表 | ansible_facts.interfaces |
/dev/vda1分区的大小 | ansible_facts.devices.vda.partitions.vda1.size |
DNS服务器列表 | ansible_facts.dns.nameservers |
当前运行的内核的版本 | ansible_facts.kernel |
🔶⼿动收集 Facts 变量
[admin@CentOS8 ~]$ ansible all -i localhost, -c local -m setup
🔶过滤 Facts
[admin@CentOS8 ~]$ ansible all -i localhost, -m setup -a "filter=*mount*" -c local
[admin@CentOS8 ~]$ ansible all -i localhost, -m setup -a "filter=*memory*" -c local
🔶在PlayBook中使⽤ Facts 变量
---
- name: print facts variable
hosts: all
tasks:
- name: print facts variable
debug:
msg: "The default IPV4 address is {{ ansible_facts.default_ipv4.address }}"
🔶在PlayBook中关闭 Facts 变量的获取
---
- name: a play example
hosts: webservers
gather_facts: no
remote_user: root
tasks:
- name: install nginx package
yum: name=nginx state=present
- name: copy nginx.conf to remote server
copy: src=nginx.conf dest=/etc/nginx/nginx.conf
- name: start nginx server
service:
name: nginx
enabled: true
state: started
🔶创建自定义事实
/etc/ansible/facts.d/*.fact
[packages]
web_package = httpd
db_package = mariadb-server
[users]
user1 = joe
user2 = jane
🔶使用魔法变量
一些变量并非事实或通过setup模块配置,但也由Ansible自动设置。这些魔法变量也可用于获取与特定受管主机相关的信息。最常用的有四个:
hostvars
:包含受管主机的变量,可以用于获取另一台受管主机的变量的值。如果还没有为受管主机收集事实,则它不会包含该主机的事实。group_names
:列出当前受管主机所属的所有组。groups
:列出清单中所有的组和主机。inventory_hostname
:包含清单中配置的当前受管主机的主机名称,这可能由于各种原因而与事实报告的主机名称不同。
🌟注册变量
---
- name: install a package and print the result
hosts: webservers
remote_user: root
tasks:
- name: install nginx package
yum: name=nginx state=present
register: install_result
- name: print result
debug: var=install_result
当⼀个变量同时在全局变量、剧本变量和资产变量中定义时,优先级最⾼的是全局变量;其次是剧本变量;最后才是资产变量。
🌟通过终端写入变量
---
- hosts: testB
remote_user: root
vars_prompt:
- name: "your_name"
prompt: "What is your name"
private: no
- name: "your_age"
prompt: "How old are you"
private: no
tasks:
- name: output vars
debug:
msg: Your name is {{your_name}},You are {{your_age}} years old.
🌟使用数组作为变量
除了将同—元素相关的配置数据分配到多个变量外,管理员也可以使用数组。这种做法的好处在于, 数组是可以浏览的。
users:
bjones:
first_name: Bob
last_name: Jones
home_dir: /users/bjones
acook:
first_name: Anne
last_name: Cook
home_dir: /users/acook
然后,您可以使用以下变量来访问用户数据:
# Returns 'Bob'
users.bjones.first_name
# Returns '/users/acook'
users.acook.home_dir
🌟使用机密加密变量
#创建加密的文件
[admin@CentOS8 ~]$ ansible-vault create secret.yml
[admin@CentOS8 ~]$ ansible-vault create --vault-password-file=vault-pass secret.yml
#查看加密的文件
[admin@CentOS8 ~]$ ansible-vault view secret.yml
#编辑现有的加密文件
[admin@CentOS8 ~]$ ansible-vault edit secret.yml
#加密现有的文件
[admin@CentOS8 ~]$ ansible-vault encrypt secret.yml
#解密现有的文件
[admin@CentOS8 ~]$ ansible-vault decrypt secret.yml
#更改加密文件的密码
[admin@CentOS8 ~]$ ansible-vault rekey secret.yml
[admin@CentOS8 ~]$ ansible-vault rekey --new-vault-password-file=NEW-pass secret.yml
#以交互模式向 Playbook 提供 Vault 密码
[admin@CentOS8 ~]$ ansible-playbook --vault-id @prompt site.yml
#指定纯文本加密文件向 Playbook 提供 Vault 密码
[admin@CentOS8 ~]$ ansible-playbook --vault-password-file=vault-pw site.yml
#您也可以使用 ANSIBLE_VAULT_PASSWORD_FILE 环境变量,指定密码文件的默认位置。
🌟变量文件管理的推荐做法
.
├── ansible.cfg
├── group_vars
│ └── webservers
│ └── vars
├── host_vars
│ └── demo.example.com
│ ├── vars
│ └── vault
├── inventory
└── playbook.yml
🌈Ansible 条件与循环
# ansible-playbook -i hosts site.yml -t updateconfig
- name: playbook example
hosts: webservers
gather_facts: no
vars:
createuser:
- tomcat
- www
- mysql
tasks:
- name: create user
user: name={{ item }} state=present
loop: "{{ createuser }}"
# with_items: "{{ createuser }}"
- name: yum ngix webserver
yum: name=nginx state=present
- name: update nginx main config
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
tags: updateconfig
notify: reload nginx server
- name: add virtualhost config
copy: src=www.qfedu.com.conf dest=/etc/nginx/conf.d/
tags: updateconfig
notify: reload nginx server
- name: check nginx syntax
shell: /usr/sbin/nginx -t
register: nginxsyntax
tags: updateconfig
- name: check nginx running
stat: path=/var/run/nginx.pid
register: nginxrunning
tags: updateconfig
- name: start nginx server
service: name=nginx state=started
when:
- nginxsyntax.rc == 0
- nginxrunning.stat.exists == false
handlers:
- name: reload nginx server
service: name=nginx state=reloaded
when:
- nginxsyntax.rc == 0
- nginxrunning.stat.exists == true
🌈Ansible 管理大项目
.
├── ansible.cfg
├── filter_plugins #自定义过滤插件(插件)
├── inventory
│ ├── aliyun.yml
│ ├── dynamic-inventory.py
│ ├── group_vars
│ │ ├── all.yml
│ │ ├── datacenters
│ │ ├── datacenters1
│ │ └── datacenters2
│ ├── host_vars
│ │ ├── all.yml
│ │ ├── demo1.example.com
│ │ ├── demo2.example.com
│ │ ├── demo3.example.com
│ │ └── demo4.example.com
│ └── static-inventory
├── library #自定义模块(可选)
├── playbook.yml
└── roles #角色目录
🌈Ansible 角色Roles
🌟角色的目录结构
[student@bastion ansible]$ tree role.example
.
├── defaults #角色变量的默认值,优先级低,应在play中更改和自定义
│ └── main.yml
├── files #包含由角色引用的静态文件
├── handlers #包含角色的处理程序定义
│ └── main.yml
├── meta #包含角色的相关信息,如作者、平台和可选的角色依赖项等
│ └── main.yml
├── README.md
├── tasks #包含角色的任务定义
│ └── main.yml
├── templates #包含由角色引用的Jinja2模板
├── tests #包含test.yml,用于测试角色
│ ├── inventory
│ └── test.yml
└── vars #包含角色的变量值,优先级高,在play中不应更改
└── main.yml
参考资料
- CL82@CSDN
- 《RH294》
- 《千峰Linux_Ansible讲义》