1:notify语法;
--- ###定义此文件为yaml文件
- hosts: all ###playbook所针对的主机
tasks: ###playbook所定义的tasks集合
- name: install base server ##task的名字可自己定义
yum: name=vim,httpd s
state=installed ###所调用的模块
- name: copy the config.conf
copy: src=/root/http.conf dest=/etc/httpd/conf/http.conf
notify: ###触发handlers,如果拷贝的文件的md5值发生变化,就会触发 restart the httpd service这个handlers
- restart the httpd service
# - name: start the httpd service
# service: name=httpd state=started enabled=yes
handlers: ###定义一个handlers让 httpd服务重启。
- name: restart the httpd service
service: name=httpd state=restarted
2:调用某个yaml文件
使用
- import_playbook : base.yml
- include: base.yml 两种方式都可以
3:ansible roles基本语法结构
roles这个词:一个分类,将mysql、php等分为各自的大组,在各个角色内定义具体的小任务,方便管理,另一方面,类似于php的类的自动加载,roles基于一个已知的文件结构,可以自动去加载某些vars_files、tasks、handlers等。
一个项目的组成如下:
site.yml
webservers.yml
fooservers.yml
roles/
common/ # 一个角色包含了一个playbook的基本参数
files/
templates/ # 模板
tasks/ # 任务
handlers/ # 触发任务
vars/ # 变量
defaults/
meta/
webservers/
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
roles内各目录含义解释:
files:用来存放由copy模块或script模块调用的文件。
templates:用来存放jinjia2模板,template模块会自动在此目录中寻找jinjia2模板文件。
tasks:此目录应当包含一个main.yml文件,用于定义此角色的任务列表,此文件可以使用include包含其它的位于此目录的task文件。
handlers:此目录应当包含一个main.yml文件,用于定义此角色中触发条件时执行的动作。
vars:此目录应当包含一个main.yml文件,用于定义此角色用到的变量。
defaults:此目录应当包含一个main.yml文件,用于为当前角色设定默认变量。
meta:此目录应当包含一个main.yml文件,用于定义此角色的特殊设定及其依赖关系。
4:基础语法
---
- hosts: all
gather_facts: no/false ###设置为no或者false,否者会出现Gathering Facts卡住的问题
remote_user; root ###远程认证用户
sudo: yes ###设置sudo操作
sudo_user: yaadmin ###执行sudo操作的用户
vars: ####设置playbook变量
nginx_port: 80
vars_file: ####设置playbook的变量调用文件
- "var.yaml"
- [ "one.yaml" , "two.yaml" ]
vars_prompt: ###通过交互式输出变量
- name: "password vaes"
prompt: "Ether password" ###使用prompt模块加密输出变量
default: "secret"
private: yes
encrypt: "md5_crypt"
confirm: yes
salt: 1234
salt_size: 8
pre_tasks: ###运行playbook之前的‘tasks’
- name: pre-tasks
shell; hostname
roles: ####设置引入role
- docker
- { role: docker, version; '1.5.0', when: "ansible_system == 'Linux'", tags: [docker,install] }
- { role: docker, version; '1.5.0', when: "ansible_all_ipv4_addresses == '192.168.124.129' }
tasks: ####设置运行tasks
- include: tasks.yaml
- include: tasks.yaml ansible_distribution='Centos7' ansible_distribution_version='6.6'
- { include: tasks.yaml. version: '1.1', package: [nginx,httpd]}
- include: tasks_192.168.124.129.yaml
when: ansible_all_ipv4_addresses == '192.168.124.129'
post_tasks: ###设置playbook运行之后的tasks
- name: post_tasks
shell: hostname
handlers: ##设置playbook的handlers
- include: handlers.yaml
5:变量的调用
变量优先级:
1、extra vars(命令中-e)最优先
2、inventory 主机清单中连接变量(ansible_ssh_user 等)
3、play 中 vars、vars_files 等
4、剩余的在 inventory 中定义的变量
5、系统的 facts 变量
6、角色定义的默认变量(roles/rolesname/defaults/main.yml)
注:子组会覆盖父组,主机总是覆盖组定义的变量
命令行指定-e
ansible-playbook -i hosts site-1.yml -e "key=123456"
命令行-e指定yaml文件,yaml文件中定义变量
ansible-playbook -i hosts site-1.yml -e @value.yml
yaml文件中使用vars_files参数指定文件,如下:
---
- hosts: all
gather_facts: no
vars_files: #####
- value.yml #####
roles:
- value
- httpd
6:tag的使用方法
---
- hosts: all
roles:
- value ###输出的role。
- httpd
- install-package
tags: ##使用tag模块定义
- os ###定义的tag名称
- ansible
tags:
- ansible
使用方法:
ansible-playbook -i hosts site-1.yml -t ansible
7:抓取ip地址配置hosts文件
---
- hosts: all
vars:
IP: "{{ ansible_ens34['ipv4']['address'] }}"
tasks:
- name: backup the hosts
shell: mv /etc/hosts /etc/hosts_bak
ignore_errors: yes ###当前任务失败时,可以继续跑下面的playbook,不会造成中断
- name: copy hosts file to other servers
copy: src=/root/hosts dest=/etc/ owner=root group=root mode=0644
- name: config ip hostname
lineinfile: dest=/etc/hosts line="{{ IP }} {{ ansible_hostname }}"
以上变量调用的是facts搜集的主机信息
需要在ansible.cfg添加如下配置:
[defaults]
inventory = /etc/ansible/hosts ###主机清单文件
host_key_checking = False ##不检查秘钥
gathering = smart ###缓存方式
fact_caching = yaml ###缓存方式
fact_caching_connection = /tmp/ansible_fact_cache ###facts缓存路径
fact_caching_timeout = 300
forks=50
retry_files_enabled = False
callback_whitelist = profile_tasks
[ssh_connection]
pipelining = True
8:批量修改主机名
---
- hosts: all
tasks:
- name: show hostname
shell: hostname
- name: show ip
command: ip a
- hostname: name=web{{ ansible_default_ipv4.address.split('.')[-1] }}
9:网络地址查询
ipaddr使用方法:(需要先安装pip install netaddr)
定义变量:
net_mask: "{{ ansible_default_ipv4.address }}/{{ ansible_default_ipv4.netmask }}"
192.168.124.129/255.255.255
编辑filter.yml文件
---
- hosts: all
vars:
list: "{{ ansible_all_ipv6_addresses }}"
net_mask: "{{ ansible_default_ipv4.address }}/{{ ansible_default_ipv4.netmask }}"
tasks:
- name: debug the min or max
# debug: msg="{{ info | ipaddr('address') | ipwrap }}"
debug: msg="{{ net_mask | ipaddr('prefix') }}"
输出结果为:“24”
ipaddr则直接输出192.168.124.129/24
ipaddr('network')输出结果为:192.168.124.0
ipaddr('network/prefix')输出结果为:192.168.124.0/24
ipaddr('host')输出结果为:192.168.124.129/24
ipwrap:如果调用的是v4地址正常显示,v6地址则以[]显示
ipaddr('10')输出结果为:192.168.124.10/24,显示第十个地址
ipmath(19)输出结果为:192.168.124.29,当前地址+19
其他参数查询:https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters_ipaddr.html
10:主机路由
delegate_to:将当前任务放在其他hosts上执行
##这是一段在容器中执行的playbook的一部分,这时候需要检测容器所在的宿主机上的对
应目录是否存在,这时候就需要用到委托来跳出当前容器到宿主机上执行当前任务
- name: Ensure mount directories exists
file:
path: "{{ item['mount_path'] }}"
state: "directory"
with_items:
- "{{ lxc_default_bind_mounts | default([]) }}"
- "{{ list_of_bind_mounts | default([]) }}"
delegate_to: "{{ physical_host }}" ##如果在本地可以使用localhost
when:
- not is_metal | bool
tags:
- common-lxc
local_action: 将任务放在ansible控制主机(运行ansible-playbook的主机)上执行
- name: Check if the git cache exists on deployment host
local_action:
module: stat
path: "{{ repo_build_git_cache }}"
register: _local_git_cache
when: repo_build_git_cache is defined
11:playbook启动容器
- name: install os-net-config container
docker_container: ###调用docker_container模块
name: os-net-config
privileged: true ###容器的执行权限
network_mode: host ##网路模式
image: "{{ os_net_config_image_full }}" ##镜像
volumes: ###映射的目录
- "/etc/passwd:/etc/passwd:ro"
- "/etc/os-net-config/:/etc/os-net-config/"
- "/etc/driverctl.d:/etc/driverctl.d"
- "/etc/sysconfig/:/etc/sysconfig/:rw"
- "/lib/modules:/lib/modules:ro"
- "/run/:/run/"
- "/sys:/sys"
- "/var/lib/os-net-config:/var/lib/os-net-config"
command: os-net-config ##执行的命令
state: started ##动作
become: true
12:多个tasks合并一起,block
- block:
- shell: rabbitmqctl stop_app
- shell: rabbitmqctl join_cluster rabbit@{{ groups['web'].0 }}
- shell: rabbitmqctl start_app
when: ansible_default_ipv4.address != "{{ groups['web'].0 }}"
注: groups['web'].0表示web主机组中的第一个主机
13:when条件使用
- name: start the mariadb service
service:
name: mariadb
state: started
delegate_to: localhost
when:
- ansible_default_ipv4.address == "{{ groups['all'].0 }}"
- not check_mariadb_file_exists.stat.exists
此处定义check_mariadb_file_exists.stat.exists结果为true,前面加not表示false。
###满足上面两个条件tasks任务才可执行。
14:merge_configs用法
- name: Copying over ceph.conf
vars:
service_name: "{{ item }}"
merge_configs:
sources:
- "{{ role_path }}/templates/ceph.conf.j2"
- "{{ node_custom_config }}/ceph.conf"
- "{{ node_custom_config }}/ceph/{{ inventory_hostname }}/ceph.conf"
dest: "{{ node_config_directory }}/{{ item }}/ceph.conf"
mode: "0660"
become: true
with_items:
- "ceph-mon"
- "ceph-osd"
- "ceph-rgw"
- "ceph-mgr"
- "ceph-mds"
- "ceph-nfs"
merge_configs:将多个文件合并为1个文件,如果文件存在则匹配文件,不存在则忽略。
15:retries/delay
- name: configuring client.admin caps
become: true
kolla_ceph_keyring:
name: client.admin
caps: "{{ ceph_client_admin_keyring_caps }}"
run_once: True
delegate_to: "{{ groups['ceph-mon'][0] }}"
register: result
until: result is success
retries: 3
delay: 15
until:表示判断条件 retries: 重试次数 delay: 每次重试的中间间隔时间
16:判断条件
当判断某个字符是否在一组列表中时,可以通过in or not in来判断
举例如下:
---
- name: get the vms status
os_server_info:
auth:
auth_url: "{{ auth_url }}"
username: "{{ username }}"
password: "{{ password }}"
project_name: "{{ project_name }}"
os_user_domain_name: "{{ os_user_domain_name }}"
os_project_domain_name: "{{ os_project_domain_name }}"
filters:
vm_state: active
register: result
- name: debug result
debug: var=result.openstack_servers
- name: ensure the vms on the host
debug: msg="have the vms on host yet"
with_items:
- "{{ result.openstack_servers}}"
failed_when: '"{{ remove_node }}" in item.host' ###通过in来判断remove_node是否在item.host中
注:判断要删除的节点remove_node是否在列表item.host中。
with_it
17:if else判断语句
类似于shell中的用法,如下:
enable_external: false
networks:
state: "present"
name: "v4"
mtu: "1310"
shared: "yes"
external: "{{ 'yes' if enable_external | bool else 'no' }}"
provider_network_type: "vlan"
provider_physical_network: "physnet1"
provider_segmentation_id: "155"
创建网络时是否启为external网络,通过enable_external:来判断。
- name: create networks for vms
os_network:
auth:
auth_url: "{{ auth_url }}"
username: "{{ username }}"
password: "{{ password }}"
project_name: "{{ project_name }}"
os_user_domain_name: "{{ os_user_domain_name }}"
os_project_domain_name: "{{ os_project_domain_name }}"
name: "{{ item.name }}"
state: "{{ item.state }}"
mtu: "{{ item.mtu }}"
shared: "{{ item.shared }}"
external: "{{ item.external }}"
provider_network_type: "{{ item.provider_network_type }}"
provider_physical_network: "{{ item.provider_physical_network }}"
provider_segmentation_id: "{{ item.provider_segmentation_id }}"
with_items:
- "{{ networks }}"
when: not check_networks_exist.openstack_networks | bool
check_networks_exist.openstack_networks结果为false,前面加not表示为true。
18:忽略不存在的变量
当在多个字典中调用变量时,而字典中的内容不一定完全一致,有的变量不存在,调用变量时
可能会失败,可使用如下方法进行解决:
{{ item.oldVersionId |default('null') }}
当不存在时,可定义为null
19:url过滤器
过滤器「urlsplit」,用于分解一个url链接,取出我们需要的字段:
打印出url中所有可用的值,如下:
debug: msg="{{ "http://172.16.35.15:10080/autoops/spring-data-jpa-audit-extension.git" | urlsplit}}"
ok: [192.168.77.73] => {
"msg": {
"fragment": "",
"hostname": "172.16.35.15",
"netloc": "172.16.35.15:10080",
"password": null,
"path": "/autoops/spring-data-jpa-audit-extension.git",
"port": 10080,
"query": "",
"scheme": "http",
"username": null
}
}
取出hostname的值,如下:
debug: msg={{ "http://172.16.35.15:10080/autoops/spring-data-jpa-audit-extension.git"|urlsplit('hostname') }}
ok: [192.168.77.73] => {
"msg": "172.16.35.15"
}
20:字符串过滤
过滤字符串中的字符,选取需要的内容
- name: debug the file
debug: msg={{ "http://172.16.35.15:10080/autoops/spring-data-jpa-audit-extension.git".split('://')[1] }}
打印内容如下:
ok: [192.168.77.73] => {
"msg": "172.16.35.15:10080/autoops/spring-data-jpa-audit-extension.git"
}
split('://')[1]:将上面链接分成两部分,取右面的值
21:合并两个字典
- name: combine the dirct
set_fact:
var={{ {'a':1, 'b':2}| combine({'c':3}) }}
- name: debug the var
debug: msg="{{ var}}"
##################################################
Friday 14 August 2020 22:46:42 +0800 (0:00:00.068) *******
ok: [192.168.77.73] => {
"msg": {
"a": 1,
"b": 2,
"c": 3
}
}