Ansible基础模块
# Ansible常用模块
# Ansible常用模块
# hostname模块
- 用于管理远程主机的主机名
name: 必选项,主机名称
更改主机名
[root@ansible ~]# ansible 192.168.100.20 -m hostname -a 'name=node99'
# user模块
- 用于创建用户以及修改用户的权限
User:管理用户
home 指定家目录路径
system 指定系统账号
group 指定组
remove 清除账户
shell 指定shell类型
ansible websrvs -m user -a 'name=user1 comment="test user" uid=2048 home=/app/user1 group=root'
ansible websrvs -m user -a 'name=sysuser1 system=yes home=/app/sysuser1'
ansible websrvs -m user -a 'name=user1 state=absent remove=yes' 清空用户所有数据
ansible websrvs -m user -a 'name=app uid=88 system=yes home=/app groups=root shell=/sbin/nologin password="$1$zfVojmPy$ZILcvxnXljvTI2PhP2Iqv1"' 创建用户
ansible websrvs -m user -a 'name=app state=absent' 不会删除家目录
# group模块
- 用于创建组和修改组的权限操作
Group:管理组
state=present表示创建组,state=absent时表示删除组;
syste=yes表示创建系统组,system=no表示创建的不是系统组;
ansible srv -m group -a "name=testgroup system=yes" 创建组
ansible srv -m group -a "name=testgroup state=absent" 删除组
在test组包含的被控端上创建组testgroup,组id为111
ansible test -m group -a 'name =testgroup gid=111 state=present system=yes'
# command模块
- 在远程主机执行命令,默认模块,可忽略-m选项
chdir: 进入到被管理主机目录
creates: 如果有一个目录是存在的,步骤将不会运行Command命令
ansible websrvs -a 'chdir=/data/ ls'
> ansible srvs -m command -a 'service vsftpd start'
> ansible srvs -m command -a 'echo adong |passwd --stdin 123456'
#此命令不支持 $VARNAME < > | ; & 等,用shell模块实现
- Playbook用法
- name: return motd to registered var
command: cat /etc/motd
register: mymotd
- name: Run command if /path/to/database does not exist (without 'args' keyword).
command: /usr/bin/make_database.sh db_user db_name creates=/path/to/database
# 'args' is a task keyword, passed at the same level as the module
- name: Run command if /path/to/database does not exist (with 'args' keyword).
command: /usr/bin/make_database.sh db_user db_name
args:
creates: /path/to/database
# 'cmd' is module parameter
- name: Run command if /path/to/database does not exist (with 'cmd' parameter).
command:
cmd: /usr/bin/make_database.sh db_user db_name
creates: /path/to/database
- name: Change the working directory to somedir/ and run the command as db_owner if /path/to/database does not exist.
command: /usr/bin/make_database.sh db_user db_name
become: yes
become_user: db_owner
args:
chdir: somedir/
creates: /path/to/database
# 'argv' is a parameter, indented one level from the module
- name: Use 'argv' to send a command as a list - leave 'command' empty
command:
argv:
- /usr/bin/make_database.sh
- Username with whitespace
- dbname with whitespace
- name: safely use templated variable to run command. Always use the quote filter to avoid injection issues.
command: cat {{ myfile|quote }}
register: myoutput
# shell模块
- 和command相似,用shell执行命令
修改配置文件,使shell作为默认模块
vim /etc/ansible/ansible.cfg
module_name = shell
> ansible all -m shell -a 'getenforce' 查看SELINUX状态
> ansible all -m shell -a "sed -i 's/SELINUX=.*/SELINUX=disabled' /etc/selinux/config"
> ansible srv -m shell -a 'echo magedu |passwd –stdin wang'
调用bash执行命令 类似 cat /tmp/stanley.md | awk -F'|' '{print $1,$2}' &> /tmp/example.txt
这些复杂命令,即使使用shell也可能会失败,
解决办法:写到脚本时,copy到远程执行,再把需要的结果拉回执行命令的机器
- Playbook用法
- name: Execute the command in remote shell; stdout goes to the specified file on the remote.
shell: somescript.sh >> somelog.txt
- name: Change the working directory to somedir/ before executing the command.
shell: somescript.sh >> somelog.txt
args:
chdir: somedir/
# You can also use the 'args' form to provide the options.
- name: This command will change the working directory to somedir/ and will only run when somedir/somelog.txt doesn't exist.
shell: somescript.sh >> somelog.txt
args:
chdir: somedir/
creates: somelog.txt
# You can also use the 'cmd' parameter instead of free form format.
- name: This command will change the working directory to somedir/.
shell:
cmd: ls -l | grep log
chdir: somedir/
- name: Run a command that uses non-posix shell-isms (in this example /bin/sh doesn't handle redirection and wildcards together but bash does)
shell: cat < /tmp/*txt
args:
executable: /bin/bash
- name: Run a command using a templated variable (always use quote filter to avoid injection)
shell: cat {{ myfile|quote }}
# You can use shell to run other executables to perform actions inline
- name: Run expect to wait for a successful PXE boot via out-of-band CIMC
shell: |
set timeout 300
spawn ssh admin@{{ cimc_host }}
expect "password:"
send "{{ cimc_password }}\n"
expect "\n{{ cimc_name }}"
send "connect host\n"
expect "pxeboot.n12"
send "\n"
exit 0
args:
executable: /usr/bin/expect
delegate_to: localhost
# Disabling warnings
- name: Using curl to connect to a host via SOCKS proxy (unsupported in uri). Ordinarily this would throw a warning.
shell: curl --socks5 localhost:9000 http://www.ansible.com
args:
warn: no
# copy模块
- 从主控端复制文件到远程主机
src : 源文件 指定拷贝文件的本地路径 (如果有/ 则拷贝目录内容,比拷贝目录本身)
dest: 指定目标路径
mode: 设置权限
backup: 备份源文件
content: 代替src 指定本机文件内容,生成目标主机文件
> ansible websrvs -m copy -a "src=/root/test1.sh dest=/tmp/test2.showner=wang mode=600 backup=yes"
如果目标存在,默认覆盖,此处指定先备份
> ansible websrvs -m copy -a "content='test content\nxxx' dest=/tmp/test.txt"
指定内容,直接生成目标文件
- Playbook用法
- name: Copy file with owner and permissions
copy:
src: /srv/myfiles/foo.conf
dest: /etc/foo.conf
owner: foo
group: foo
mode: '0644'
- name: Copy file with owner and permission, using symbolic representation
copy:
src: /srv/myfiles/foo.conf
dest: /etc/foo.conf
owner: foo
group: foo
mode: u=rw,g=r,o=r
- name: Another symbolic mode example, adding some permissions and removing others
copy:
src: /srv/myfiles/foo.conf
dest: /etc/foo.conf
owner: foo
group: foo
mode: u+rw,g-wx,o-rwx
- name: Copy a new "ntp.conf file into place, backing up the original if it differs from the copied version
copy:
src: /mine/ntp.conf
dest: /etc/ntp.conf
owner: root
group: root
mode: '0644'
backup: yes
- name: Copy a new "sudoers" file into place, after passing validation with visudo
copy:
src: /mine/sudoers
dest: /etc/sudoers
validate: /usr/sbin/visudo -csf %s
- name: Copy a "sudoers" file on the remote machine for editing
copy:
src: /etc/sudoers
dest: /etc/sudoers.edit
remote_src: yes
validate: /usr/sbin/visudo -csf %s
- name: Copy using inline content
copy:
content: '# This file was moved to /etc/other.conf'
dest: /etc/mine.conf
- name: If follow=yes, /path/to/file will be overwritten by contents of foo.conf
copy:
src: /etc/foo.conf
dest: /path/to/link # link to /path/to/file
follow: yes
- name: If follow=no, /path/to/link will become a file and be overwritten by contents of foo.conf
copy:
src: /etc/foo.conf
dest: /path/to/link # link to /path/to/file
follow: no
# yum_repository模块
- 配置repo的yum源模块
name参数: 必须参数,用于指定要操作的唯一的仓库ID,也就是”.repo”配置文件中每个仓库对应的”中括号”内的仓库ID
baseurl参数: 此参数用于设置yum仓库的baseurl
description参数: 此参数用于设置仓库的注释,也就是”.repo”配置文件中每个仓库对应的”name字段”对应的内容。
file参数: 此参数用于设置仓库的配置文件名称,即设置”.repo”配置文件的文件名前缀,在不使用此参数的情况下,默认以name参数的仓库ID作为”.repo”配置文件的文件名前缀,同一个’.repo’配置文件中可以存在多个yum源
enabled参数: 此参数用于设置是否激活对应的yum源,此参数默认值为yes,表示启用对应的yum源,设置为no表示不启用对应的yum源。
gpgcheck参数: 此参数用于设置是否开启rpm包验证功能,默认值为no,表示不启用包验证,设置为yes表示开启包验证功能。
gpgcakey参数: 当gpgcheck参数设置为yes时,需要使用此参数指定验证包所需的公钥
state参数: 默认值为present,当值设置为absent时,表示删除对应的yum源
yum_repository模块的示例命令如下:
[root@server4 ~]# ansible testA -m yum_repository -a 'name=rhel7.3 description="ansible rhel7.3" baseurl=http://172.25.1.250/westos gpgcheck=no enabled=yes'
# yum模块
- yum源安装rpm包的管理模块
state:状态(present安装,absent卸载,latest最新的)
ansible websrvs -m yum -a 'list=httpd' 查看程序列表
ansible websrvs -m yum -a 'name=httpd state=present' 安装
ansible websrvs -m yum -a 'name=httpd state=absent' 删除
可以同时安装多个程序包
[root@ansible ~]# ansible test -m yum -a 'name=vsftpd,httpd,memcached'
更新缓存
[root@ansible ~]# ansible test -m yum -a 'name=dstat update_cache=yes'
- Playbook用法
- name: install the latest version of Apache
yum:
name: httpd
state: latest
- name: ensure a list of packages installed
yum:
name: "{{ packages }}"
vars:
packages:
- httpd
- httpd-tools
- name: remove the Apache package
yum:
name: httpd
state: absent
- name: install the latest version of Apache from the testing repo
yum:
name: httpd
enablerepo: testing
state: present
- name: install one specific version of Apache
yum:
name: httpd-2.2.29-1.4.amzn1
state: present
- name: upgrade all packages
yum:
name: '*'
state: latest
- name: upgrade all packages, excluding kernel & foo related packages
yum:
name: '*'
state: latest
exclude: kernel*,foo*
- name: install the nginx rpm from a remote repo
yum:
name: http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
state: present
- name: install nginx rpm from a local file
yum:
name: /usr/local/src/nginx-release-centos-6-0.el6.ngx.noarch.rpm
state: present
- name: install the 'Development tools' package group
yum:
name: "@Development tools"
state: present
- name: install the 'Gnome desktop' environment group
yum:
name: "@^gnome-desktop-environment"
state: present
- name: List ansible packages and register result to print with debug later.
yum:
list: ansible
register: result
- name: Install package with multiple repos enabled
yum:
name: sos
enablerepo: "epel,ol7_latest"
- name: Install package with multiple repos disabled
yum:
name: sos
disablerepo: "epel,ol7_latest"
- name: Install a list of packages
yum:
name:
- nginx
- postgresql
- postgresql-server
state: present
- name: Download the nginx package but do not install it
yum:
name:
- nginx
state: latest
download_only: true
# service模块
- 服务状态管理模块
enabled:[yes/no] 启动os后启动对应service的选项;是否开机启动
name:需要进行操作的service名字
state:[stared/stoped/restarted/reloaded] 服务最终操作后的状态
>ansible srv -m service -a 'name=httpd state=stopped' 停止服务
>ansible srv -m service -a 'name=httpd state=started enabled=yes' 启动服务,并设为开机自启
>ansible srv -m service -a 'name=httpd state=reloaded' 重新加载
>ansible srv -m service -a 'name=httpd state=restarted' 重启服务
- Playbook用法
- name: Start service httpd, if not started
service:
name: httpd
state: started
- name: Stop service httpd, if started
service:
name: httpd
state: stopped
- name: Restart service httpd, in all cases
service:
name: httpd
state: restarted
- name: Reload service httpd, in all cases
service:
name: httpd
state: reloaded
- name: Enable service httpd, and not touch the state
service:
name: httpd
enabled: yes
- name: Start service foo, based on running process /usr/bin/foo
service:
name: foo
pattern: /usr/bin/foo
state: started
- name: Restart network service for interface eth0
service:
name: network
state: restarted
args: eth0
# script模块
- 可以实现被控端上可以执行ansible控制端的脚本
示例:ansible test -m script -a '/4.40/www/2.sh'
在test组所有被控端执行ansible控制端中/4.40./www/目录下的2.sh
> -a "/PATH/TO/SCRIPT_FILE"
> ansible websrvs -m script -a /data/test.sh
- Playbook用法
- name: Run a script with arguments (free form)
script: /some/local/script.sh --some-argument 1234
- name: Run a script with arguments (using 'cmd' parameter)
script:
cmd: /some/local/script.sh --some-argument 1234
- name: Run a script only if file.txt does not exist on the remote node
script: /some/local/create_file.sh --some-argument 1234
args:
creates: /the/created/file.txt
- name: Run a script only if file.txt exists on the remote node
script: /some/local/remove_file.sh --some-argument 1234
args:
removes: /the/removed/file.txt
- name: Run a script using an executable in a non-system path
script: /some/local/script
args:
executable: /some/remote/executable
- name: Run a script using an executable in a system path
script: /some/local/script.py
args:
executable: python3
# fetch+file模块
- Fetch:从远程主机提取文件至主控端,copy相反,目前不支持目录,可以先打包,再提取文件
- File:设置文件属性
# Fetch:从远程主机提取文件至主控端,copy相反,目前不支持目录,可以先打包,再提取文件
> ansible websrvs -m fetch -a 'src=/root/test.sh dest=/data/scripts'
会生成每个被管理主机不同编号的目录,不会发生文件名冲突
> ansible all -m shell -a 'tar jxvf test.tar.gz /root/test.sh'
> ansible all -m fetch -a 'src=/root/test.tar.gz dest=/data/'
# File:设置文件属性
path: 要管理的文件路径 (强制添加)
recurse: 递归,文件夹要用递归
src: 创建硬链接,软链接时,指定源目标,配合'state=link' 'state=hard' 设置软链接,硬链接
state: 状态
absent 缺席,删除
> ansible websrvs -m file -a 'path=/app/test.txt state=touch' 创建文件
> ansible websrvs -m file -a "path=/data/testdir state=directory" 创建目录
> ansible websrvs -m file -a "path=/root/test.sh owner=wang mode=755" 设置权限755
> ansible websrvs -m file -a 'src=/data/testfile dest=/data/testfile-link state=link' 创建软链接
- playbook用法
- name: Change file ownership, group and permissions
file:
path: /etc/foo.conf
owner: foo
group: foo
mode: '0644'
- name: Give insecure permissions to an existing file
file:
path: /work
owner: root
group: root
mode: '1777'
- name: Create a symbolic link
file:
src: /file/to/link/to
dest: /path/to/symlink
owner: foo
group: foo
state: link
- name: Create two hard links
file:
src: '/tmp/{{ item.src }}'
dest: '{{ item.dest }}'
state: hard
loop:
- { src: x, dest: y }
- { src: z, dest: k }
# cron模块
- 定时任务的创建和删除管理
创建一个定时任务
[root@ansible ~]# ansible test -m cron -a 'minute=* weekday=1,3,5 job="/usr/bin/wall FBI waring" name=warningcron'
禁用一个定时任务
[root@ansible ~]# ansible test -m cron -a 'disabled=true job="/usr/bin/wall FBI waring" name=warningcron'
# unarchive模块
- 解压缩的管理模块,可以将本地ansible控制节点的包解压至node节点
creates: 一个文件名,当它已经存在时,这个步骤将不会被运行。
copy: 默认为yes,拷贝的文件从ansible主机复制到远程主机,no在远程主机上寻找src源文件解压
src: tar源路径,可以是ansible主机上的路径,也可以是远程主机上的路径,如果是远程主机上的路径,则需设置copy=no
dest: 远程主机上的目标绝对路径
mode: 设置解压缩后的文件权限
exec: 列出需要排除的目录和文件
remote_src: 设置remote_src=yes为解包目标上已经存在的档案。对于Windows目标,改用win_unzip模块。
owner: 解压后文件或目录的属主
group: 解压后的目录或文件的属组
在远程主机上解压文件并设置权限
[root@ansible ~]# ansible all -m unarchive -a 'src=/srv/tomcat8/apache-tomcat-8.0.29.tar.gz dest=/usr/local copy=no mode=0755'
解压ansible管理机上的压缩文件到远程主机并设置权限
[root@ansible ~]# ansible all -m unarchive -a "src=/tmp/install/zabbix-3.0.4.tar.gz dest=/tmp/ mode=0755 copy=yes"
- Playbook用法
- name: Extract foo.tgz into /var/lib/foo
unarchive:
src: foo.tgz
dest: /var/lib/foo
- name: Unarchive a file that is already on the remote machine
unarchive:
src: /tmp/foo.zip
dest: /usr/local/bin
remote_src: yes
- name: Unarchive a file that needs to be downloaded (added in 2.0)
unarchive:
src: https://example.com/example.zip
dest: /usr/local/bin
remote_src: yes
- name: Unarchive a file with extra options
unarchive:
src: /tmp/foo.zip
dest: /usr/local/bin
extra_opts:
- --transform
- s/^xxx/yyy/
# 利用模块快速部署
配置好hosts
[root@ansible ~]# ansible --list-hosts server
hosts (3):
192.168.1.107
192.168.1.108
192.168.1.110
使用模块操作子机
#使用COPY模块传送CentOS-Base.repo的yum源
[root@ansible ~]# ansible server -m copy -a "src=/root/CentOS-Base.repo dest=/etc/yum.repos.d/CentOS-Base.repo mode=600 backup=yes"
192.168.1.110 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"checksum": "4966466ad015ef3d2a3cc0b8252d43efbdcf2c94",
"dest": "/etc/yum.repos.d/CentOS-Base.repo",
"gid": 0,
"group": "root",
"md5sum": "d06fb7d5709727828bcaba7457ea673e",
"mode": "0600",
"owner": "root",
"secontext": "system_u:object_r:system_conf_t:s0",
"size": 2595,
"src": "/root/.ansible/tmp/ansible-tmp-1632059937.218095-11326-239583984569451/source",
"state": "file",
"uid": 0
}
..........
#使用shell模块检测yum源是否正常使用
[root@ansible ~]# ansible server -m shell -a "yum repolist all"
[WARNING]: Consider using the yum module rather than running 'yum'. If you need to use command because yum is insufficient you can add 'warn:
false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message.
192.168.1.110 | CHANGED | rc=0 >>
Updating Subscription Management repositories.
Unable to read consumer identity
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
repo id repo name status
AppStream CentOS-8 - AppStream - mirrors.aliyun.com enabled
PowerTools CentOS-8 - PowerTools - mirrors.aliyun.com disabled
base CentOS-8 - Base - mirrors.aliyun.com enabled
centosplus CentOS-8 - Plus - mirrors.aliyun.com disabled
extras CentOS-8 - Extras - mirrors.aliyun.com enabled
..........
#使用yum模块安装httpd服务
[root@ansible ~]# ansible -m yum -a "name=httpd state=present" server
192.168.1.108 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Installed: mailcap-2.1.48-3.el8.noarch",
"Installed: httpd-2.4.37-39.module_el8.4.0+778+c970deab.x86_64",
"Installed: httpd-filesystem-2.4.37-39.module_el8.4.0+778+c970deab.noarch",
"Installed: httpd-tools-2.4.37-39.module_el8.4.0+778+c970deab.x86_64",
"Installed: mod_http2-1.15.7-3.module_el8.4.0+778+c970deab.x86_64",
"Installed: centos-logos-httpd-85.8-1.el8.noarch",
"Installed: apr-1.6.3-11.el8.x86_64",
"Installed: apr-util-1.6.1-6.el8.x86_64",
"Installed: apr-util-bdb-1.6.1-6.el8.x86_64",
"Installed: apr-util-openssl-1.6.1-6.el8.x86_64"
]
}
..........
#使用shell模块远程开启,远程查看服务状态
[root@ansible ~]# ansible server -m shell -a "systemctl start httpd"
192.168.1.107 | CHANGED | rc=0 >>
192.168.1.108 | CHANGED | rc=0 >>
192.168.1.110 | CHANGED | rc=0 >>
[root@ansible ~]# ansible server -m shell -a "curl http://local:80"
^Z
[1]+ Stopped ansible server -m shell -a "curl http://local:80"
[root@ansible ~]# ansible server -m shell -a "systemctl status httpd"
192.168.1.110 | CHANGED | rc=0 >>
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: active (running) since Sun 2021-09-19 22:08:57 CST; 1min 24s ago
Docs: man:httpd.service(8)
Main PID: 11512 (httpd)
Status: "Running, listening on: port 80"
Tasks: 213 (limit: 11468)
Memory: 27.4M
CGroup: /system.slice/httpd.service
├─11512 /usr/sbin/httpd -DFOREGROUND
├─11612 /usr/sbin/httpd -DFOREGROUND
├─11613 /usr/sbin/httpd -DFOREGROUND
├─11614 /usr/sbin/httpd -DFOREGROUND
└─11615 /usr/sbin/httpd -DFOREGROUND
Sep 19 22:08:17 server3 systemd[1]: Starting The Apache HTTP Server...
Sep 19 22:08:57 server3 httpd[11512]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::4a92:a42e:da79:b4e6. Set the 'ServerName' directive globally to suppress this message
Sep 19 22:08:57 server3 systemd[1]: Started The Apache HTTP Server.
Sep 19 22:09:37 server3 httpd[11512]: Server configured, listening on: port 80
# 使用playbook的方式
[root@ansible ~]# vim playbook.yaml
---
- name: install httpd
hosts: server
tasks:
- name: install httpd
yum:
name: httpd
state: present
- name: service start
service:
name: httpd
state: started
enabled: yes
使用ansible-playbook部署
[root@ansible ~]# ansible-playbook playbook.yaml
PLAY [install httpd] ***********************************************************************************************
TASK [Gathering Facts] *********************************************************************************************
ok: [192.168.1.107]
ok: [192.168.1.108]
ok: [192.168.1.110]
TASK [install httpd] ***********************************************************************************************
ok: [192.168.1.110]
ok: [192.168.1.107]
ok: [192.168.1.108]
TASK [service start] ***********************************************************************************************
changed: [192.168.1.108]
changed: [192.168.1.107]
changed: [192.168.1.110]
PLAY RECAP *********************************************************************************************************
192.168.1.107 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.1.108 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.1.110 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansible ~]#
上次更新: 2023/11/28, 22:03:59