文章目录
ansible介绍
ansible是一款自动化运维工具,基于python开发,实现了批量系统配置、批量程序部署、批量运行命令等功能。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/20905560e3efdf9a2f0f0f2b1805ca65.jpeg)
Ansible组成
-
Ansible
核心组件,命令执行工具。 -
Inventory
主机,定义被管理的主机清单。 -
Modules
模块,功能模块以及自定义模块。 -
Plugins
插件,模块功能的补充,如连接,过滤。 -
Playbooks
剧本,多任务配置。 -
API
应用编程接口。
环境准备
IP | 系统 | 描述 |
---|---|---|
10.10.10.10 | centos7 | 管理节点 |
10.10.10.11 | centos7 | 被管节点 |
10.10.10.12 | centos7 | 被管节点 |
ansible配置
[defaults]:通用配置项
[inventory]:与主机清单相关的配置项
[privilege_escalation]:特权升级相关的配置项
[paramiko_connection]:使用paramiko连接的相关配置项,Paramiko在RHEL6以及更早的版本中默认使用的ssh连接方式
[ssh_connection]:使用OpenSSH连接的相关配置项,OpenSSH是Ansible在RHEL6之后默认使用的ssh连接方式
[persistent_connection]:持久连接的配置项
[accelerate]:加速模式配置项
[selinux]:selinux相关的配置项
[colors]:ansible命令输出的颜色相关的配置项
[diff]:定义是否在运行时打印diff(变更前与变更后的差异)
[root@localhost ~]# cat /etc/ansible/ansible.cfg
[defaults]
# some basic default values...
#inventory = /etc/ansible/hosts --主机清单
#library = /usr/share/my_modules/ --自定义lib路径
#module_utils = /usr/share/my_module_utils/ --自定义模块路径
#remote_tmp = ~/.ansible/tmp --远程临时文件
#local_tmp = ~/.ansible/tmp --本地临时文件
#ansible执行一个命令会生成python脚本,存放于local_tmp,并复制到remote_tmp,目标主机执行此脚本,执行结束后即删除。
#plugin_filters_cfg = /etc/ansible/plugin_filters.yml --插件配置文件
#forks = 5 --并行进程数
#poll_interval = 15 --轮询时间间隔,多久拉一次数据
#sudo_user = root --切换root允许
#ask_sudo_pass = True --是否询问sudo口令
#ask_pass = True --是否询问用户口令
#transport = smart --连接模式smart
#remote_port = 22 --ssh远程端口
#roles_path = /etc/ansible/roles --roles路径
#host_key_checking = False --主机密钥检查
#sudo_exe = sudo --sudo执行文件
#sudo_flags = -H -S -n --sudo参数
#timeout = 10 --ssh连接超时时常
#remote_user = root --远程连接用户
#log_path = /var/log/ansible.log --日志文件
#module_name = command --默认执行模块
#executable = /bin/sh --默认执行shell
#private_key_file = /path/to/file --私钥文件
#vault_password_file = /path/to/vault_password_file --vault密码文件
[privilege_escalation]
#become=True --启用权限提升
#become_method=sudo --权限提升方法
#become_user=root --权限提升到指定用户
#become_ask_pass=False --是否询问密码
[paramiko_connection]
……省略……
[ssh_connection]
……省略……
[persistent_connection]
……省略……
[accelerate]
……省略……
[selinux]
……省略……
[colors]
……省略……
[diff]
……省略……
ansible命令
ansible
帮助:
[root@localhost ~]# ansible -h
usage: ansible <host-pattern> [options]
host-pattern
ip: 主机地址
ansible 10.10.10.11,10.10.10.12 -m ping
all: 主机清单中所有
ansible all -m ping
组: 特定组
ansible web -m ping #web组中所有主机
ansible web[0] -m ping #web组中第1个主机
ansible web[0,10] -m ping #web组中第1个到第10个主机
ansible .com -m ping #表示所有以.com结尾主机
逻辑与或非
ansible web1:&web2 -m ping #交集,web1和web2中共同主机
ansible web1:web2 -m ping #并集,web1和web2中所有主机
ansible web1:!web2 -m ping #差集,web1中排除web2的主机
options
可选选项:
--list-host:列出host-pattern主机
--playbook-dir BASEDIR:playbook路径,
--syntax-check:检查playbook语法,不执行
--ask-vault-pass:询问vault密码
--vault-id VAULT_IDS:vault密码文件
--vault-password-file VAULT_PASSWORD_FILES:vault密码文件(建议使用vault-id)
--version:版本
-B SECONDS, --background SECONDS:异步超时时间
-C, --check:测试
-D, --diff:当更改文件和模板时,显示这些文件得差异
-M MODULE_PATH, --module-path MODULE_PATH:模块路径
-P POLL_INTERVAL, --poll POLL_INTERVAL:使用-B后设置poll轮询间隔(默认15s)
-a MODULE_ARGS, --args MODULE_ARGS:模块参数
-e EXTRA_VARS, --extra-vars EXTRA_VARS:额外参数
-f FORKS, --forks FORKS:默认进程数(默认5),默认一批管理的主机数
-h, --help:帮助
-i INVENTORY, --inventory INVENTORY, --inventory-file INVENTORY:主机清单文件(默认/etc/ansible/hosts)
-l SUBSET, --limit SUBSET:进一步限制所选主机/组模式,只执行-l 后的主机和组。
-m MODULE_NAME, --module-name MODULE_NAME:执行模块
-o, --one-line:结果输出在一行上
-t TREE, --tree TREE:将日志内容保存在该目录中,文件名以执行主机名命名
-v, --verbose:输出执行的详细信息,使用-vvv获得更多,-vvvv 启用连接调试
权限选项:
--become-method BECOME_METHOD:权限提升方法(默认方法为sudo)
ansible-doc -t become -l:查看方法
--become-user BECOME_USER:以此用户身份运行操作(默认user为root)
-K, --ask-become-pass:BECOME_USER对应的密码
-b, --become:使用become运行操作
连接选项:
--private-key PRIVATE_KEY_FILE, --key-file PRIVATE_KEY_FILE:认证连接的私钥文件
--scp-extra-args SCP_EXTRA_ARGS:传递给scp额外参数,如-l
--sftp-extra-args SFTP_EXTRA_ARGS:传递给sftp额外参数,如-f,-l
--ssh-common-args SSH_COMMON_ARGS:传递给sftp/scp/ssh的公共参数(例如ProxyCommand)
--ssh-extra-args SSH_EXTRA_ARGS:传递给ssh额外参数,如-R
-T TIMEOUT, --timeout TIMEOUT:连接超时时间(默认10s)
-c CONNECTION, --connection CONNECTION:连接类型(默认smart)
local:本地主机
-k, --ask-pass:连接密码
-u REMOTE_USER, --user REMOTE_USER:连接用户
常用格式:
ansible HOST-PATTERN -m MODULE_NAME -a MOD_ARGS -f FORKS -C -u USERNAME
例子:
[root@localhost ~]# ansible all -m ping
10.10.10.12 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
10.10.10.11 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
ansible-doc
帮助:
[root@localhost ~]# ansible-doc -h
Usage: ansible-doc [options]
Options:
-h, --help:获取帮助
-l, --list:列出模块
-s, --snippet:模块帮助
例子:
[root@localhost ~]# ansible-doc -l | grep authorized_key
authorized_key Adds or removes an SSH authorized key
[root@localhost ~]# ansible-doc -s authorized_key
- name: Adds or removes an SSH authorized key
……省略……
ansible-playbook
帮助:
[root@localhost ~]# ansible-playbook --help
Usage: ansible-playbook [options] playbook.yml [playbook2 ...]
Runs Ansible playbooks, executing the defined tasks on the targeted hosts.
Options:
-C, --check:测试
-e EXTRA_VARS, --extra-vars=EXTRA_VARS:给定参数
--flush-cache:清空fack收集的主机信息
-f FORKS, --forks=FORKS:默认进程数(默认5),默认一批管理的主机数
-h, --help:帮助
-i INVENTORY, --inventory=INVENTORY, --inventory-file=INVENTORY:主机清单
--list-hosts:列出所有主机
--list-tags:列出所有标签
--list-tasks:列出所有任务
--skip-tags=SKIP_TAGS:跳过指定的TAGS
--step:一次执行一个TAGS,确认后继续执行
--syntax-check:语法检测
-t TAGS, --tags=TAGS:执行指定的TAGS
Connection Options:
…省略…
Privilege Escalation Options:
…省略…
ansible模块
authorized_key
帮助
[root@localhost ~]# ansible-doc -s authorized_key
- name: Adds or removes an SSH authorized key
authorized_key:
key: #本地公钥(字符串或url)
path: #authorized_keys文件存放的位置(默认:(homedir)+/.ssh/authorized_keys)
state: #present添加,absent删除
user: #远端服务器上的用户(编辑该用户的authorized_keys文件)
……省略……
实例
[root@localhost ~]# ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
……省略……
The key's randomart image is:
+---[RSA 2048]----+
| . =X=*o+ |
| . ..+@.* . |
| . .*+B + |
| . . o.oBoo |
| o + .S+. |
| . + o o |
| . . o. |
| .+.o |
| ++E.. |
+----[SHA256]-----+
[root@localhost ~]# vim /etc/ansible/ansible.cfg
#禁用主机密钥检查,默认启用
host_key_checking = False
[root@localhost ~]# ansible all -m authorized_key -a "user=root key='{{ lookup('file', '/root/.ssh/id_rsa.pub')}}' path='/root/.ssh/authorized_keys'" --ask-pass
SSH password:
10.10.10.11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"comment": null,
"exclusive": false,
"follow": false,
"gid": 0,
"group": "root",
"key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDRJVyJMuzeYecnLtJt002j0QeLsNdfYdoxf9kqbQPbF5CmsR/p6e1Vgj3LH5Y9olR9CRBMWFMDJy9Tfa7QOiw2U09DUi0GGuUq3bsyOb60sM0NEeMlUAq6nR4iwXvofpwtn1hZuK8T/H7d2AdMbsVeK1pO8TAwJb4MIUh1sVUHOPvWHEtm77D77ZDfotJ1hY47T1HFeUOcFaI7LGBw0zPcOqVJIrqzpLiSMXDa0Nksq7Zk5y6AQcr83ndJpdfAtsBRyx1tZFvUqth5PfexUGstC0rlxkgUYrCPgnH3+2y+79FVuGP6eYtNRmRqTQG5AQY3YOz6VNWOh4HBnEK05Ztr root@localhost",
"key_options": null,
"keyfile": "/root/.ssh/authorized_keys",
"manage_dir": true,
"mode": "0600",
"owner": "root",
"path": "/root/.ssh/authorized_keys",
"secontext": "system_u:object_r:ssh_home_t:s0",
"size": 396,
"state": "file",
"uid": 0,
"user": "root",
"validate_certs": true
}
10.10.10.12 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"comment": null,
"exclusive": false,
"follow": false,
"gid": 0,
"group": "root",
"key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDRJVyJMuzeYecnLtJt002j0QeLsNdfYdoxf9kqbQPbF5CmsR/p6e1Vgj3LH5Y9olR9CRBMWFMDJy9Tfa7QOiw2U09DUi0GGuUq3bsyOb60sM0NEeMlUAq6nR4iwXvofpwtn1hZuK8T/H7d2AdMbsVeK1pO8TAwJb4MIUh1sVUHOPvWHEtm77D77ZDfotJ1hY47T1HFeUOcFaI7LGBw0zPcOqVJIrqzpLiSMXDa0Nksq7Zk5y6AQcr83ndJpdfAtsBRyx1tZFvUqth5PfexUGstC0rlxkgUYrCPgnH3+2y+79FVuGP6eYtNRmRqTQG5AQY3YOz6VNWOh4HBnEK05Ztr root@localhost",
"key_options": null,
"keyfile": "/root/.ssh/authorized_keys",
"manage_dir": true,
"mode": "0600",
"owner": "root",
"path": "/root/.ssh/authorized_keys",
"secontext": "system_u:object_r:ssh_home_t:s0",
"size": 396,
"state": "file",
"uid": 0,
"user": "root",
"validate_certs": true
}
command
帮助
[root@localhost ~]# ansible-doc -s command
- name: Execute commands on targets
command:
chdir: #切换到指定目录下执行命令
creates: #如果指定文件存在,不会执行这步操作
free_form: #自由格式需要执行的linux命令,-a定义
removes: #如果指定文件存在,会执行这步操作,与creates相反
实例
[root@localhost ~]# ansible all -m command -a "creates=/root ls /root"
10.10.10.11 | SUCCESS | rc=0 >>
skipped, since /root exists
10.10.10.12 | SUCCESS | rc=0 >>
skipped, since /root exists
[root@localhost ~]# ansible all -m command -a "creates=/root/file ls /root"
10.10.10.11 | CHANGED | rc=0 >>
anaconda-ks.cfg
10.10.10.12 | CHANGED | rc=0 >>
anaconda-ks.cfg
shell
帮助
[root@localhost ~]# ansible-doc -s shell
- name: Execute shell commands on targets
shell:
chdir: #切换到指定目录下执行命令
creates: #如果指定文件存在,不会执行这步操作
executable: #指定shell(默认/bin/sh)
free_form: #自由格式需要执行的linux命令,-a定义
removes: #如果指定文件存在,会执行这步操作,与creates相反
实例
[root@localhost ~]# ansible all -m shell -a "cat /etc/redhat-release"
10.10.10.11 | CHANGED | rc=0 >>
CentOS Linux release 8.0.1905 (Core)
10.10.10.12 | CHANGED | rc=0 >>
CentOS Linux release 8.0.1905 (Core)
script
帮助
[root@localhost ~]# ansible-doc -s script
- name: Runs a local script on a remote node after transferring it
script:
chdir: #切换到指定目录下执行命令
creates: #如果指定文件存在,不会执行这步操作
decrypt: #使用vault自动解密源文件。
executable: #指定shell(默认/bin/sh)
free_form: #自由格式需要执行的linux命令,-a定义
removes: #如果指定文件存在,会执行这步操作,与creates相反
[root@localhost ~]# vim test.sh
#编辑脚本文件
#!/bin/bash
echo `hostname`
[root@localhost ~]# chmod +x test.sh
[root@localhost ~]# ansible all -m script -a "/root/test.sh"
10.10.10.12 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 10.10.10.12 closed.\r\n",
"stderr_lines": [
"Shared connection to 10.10.10.12 closed."
],
"stdout": "localhost.localdomain\r\n",
"stdout_lines": [
"localhost.localdomain" #返回结果
]
}
10.10.10.11 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 10.10.10.11 closed.\r\n",
"stderr_lines": [
"Shared connection to 10.10.10.11 closed."
],
"stdout": "localhost.localdomain\r\n",
"stdout_lines": [
"localhost.localdomain"
]
}
file
帮助
[root@localhost ~]# ansible-doc -s file
- name: Manage files and file properties
file:
mode:设置权限
owner:设置属主
group:设置属组
recurse:递归设置文件属性(state=directory)
src:链接的原文件(state=link或state=hard
path:(必需)要管理的文件的路径。
state:
directory #创建目录,如果目标不存在则创建目录及其子目录
touch #创建文件,如果文件存在,则修改文件属性
absent #删除文件或目录
mode #设置文件或目录权限
owner #设置文件或目录属主信息
group #设置文件或目录属组信息
link #创建软连接,需要和src配合使用
hard #创建硬连接,需要和src配合使用
实例
#创建目录
[root@localhost ~]# ansible all -m file -a "path=/zabbix/ state=directory"
10.10.10.11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/zabbix/",
"secontext": "unconfined_u:object_r:default_t:s0",
"size": 6,
"state": "directory",
"uid": 0
}
10.10.10.12 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/zabbix/",
"secontext": "unconfined_u:object_r:default_t:s0",
"size": 6,
"state": "directory",
"uid": 0
}
#创建软连接
[root@localhost ~]# ansible all -m file -a "src=/etc/fstab path=/tmp/fstab.link state=link"
10.10.10.12 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"dest": "/tmp/fstab.link",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"secontext": "unconfined_u:object_r:user_tmp_t:s0",
"size": 10,
"src": "/etc/fstab",
"state": "link",
"uid": 0
}
10.10.10.11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"dest": "/tmp/fstab.link",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"secontext": "unconfined_u:object_r:user_tmp_t:s0",
"size": 10,
"src": "/etc/fstab",
"state": "link",
"uid": 0
}
copy
帮助
[root@localhost ~]# ansible-doc -s copy
- name: Copy files to remote locations
copy:如果复制前后文件不同则替换,相同则不执行
content="content":把content的内容直接设定指定文件的值
decrypt:使用vault自动解密原文件
dest:(必选)copy的目标文件|目录
group:设置copy后文件属组
mode:设置copy后文件权限
owner:设置copy后文件属主
src:管理节点原文件|原目录,原目录以"/"结尾,表示copy目录下所有内容;原目录未以"/"结尾,表示copy整个目录
remote_src=yes|no:YES指在远程主机内的原文件|原目录
实例
[root@localhost ~]# ansible all -m copy -a "src=/etc/fstab dest=/tmp/fstab"
10.10.10.11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"checksum": "b2c2ada9849d4ed17c09b80413c07cf7fb6d5c5b",
"dest": "/tmp/fstab",
"gid": 0,
"group": "root",
"md5sum": "833ddbfe06c875f4abda32c064bace3c",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 579,
"src": "/root/.ansible/tmp/ansible-tmp-1577552887.7366946-3325865568984/source",
"state": "file",
"uid": 0
}
10.10.10.12 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"checksum": "b2c2ada9849d4ed17c09b80413c07cf7fb6d5c5b",
"dest": "/tmp/fstab",
"gid": 0,
"group": "root",
"md5sum": "833ddbfe06c875f4abda32c064bace3c",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 579,
"src": "/root/.ansible/tmp/ansible-tmp-1577552887.7409215-175079830399158/source",
"state": "file",
"uid": 0
}
fetch
帮助
[root@localhost ~]# ansible-doc -s fetch
- name: Fetch files from remote nodes
fetch:
src=SRC_DIR:要拉取的远端文件路径
dest=DEST_DIR:远端文件本地存放路径
实例
[root@localhost ~]# ansible all -m fetch -a "src=/etc/fstab dest=/root/fstab"
10.10.10.11 | CHANGED => {
"changed": true,
"checksum": "b2c2ada9849d4ed17c09b80413c07cf7fb6d5c5b",
"dest": "/root/fstab/10.10.10.11/etc/fstab",
"md5sum": "833ddbfe06c875f4abda32c064bace3c",
"remote_checksum": "b2c2ada9849d4ed17c09b80413c07cf7fb6d5c5b",
"remote_md5sum": null
}
10.10.10.12 | CHANGED => {
"changed": true,
"checksum": "b2c2ada9849d4ed17c09b80413c07cf7fb6d5c5b",
"dest": "/root/fstab/10.10.10.12/etc/fstab",
"md5sum": "833ddbfe06c875f4abda32c064bace3c",
"remote_checksum": "b2c2ada9849d4ed17c09b80413c07cf7fb6d5c5b",
"remote_md5sum": null
}
[root@localhost ~]# tree fstab/
fstab/
├── 10.10.10.11
│ └── etc
│ └── fstab
└── 10.10.10.12
└── etc
└── fstab
user
帮助
[root@localhost ~]# ansible-doc -s user
- name: Manage user accounts
user:
comment=COMMENT:用户的说明
create_home=yes|no:是否创建家目录
group=GROUP:指定用户组
groups=GROUP:指定附加组
home=HOME_DIR:指定家目录
name=LOGIN:指定用户名
password=PWD: 指定用户密码
remove=yes|no:state=absent时,是否删除家目录
shell=SHELL:指定用户的shell
state=present|absent:创建|删除用户
system=yes|no:state=present时,是否创建为系统账户
uid=UID:指定用户UID
实例
#创建用户chenran
[root@localhost ~]# ansible all -m user -a "state=present name=chenran password=`openssl passwd -6 "123"` create_home=no shell=/bin/bash"
10.10.10.11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"append": false,
"changed": true,
"comment": "",
"group": 1000,
"home": "/home/chenran",
"move_home": false,
"name": "chenran",
"password": "NOT_LOGGING_PASSWORD",
"shell": "/bin/bash",
"state": "present",
"uid": 1000
}
10.10.10.12 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"append": false,
"changed": true,
"comment": "",
"group": 1000,
"home": "/home/chenran",
"move_home": false,
"name": "chenran",
"password": "NOT_LOGGING_PASSWORD",
"shell": "/bin/bash",
"state": "present",
"uid": 1000
}
#删除用户chenran
[root@localhost ~]# ansible all -m user -a "state=absent name=chenran remove=yes"
10.10.10.11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"force": false,
"name": "chenran",
"remove": true,
"state": "absent",
"stderr": "userdel: chenran home directory (/home/chenran) not found\n",
"stderr_lines": [
"userdel: chenran home directory (/home/chenran) not found"
]
}
10.10.10.12 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"force": false,
"name": "chenran",
"remove": true,
"state": "absent",
"stderr": "userdel: chenran home directory (/home/chenran) not found\n",
"stderr_lines": [
"userdel: chenran home directory (/home/chenran) not found"
]
}
group
帮助
[root@localhost ~]# ansible-doc -s group
- name: Add or remove groups
group:
gid=GID:设置组gid
name:设置组名
state=present|absent:创建|删除组
system=yes|no:state=present时,是否创建为系统组
实例
[root@localhost ~]# ansible all -m group -a "state=present name=chenran"
10.10.10.12 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"gid": 1000,
"name": "chenran",
"state": "present",
"system": false
}
10.10.10.11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"gid": 1000,
"name": "chenran",
"state": "present",
"system": false
}
yum
帮助
[root@localhost ~]# ansible-doc -s yum
- name: Manages packages with the `yum' package manager
yum:
disable_gpg_check=yes|no:当state=installed|present时,禁用gpg_check
disablerepo=REPO:当state=installed|present时,禁用指定repo
enablerepo=REPO:当state=installed|present时,启用以禁用的指定repo
name=PACKAGE:按照指定软件包
list:
installed:列出所有已安装的软件包
updates:列出所有可以更新的软件包
repos:列出所有的yum仓库
state:
installed|present:安装软件包(两者任选其一都可以)
removed|absent:卸载软件包
latest:安装最新软件包
实例
#显示yum repolist
[root@localhost ~]# ansible all -m yum -a "list=repos"
10.10.10.12 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"msg": "",
"results": [
{
"repoid": "AppStream",
"state": "enabled"
},
{
"repoid": "BaseOS",
"state": "enabled"
},
{
"repoid": "extras",
"state": "enabled"
}
]
}
10.10.10.11 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"msg": "",
"results": [
{
"repoid": "AppStream",
"state": "enabled"
},
{
"repoid": "BaseOS",
"state": "enabled"
},
{
"repoid": "extras",
"state": "enabled"
}
]
}
#安装nginx
[root@localhost ~]# ansible all -m yum -a "state=present name=nginx"
10.10.10.12 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Installed: nginx",
"Installed: nginx-mod-mail-1:1.14.1-9.module_el8.0.0+184+e34fea82.x86_64",
"Installed: nginx-mod-stream-1:1.14.1-9.module_el8.0.0+184+e34fea82.x86_64",
"Installed: nginx-1:1.14.1-9.module_el8.0.0+184+e34fea82.x86_64",
"Installed: nginx-all-modules-1:1.14.1-9.module_el8.0.0+184+e34fea82.noarch",
"Installed: nginx-filesystem-1:1.14.1-9.module_el8.0.0+184+e34fea82.noarch",
"Installed: nginx-mod-http-image-filter-1:1.14.1-9.module_el8.0.0+184+e34fea82.x86_64",
"Installed: nginx-mod-http-perl-1:1.14.1-9.module_el8.0.0+184+e34fea82.x86_64",
"Installed: nginx-mod-http-xslt-filter-1:1.14.1-9.module_el8.0.0+184+e34fea82.x86_64"
]
}
10.10.10.11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Installed: nginx",
"Installed: nginx-mod-mail-1:1.14.1-9.module_el8.0.0+184+e34fea82.x86_64",
"Installed: nginx-mod-stream-1:1.14.1-9.module_el8.0.0+184+e34fea82.x86_64",
"Installed: nginx-1:1.14.1-9.module_el8.0.0+184+e34fea82.x86_64",
"Installed: nginx-all-modules-1:1.14.1-9.module_el8.0.0+184+e34fea82.noarch",
"Installed: nginx-filesystem-1:1.14.1-9.module_el8.0.0+184+e34fea82.noarch",
"Installed: nginx-mod-http-image-filter-1:1.14.1-9.module_el8.0.0+184+e34fea82.x86_64",
"Installed: nginx-mod-http-perl-1:1.14.1-9.module_el8.0.0+184+e34fea82.x86_64",
"Installed: nginx-mod-http-xslt-filter-1:1.14.1-9.module_el8.0.0+184+e34fea82.x86_64"
]
}
service | systemd
帮助
[root@localhost ~]# ansible-doc -s service
- name: Manage services
service:
enabled=YES|NO:设置开机启动
name=SERVICE_NAME:服务名
state:
started:启动服务
stopped:停止服务
restarted:重启服务
reloaded:重载服务
实例
[root@localhost ~]# ansible all -m service -a "name=vsftpd state=started"
[root@localhost ~]# ansible all -m shell -a "systemctl status vsftpd"
10.10.10.11 | CHANGED | rc=0 >>
● vsftpd.service - Vsftpd ftp daemon
Loaded: loaded (/usr/lib/systemd/system/vsftpd.service; disabled; vendor preset: disabled)
Active: active (running) since Sat 2020-01-11 15:48:00 CST; 1min 51s ago
Process: 8977 ExecStart=/usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf (code=exited, status=0/SUCCESS)
Main PID: 8978 (vsftpd)
Tasks: 1 (limit: 4911)
Memory: 544.0K
CGroup: /system.slice/vsftpd.service
└─8978 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf
Jan 11 15:48:00 localhost.localdomain systemd[1]: Starting Vsftpd ftp daemon...
Jan 11 15:48:00 localhost.localdomain systemd[1]: Started Vsftpd ftp daemon.
10.10.10.12 | CHANGED | rc=0 >>
● vsftpd.service - Vsftpd ftp daemon
Loaded: loaded (/usr/lib/systemd/system/vsftpd.service; disabled; vendor preset: disabled)
Active: active (running) since Sat 2020-01-11 15:48:00 CST; 1min 51s ago
Process: 8965 ExecStart=/usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf (code=exited, status=0/SUCCESS)
Main PID: 8966 (vsftpd)
Tasks: 1 (limit: 4911)
Memory: 548.0K
CGroup: /system.slice/vsftpd.service
└─8966 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf
Jan 11 15:48:00 localhost.localdomain systemd[1]: Starting Vsftpd ftp daemon...
Jan 11 15:48:00 localhost.localdomain systemd[1]: Started Vsftpd ftp daemon.
cron
帮助
[root@localhost ~]# ansible-doc -s cron
- name: Manage cron.d and crontab entries
cron:
disabled:当`state=present',禁用指定任务
job:当`state=present',执行指定任务
minute:分( 0-59, *, */2, etc )
hour:时( 0-23, *, */2, etc )
weekday:周( 0-6 for Sunday-Saturday, *, etc )
day:天( 1-31, *, */2, etc )
month:月( 1-12, *, */2, etc )
name:计划任务名
state:
present:增加
absent:删除
user:为指定user创建计划任务,默认root
实例
[root@localhost ~]# cat test.sh
echo cron_test > /dev/console #输出到console窗口
[root@localhost ~]# chmod +x test.sh
[root@localhost ~]# bash test.sh
cron_test
[root@localhost ~]# ansible all -m copy -a "src=/root/test.sh dest=/root/test.sh mode=755"
[root@localhost ~]# ansible all -m cron -a "minute=* job='/bin/sh /root/test.sh' name=test state=present"
setup
mount
帮助
[root@localhost ~]# ansible-doc -s mount
- name: Control active and configured mount points
mount:
fstype:文件类型
opts:挂在参数
path:挂在路径
src:块文件设备
state:
present:挂载项写入fstab文件
absent:挂载项从fstab文件中删除
mounted:挂载项写入fstab文件并挂载
unmounted:卸载
实例
准备一块磁盘,分区并格式化。挂在/dev/sdb1到/data目录。
[root@localhost ~]# ansible 10.10.10.11 -m shell -a "mkdir -pv /data"
[root@localhost ~]# ansible 10.10.10.11 -m mount -a "src=/dev/sdb1 path=/data fstype=xfs opts=defaults state=present"
[root@localhost ~]# ansible 10.10.10.11 -m shell -a "cat /etc/fstab | grep /data"
10.10.10.11 | CHANGED | rc=0 >>
/dev/sdb1 /data xfs defaults 0 0
[root@localhost ~]# ansible 10.10.10.11 -m mount -a "src=/dev/sdb1 path=/data fstype=xfs opts=defaults state=unmounted"
[root@localhost ~]# ansible 10.10.10.11 -m shell -a "cat /etc/fstab | grep /data"
10.10.10.11 | CHANGED | rc=0 >>
/dev/sdb1 /data xfs defaults 0 0
[root@localhost ~]# ansible 10.10.10.11 -m shell -a "cat /proc/mounts | grep /data"
10.10.10.11 | FAILED | rc=1 >>
non-zero return code
[root@localhost ~]# ansible 10.10.10.11 -m mount -a "src=/dev/sdb1 path=/data state=absent"
[root@localhost ~]# ansible 10.10.10.11 -m shell -a "cat /etc/fstab | grep /data"
10.10.10.11 | FAILED | rc=1 >>
non-zero return code
ansible剧本
ansible-playbook
ansible-playbook是基于yaml格式组织。
核心元素:
- hosts: all #主机
remote_user: root #远端执行用户
vars: #变量
- key1: value1 #key=value
- key2: value2
tasks: #任务列表
- name: task_name #任务名
tags: tag_name #标签名
template: src=path dest=path #模板
notify: handler_name #通知handler
- name: task_name
yum: name={{ item }} state=installed
with_items: #迭代循环
- item1
- item2
- item3
- name: task_name
user: name={{ item.name }} group={{ item.group }} state=present
with_items:
- { name: "user1", group: "group1" }
- { name: "user2", group: "group2" }
- { name: "user3", group: "group3" }
when: ansible_os_family == "RedHat" #条件判断
handlers: #事件
- name: handler_name
systemd: name=app_name state=restartd
基本使用
为10.10.10.11和10.10.10.12安装redis服务,并提供配置文件。
[root@localhost ~]# mkdir playbooks
[root@localhost ~]# cd playbooks
[root@localhost playbooks]# cat installRedis.yaml
- hosts: all
remote_user: root
tasks:
- name: install redis
yum: name=redis state=installed
when: ansible_os_family == "RedHat"
- name: provide redis configure file
copy: src=/root/playbooks/redis.conf dest=/etc/redis.conf
- name: start redis
systemd: name=redis state=started
[root@localhost playbooks]# ansible-playbook --syntax-check installRedis.yaml
playbook: installRedis.yaml
[root@localhost playbooks]# ansible-playbook -C installRedis.yaml
PLAY [all] ************************************************************************************************
TASK [Gathering Facts] ************************************************************************************
ok: [10.10.10.12]
ok: [10.10.10.11]
TASK [install redis] **************************************************************************************
ok: [10.10.10.11]
ok: [10.10.10.12]
TASK [provide redis configure file] ***********************************************************************
ok: [10.10.10.12]
ok: [10.10.10.11]
TASK [start redis] ****************************************************************************************
changed: [10.10.10.12]
changed: [10.10.10.11]
PLAY RECAP ************************************************************************************************
10.10.10.11 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.10.10.12 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
标签
当我们使用playbook时,只执行或跳过某一个特定任务的时候就需要使用tags。例如我们在前面的基础上,当每次redis的配置文件更新,我们可指定标签只执行任务”provide redis configure file“。
[root@localhost playbooks]# cat installRedis.yaml
- hosts: all
remote_user: root
tasks:
- name: install redis
yum: name=redis state=installed
- name: provide redis configure file
tags: configure #标签
copy: src=/root/playbooks/redis.conf dest=/etc/redis.conf
- name: start redis
systemd: name=redis state=started
[root@localhost playbooks]# ansible-playbook --list-tasks installRedis.yaml
playbook: installRedis.yaml
play #1 (all): all TAGS: []
tasks:
install redis TAGS: []
provide redis configure file TAGS: [configure]
start redis TAGS: []
[root@localhost playbooks]# ansible-playbook -C -t configure installRedis.yaml
PLAY [all] ************************************************************************************************
TASK [Gathering Facts] ************************************************************************************
ok: [10.10.10.11]
ok: [10.10.10.12]
TASK [provide redis configure file] ***********************************************************************
ok: [10.10.10.12]
ok: [10.10.10.11]
PLAY RECAP ************************************************************************************************
10.10.10.11 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.10.10.12 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
事件
当配置文件更新后,通过playbook执行tags后,配置文件是更新,但服务没有重启,配置项没有生效,所以在每次更新配置文件后,应重启一次服务,可以使用notify和handlers完成。
[root@localhost playbooks]# cat installRedis.yaml
- hosts: all
remote_user: root
tasks:
- name: install redis
yum: name=redis state=installed
- name: provide redis configure file
tags: configure
copy: src=/root/playbooks/redis.conf dest=/etc/redis.conf
notify: restart redis #配置文件更新,通知定义的handlers
- name: start redis
systemd: name=redis state=started
handlers: #重启redis
- name: restart redis
systemd: name=redis state=restarted
[root@localhost playbooks]# ansible-playbook --syntax-check installRedis.yaml
playbook: installRedis.yaml
[root@localhost playbooks]# ansible-playbook -C -t configure installRedis.yaml
PLAY [all] ************************************************************************************************
TASK [Gathering Facts] ************************************************************************************
ok: [10.10.10.11]
ok: [10.10.10.12]
TASK [provide redis configure file] ***********************************************************************
changed: [10.10.10.11]
changed: [10.10.10.12]
RUNNING HANDLER [restart redis] ***************************************************************************
changed: [10.10.10.12]
changed: [10.10.10.11]
PLAY RECAP ************************************************************************************************
10.10.10.11 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.10.10.12 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
参数
- 定义key
- playbook
vars:
- key: value
- hosts
[servers] #组中各成员单独定义变量,可对同key传入不同value
ip|domain key1=value1
ip|domain key2=value2
[servers:vars] #组中统一定义变量
key=value
- 命令行
-e, --extra-vars #key=value
- Gathering Facts
从被管理主机收集到的系统信息,可直接调用
[root@localhost playbooks]# ansible 10.10.10.11 -m setup
- 调用 {{ key }}
- playbook中调用
- template中调用
- 实例
[root@localhost playbooks]# cat /etc/ansible/hosts
[redis]
10.10.10.11
10.10.10.12
[redis:vars]
redis_port=6379
[root@localhost playbooks]# cat installRedis.yaml
- hosts: all
remote_user: root
vars: #playbook中定义
- package: redis
tasks:
- name: install {{ package }} listen_ip={{ ansible_ens33.ipv4.address }} listen_port={{ redis_port }}
#调用playbook中定义的key;调用facts收集到的ip;调用hosts中定义的port
yum: name=redis state=installed
- name: provide {{ package }} configure file
tags: configure
copy: src=/root/playbooks/redis.conf dest=/etc/redis.conf
notify: restart {{ package }}
- name: start redis
systemd: name=redis state=started
handlers:
- name: restart {{ package }}
systemd: name=redis state=restarted
[root@localhost playbooks]# ansible-playbook -C installRedis.yaml -e package=nginx
#传入值,可覆盖playbook中定义参数原有值
PLAY [all] ************************************************************************************************
TASK [Gathering Facts] ************************************************************************************
#收集到的主机参数,可直接使用
ok: [10.10.10.12]
ok: [10.10.10.11]
TASK [install nginx listen_ip=10.10.10.11 listen_port=6379] *********************************************************************
#传入的参数、playbook和hosts文件中定义参数
ok: [10.10.10.11]
ok: [10.10.10.12]
TASK [provide nginx configure file] ***********************************************************************
changed: [10.10.10.12]
changed: [10.10.10.11]
TASK [start redis] ****************************************************************************************
changed: [10.10.10.11]
changed: [10.10.10.12]
RUNNING HANDLER [restart nginx] ***************************************************************************
changed: [10.10.10.11]
changed: [10.10.10.12]
PLAY RECAP ************************************************************************************************
10.10.10.11 : ok=5 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.10.10.12 : ok=5 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
模板
template是使用jinja2语言提供动态配置服务,支持判断、运算、比较等操作。可以将一个应用的配置文件引用facts收集到的系统信息或自定义key作为参数调用来创建模板。基于该模板实现不同主机的配置。
[root@localhost playbooks]# cat redis.conf.j2 | grep ^bind
bind {{ ansible_ens33.ipv4.address }}
[root@localhost playbooks]# cat installRedis.yaml
- hosts: all
remote_user: root
vars:
- package: redis
tasks:
- name: install {{ package }} listen_port={{ ansible_ens33.ipv4.address }} listen_port={{ redis_port }}
yum: name=redis state=installed
- name: provide {{ package }} configure file
tags: configure
template: src=/root/playbooks/redis.conf.j2 dest=/etc/redis.conf
#模板调用
notify: restart {{ package }}
- name: start redis
systemd: name=redis state=started
handlers:
- name: restart {{ package }}
systemd: name=redis state=restarted
[root@localhost playbooks]# ansible-playbook installRedis.yaml -t configure
PLAY [all] **************************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************************************************************************************************************************
ok: [10.10.10.12]
ok: [10.10.10.11]
TASK [provide redis configure file] *************************************************************************************************************************************************************************************************************
changed: [10.10.10.11]
changed: [10.10.10.12]
RUNNING HANDLER [restart redis] *****************************************************************************************************************************************************************************************************************
changed: [10.10.10.11]
changed: [10.10.10.12]
PLAY RECAP **************************************************************************************************************************************************************************************************************************************
10.10.10.11 : ok=5 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.10.10.12 : ok=5 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@localhost playbooks]# ansible all -m shell -a "cat /etc/redis.conf | grep ^bind"
10.10.10.12 | CHANGED | rc=0 >>
bind 10.10.10.12
10.10.10.11 | CHANGED | rc=0 >>
bind 10.10.10.11
ansible角色
roles能够根据层次结构,将变量、文件、任务、模板分别放置于单独目录,并可使用include它们的一种机制。
![ansible_role](https://i-blog.csdnimg.cn/blog_migrate/1a2a4a68214e7b7d4a94cda3e5b77b5e.png)
-
roles
默认位置/etc/ansible/roles下 -
project
项目名,如nginx、tomcat、php -
file
存放copy或script模块掉用的文件 -
templates
存放jinjia2模板文件,template模块自动在此目录下搜索 -
tasks
目录中应包含一个main.yml,使用include包含此目录下的task文件 -
handlers
目录中应包含一个main.yml,触发条件时执行的动作 -
vars
目录中应包含一个main.yml,角色中使用的变量 -
defaults
目录中应包含一个main.yml,角色中使用的默认变量 -
meta
目录中应包含一个main.yml,定义及其依赖关系
实例
通过ansible实现lnmp安装
1、创建目录结构
[root@localhost ~]# cd /etc/ansible/roles/
[root@localhost roles]# mkdir -p {nginx,mariadb,php}/{files,tasks,vars,templates,handlers}
[root@localhost roles]# tree
.
├── lnmp_roles.yaml
├── mariadb
│ ├── files
│ │ └── create_user.sh #创建mysql用户脚本
│ ├── handlers
│ ├── tasks
│ │ ├── main.yaml #引用子任务
│ │ ├── mariadb_create_user.yaml #创建用户任务
│ │ ├── mariadb_install.yaml #数据库安装任务
│ │ └── mariadb_start.yaml #启动数据库任务
│ ├── templates
│ └── vars
│ └── main.yaml #变量
├── mariadb_roles.yaml
├── nginx
│ ├── files
│ │ ├── index.php
│ │ └── test_sql.php
│ ├── handlers
│ │ └── main.yaml
│ ├── tasks
│ │ ├── main.yaml
│ │ ├── nginx_config.yaml
│ │ ├── nginx_install.yaml
│ │ ├── nginx_php_page.yaml
│ │ └── nginx_start.yaml
│ ├── templates
│ │ └── nginx.conf.j2
│ └── vars
│ └── main.yml
├── nginx_roles.yaml
├── php
│ ├── files
│ ├── handlers
│ ├── tasks
│ │ ├── main.yaml
│ │ ├── php_install.yaml
│ │ └── php_start.yaml
│ ├── templates
│ └── vars
└── php_roles.yaml
lnmp_roles
#roles
[root@localhost roles]# cat lnmp_roles.yaml
- hosts: 10.10.10.11
remote_user: root
roles:
- role: nginx
- role: mariadb
- role: php
nginx_roles
#roles
[root@localhost roles]# cat nginx_roles.yaml
- hosts: 10.10.10.11
remote_user: root
roles:
- role: nginx
#tasks
[root@localhost roles]# cat nginx/tasks/main.yaml
- include: nginx_install.yaml
- include: nginx_config.yaml
- include: nginx_php_page.yaml
- include: nginx_start.yaml
[root@localhost roles]# cat nginx/tasks/nginx_install.yaml
- name: yum install nginx
yum: name=nginx state=installed
[root@localhost roles]# cat nginx/tasks/nginx_config.yaml
- name: nginx config template
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: restart nginx
[root@localhost roles]# cat nginx/tasks/nginx_php_page.yaml
- name: copy php_page
copy: src={{ item }} dest=/usr/share/nginx/html
with_items:
- index.php
- test_sql.php
[root@localhost roles]# cat nginx/tasks/nginx_start.yaml
- name: systemctl start nginx
systemd: name=nginx state=started enabled=yes
#handlers
[root@localhost roles]# cat nginx/handlers/main.yaml
- name: restart nginx
systemd: name=nginx state=restarted
#files
[root@localhost roles]# cat nginx/files/index.php
<?php
phpinfo();
?>
[root@localhost roles]# cat nginx/files/test_sql.php
<?php
$conn=mysqli_connect("127.0.0.1","nginx","nginx");
if($conn){
echo"ok";
$conn->close();
}else{
echo"error";
}
?>
#template
[root@localhost roles]# cat nginx/templates/nginx.conf.j2
user {{ nginx_user }};
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
server {
listen {{ ansible_ens33.ipv4.address }}:{{listen_port }} default_server;
server_name {{ server_name }};
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
#vars
[root@localhost roles]# cat nginx/vars/main.yml
nginx_user: nginx
listen_port: 80
server_name: www.chenran.com
mariadb_role
#roles
[root@localhost roles]# cat mariadb_roles.yaml
- hosts: 10.10.10.11
remote_user: root
roles:
- role: mariadb
#tasks
[root@localhost roles]# cat mariadb/tasks/main.yaml
- include: mariadb_install.yaml
- include: mariadb_start.yaml
- include: mariadb_create_user.yaml
[root@localhost roles]# cat mariadb/tasks/mariadb_install.yaml
- name: yum install mariadb-server
yum: name=mariadb-server state=installed
[root@localhost roles]# cat mariadb/tasks/mariadb_start.yaml
- name: mariadb start
systemd: name=mariadb state=started enabled=yes
[root@localhost roles]# cat mariadb/tasks/mariadb_create_user.yaml
- name: mariadb create mariadb_user
script: create_user.sh {{ user }} {{ password }}
#file
[root@localhost roles]# cat mariadb/files/create_user.sh
#!/bin/bash
exist=$(mysql -e "use mysql;select count(*) from user where User='$1'" | sed "1d")
if [ 0 -eq $exist ]; then
$(mysql -e "grant all privileges on *.* to '$1'@'%' identified by '$2'")
fi
#vars
[root@localhost roles]# cat mariadb/vars/main.yaml
user: nginx
password: nginx
php_role
#roles
[root@localhost roles]# cat php_roles.yaml
- hosts: 10.10.10.11
remote_user: root
roles:
- role: php
#tasks
[root@localhost roles]# cat php/tasks/main.yaml
- include: php_install.yaml
- include: php_start.yaml
[root@localhost roles]# cat php/tasks/php_install.yaml
- name: yum install php
yum: name={{ item.name }} state=installed
with_items:
- { name: 'php' }
- { name: 'php-fpm' }
- { name: 'php-mysqlnd' }
[root@localhost roles]# cat php/tasks/php_start.yaml
- name: php start
systemd: name=php-fpm state=started enabled=yes