生产实践:
使用shell脚本调用ansible执行批量操作
学习技巧:
Shell 脚本调用ansible、Ansible常用模块使用
脚本内容:
生产中如果没有平台支持,在中控批量操作远程主机是很常用的,如果已经做好ssh互信认证用pssh这种就很方便,没有提前做好认证用ansible更合适,但是根据经验其实都是混用。pssh,ansible,saltstack,脚本,哪个更适用就用哪个或者组合使用。以下是几个shell调用 ansible 2.9.25 执行批量操作的脚本,用的比较随意可以优化。
ansilbe_shell.sh:使用ansible shell模块批量执行命令
#!/bin/bash
#set -x
set -e
if [ $# -lt 2 ]; then
echo "Usage: ansible_shell <host1,hosts2,hostgroup> <commands>"
exit
fi
hosts="*$1"
shift 1
commands="$*"
#commands=${*:2}
# ansible_sudo_pass也可以在ansible主机配置文件里写,这里就无需加-e写了
if [ -n "${commands}" ]; then
ansible $hosts -m shell -a "$commands;echo ' '" -e "ansible_sudo_pass=xxx" 2>/dev/null
fi
exitansible_sync.sh:使用ansible synchronize模块批量往远程主机推文件或文件夹,也可以将远程文件拉回本地
#!/bin/bash
##############################################################################
# $Name: ansible_syncfile.sh
# $Version: v1.0
# $Function: Used to synchronize host's files
# $Author: Zhihe An
# $Create Date: 20230524
##############################################################################
set -e
if [[ $# -lt 4 || "$1" == "-h" || "$1" == "--help" || -z "$1" ]]; then
echo "Usage: ansible_syncfile <host1,hosts2,hostgroup> <src file> <dst file> <mode>[pull|push]"
exit
fi
hosts="$1"
# 获取执行主机列表
host_list=$(ansible $hosts --list-hosts 2>/dev/null | sed '1d')
src_file="$2"
dest_file="$3"
sync_mode="$4"
# list servers
echo -e "\nYou will \033[31m$sync_mode files\033[0m by these servers:\n"
ansible $hosts --list-hosts 2>/dev/null
echo ""
read -p "Are you sure?(y|n) " ans
echo ""
if [[ "$ans" != @("y"|"Y"|"Yes"|"yes") ]]; then
echo -e "\033[31m已取消操作...\033[0m"
exit
fi
# 注意mode参数:指定同步的方向,在推模式下,本地主机或委托是源;在拉模式下,上下文中的远程主机是源
# rsync同步的方式为push、pull,默认是推送push,从本机推送给远程主机,从『控制机』到『目标机』;pull表示从远程主机上拿文件,从『目标机』到『控制机』
if [[ "$sync_mode" == "pull" && -e "$dest_file" ]]; then
# 将远端文件拉到指定目录
if [[ -n $host_list ]]; then
for host in ${host_list[@]}; do
[[ ! -e "$dest_file/$host" ]] && mkdir -p $dest_file/$host
ansible $host -m synchronize -a "src=$src_file dest=$dest_file/$host/ rsync_path=/usr/bin/rsync mode=pull" -e "ansible_sudo_pass=xxx" 2>/dev/null
sleep 1
done
[[ $? = 0 ]] && echo "文件下载完成,请进入$dest_file中查看"
fi
elif [[ "$sync_mode" == "push" && -e "$src_file" ]]; then
# 将文件推到远端机器指定目录
ansible $hosts -m synchronize -a "src=$src_file dest=$dest_file rsync_path=/usr/bin/rsync" -e "ansible_sudo_pass=xxx" 2>/dev/null
[[ $? = 0 ]] && echo "文件推送完成"
else
echo "文件同步失败,请检察文件路径是否存在或主机是否匹配!"
fi
exitansible_copy.sh:使用ansible copy模块往远程主机推文件
#!/bin/bash
set -e
if [ $# -lt 3 ]; then
echo "Usage: ansible_copy <host_list> <src file> <dst file>"
exit
fi
hosts="*$1*"
src_file="$2"
dst_file="$3"
args=${*:4}
# list servers
echo -e "\nYou will copy \033[31m$src_file\033[0m to these servers:\n"
ansible $hosts --list-hosts 2>/dev/null
echo ""
read -p "Are you sure?(y|n) " ans
echo ""
if [[ "$ans" != @("y"|"Y"|"Yes"|"yes") ]]; then
echo -e "\033[31m已取消操作...\033[0m"
exit
fi
if [ -e "$src_file" ]; then
ansible $hosts -m copy -a "src=$src_file dest=$dst_file owner=root group=root mode=0755" -e "ansible_sudo_pass=xxx" $args 2>/dev/null
fi
exitansible_script.sh:使用ansible script模块在远程主机执行脚本
#!/bin/bash if [ $# -lt 3 ]; then echo "usage: $0 <inventory file> <all|host1,host2,host3> <script file>" exit fi inventory=$(readlink -fn $1) hosts="$2" script_file=$(readlink -fn $3) if [ -f "$script_file" ]; then ansible -i $inventory $hosts -m script -a "$script_file" fi
pk:执行ansible-playbook,主机列表通过host_list变量传到playbook中,如:pk check_adcu.yaml *6666* -t date -v
echo "[[ -f ~/.bash_aliases ]] && source ~/.bash_aliases" >> ~/.bash_profile
cat >> ~/.bash_profile << EOF
# 执行ansible playbook by anzhihe 20230522
pk() {
if [[ $# -lt 2 || "$1" == "-h" || "$1" == "--help" || -z "$1" ]]; then
echo "usage: pk <playbook file> <all|host1,hosts2,hostgroup> [args]"
# exit
fi
pkfile="$(readlink -fn $1)"
hosts="$2"
#shift 2
args=${*:3}
if [ -f "${pkfile}" ]; then
eval "ansible-playbook ${pkfile} --extra-vars "ansible_sudo_pass=xxx" -e "host_list=$hosts" "$args"" 2>/dev/null
fi
}
function nps() {
if [[ "$1" == "-h" || "$1" == "--help" || -z "$1" ]]; then
python3 /home/anzhihe/op/python/ops.py -h 2>/dev/null
else
python3 /home/anzhihe/op/python/ops.py -nps $1 2>/dev/null
fi
}
EOF
source ~/.bash_profile && source ~/.bash_aliases参考: