RHEL8.x-RedHat-Ansible

alex-rhel8.2 虚拟机

Anisble-练习环境说明
hostname:server1
ip:172.25.254.250/24
kiosk:redhat
root:Asimov
RHCE-RH294-172.25.254.250

control、node1-5
alice:alice
root:redhat

[kiosk@server1 ~]$ ip addr show
privbr0:
inet 172.25.250.254/24
inet 172.25.0.254/24
inet 172.25.254.254/24
inet 172.25.254.250/24 (xshell)

[root@server1 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6

172.25.0.254 server1.net0.example.com
172.25.0.25 alex01.net0.examle.com alex01
172.25.0.26 alex02.net0.examle.com alex02
172.25.254.254 classroom content classroom.example.com content.example.com
172.25.254.250 foundation0 foundation0.example.com study.lab0.example.com
172.25.254.100 control.lab0.example.com control con
172.25.254.101 node1.lab0.example.com node1 n1
172.25.254.102 node2.lab0.example.com node2 n2
172.25.254.103 node3.lab0.example.com node3 n3
172.25.254.104 node4.lab0.example.com node4 n4
172.25.254.105 node5.lab0.example.com node5 n5
172.25.0.220 registry.lab.example.com utility

[kiosk@server1 ~]$ rht-vmctl status all
Usage: rht-vmctl 子命令 虚拟机名称
子命令可以是:
start: 启动虚拟机
stop : 关闭虚拟机
reset: 重置虚拟机
虚拟机名称可以是:
red
blue
control
node1
node2
node3
node4
node5

[root@server1 ~]# virsh list --all
Id Name State

1 control running
2 node1 running
3 node2 running
4 node3 running
5 node4 running
6 node5 running

  • alex01                        shut off
    
  • alex02                        shut off
    
  • utility                        shut off
    

[root@server1 ~]# virsh start control
[root@server1 ~]# virsh shutdown control

切换用户
[kiosk@server1 ~]$ su - root
Password:Asimov

启动control 和 node1、node2、node3、node4、node5 六台服务器
[root@server1 ~]# rht-vmctl start control
Start control OK.
[root@server1 ~]# rht-vmctl start node1
Start node1 OK.
[root@server1 ~]# rht-vmctl start node2
Start node2 OK.
[root@server1 ~]# rht-vmctl start node3
Start node3 OK.
[root@server1 ~]# rht-vmctl start node4
Start node4 OK.
[root@server1 ~]# rht-vmctl start node5
Start node5 OK

[root@server1 ~]# ping control

[root@server1 ~]# ssh alice@control
alice@control’s password:alice

安装ansible
[alice@control ~]$ sudo dnf install -y ansible

查看 ansible 版本
[alice@control ~]$ ansible --version
ansible 2.8.5

测试验证 ansible 是否在工作(add-hoc临时命令)
测试 ansible ,表示ansible运行成功,参数 -m 表示 module 的意思
[alice@control ~]$ ansible -m ping localhost
localhost | SUCCESS => {
“changed”: false,
“ping”: “pong”
}

测试 control 到 node[1-5] 之间是否 SSH 免密
[alice@control ~]$ ssh alice@node1
[alice@node1 ~]$ exit

[alice@control ~]$ ssh alice@node2
[alice@node2 ~]$ exit

[alice@control ~]$ ssh alice@node3
[alice@node3 ~]$ exit

[alice@control ~]$ ssh alice@node4
[alice@node4 ~]$ exit

[alice@control ~]$ ssh alice@node5
[alice@node5 ~]$ exit
[alice@control ~]$

安装 ansible 后自动生成的文件
[alice@control ~]$ ls -l /etc/ansible/
-rw-r–r--. 1 root root 19980 Oct 11 2019 ansible.cfg
-rw-r–r--. 1 root root 1016 Oct 11 2019 hosts
drwxr-xr-x. 2 root root 6 Oct 11 2019 roles

参数解析
ansible.cfg -> 表示配置文件
hosts -> 表示资产清单文件
roles -> 表示角色
一般情况下,我们不使用默认的 hosts 作为清单文件,而是自定义一个清单,比如"alex-hosts"

在家目录创建 ansible 目录,并复制文件到家目录的 ansible
[alice@control ~]$ mkdir -p ~/ansible
[alice@control ~]$ cp -rfv /etc/ansible/ansible.cfg ansible/
[alice@control ~]$ cp -rfv /etc/ansible/hosts ansible/

当我们通过普通用户,进行远程连接的时候,需要做如下配置
[alice@control ~]$ vim ansible/ansible.cfg
15 inventory = /home/alice/ansible/alice-inventory
25 ask_pass = False
73 host_key_checking = False
107 remote_user = alice
341 [privilege_escalation]
342 become=True
343 become_method=sudo
344 become_user=root
345 become_ask_pass=False

/home/alice/ansible 目录创建 alice-inventory 文件
[alice@control ~]$ touch ansible/alice-inventory

编辑 alice-inventory 资产清单文件
[alice@control ~]$ vim ansible/alice-inventory
[network]
node1.lab0.example.com

[linux]
node[2:3].lab0.example.com

[os:children]
linux

[prod]
node[4:5].lab0.example.com

查看
[alice@control ~]$ ansible-inventory -i /home/alice/ansible/alice-inventory --list

ansible ping
[alice@control ~]$ ansible -m ping os -i ansible/alice-inventory
node2.lab0.example.com | SUCCESS => {
“ansible_facts”: {
“discovered_interpreter_python”: “/usr/libexec/platform-python”
},
“changed”: false,
“ping”: “pong”
}
node3.lab0.example.com | SUCCESS => {
“ansible_facts”: {
“discovered_interpreter_python”: “/usr/libexec/platform-python”
},
“changed”: false,
“ping”: “pong”
}

ansible 加载当前路径下的 ansible.cfg 配置文件
[alice@control ~]$ cd ansible/
[alice@control ansible]$ pwd
/home/alice/ansible
[alice@control ansible]$ ansible -m ping os
node2.lab0.example.com | SUCCESS => {
“ansible_facts”: {
“discovered_interpreter_python”: “/usr/libexec/platform-python”
},
“changed”: false,
“ping”: “pong”
}
node3.lab0.example.com | SUCCESS => {
“ansible_facts”: {
“discovered_interpreter_python”: “/usr/libexec/platform-python”
},
“changed”: false,
“ping”: “pong”
}

[alice@control ansible]$ pwd
/home/alice/ansible
[alice@control ansible]$ ansible -m ping network

yum 模块安装受管理节点的软件包
语法: ansible -m <主机或者主机组> -a “选项”
[alice@control ansible]$ ansible -m yum prod -a “name=httpd state=latest”
[alice@control ansible]$ ansible -m yum prod -a “name=httpd state=present”
[alice@control ansible]$ ansible -m yum prod -a “name=httpd state=absent”

参数解析
latest -> 更新为最新的版本
present -> 安装
absent -> remove 卸载

[alice@control ansible]$ ansible -m dnf prod -a “name=httpd state=latest”
[alice@control ansible]$ ansible -m dnf prod -a “name=httpd state=present”
[alice@control ansible]$ ansible -m dnf prod -a “name=httpd state=absent”

升级所有的包
[alice@control ansible]$ ansible -m dnf prod -a “name=’*’ state=latest”

组安装 yum groupinstall -y , 这个组内的所有包都会安装
name=’@Development tools’
[alice@control ansible]$ ansible -m dnf prod -a “name=’@Development tools’ state=latest”

shell 模块平时执行系统命令一样对主机组的节点进行命令的执行
[alice@control ansible]$ ansible -m shell prod -a “yum repolist -y all”

列出 ansible 已经支持的模块
[alice@control ansible]$ ansible-doc -l
[alice@control ansible]$ ansible-doc -l | grep -i yum
[alice@control ansible]$ ansible-doc -l | grep -i azure

查看有多少模块
[alice@control ansible]$ ansible-doc -l | wc -l
2834

查看模块的名称和内容
[alice@control ansible]$ ansible-doc -l | grep -i lvol

查看某一个模块的具体参数
[alice@control ansible]$ ansible-doc -s yum

##安装BaseOS软件仓库
[alice@control ansible]$ ansible -m yum_repository prod -a “baseurl=http://study.lab0.example.com/rhel8.2/BaseOS enabled=true file=‘BaseOS’ name=‘BaseOS’ gpgcheck=false description=‘This is BaseOS repofile’”

##安装AppStream软件仓库
[alice@control ansible]$ ansible -m yum_repository prod -a “baseurl=http://study.lab0.example.com/rhel8.2/AppStream enabled=true file=‘AppStream’ name=‘AppStream’ gpgcheck=false description=‘This is AppStream repofile’”

查看 /etc/yum.repos.d/ 目录内容
[alice@control ansible]$ ansible -m shell prod -a “ls -l /etc/yum.repos.d/”

ansible 方式通过 yum 模块,安装 httpd 服务
[alice@control ansible]$ ansible -m yum prod -a “name=httpd state=present”

ansible 方式通过 shell 模块,查看 httpd 信息
[alice@control ansible]$ ansible -m shell prod -a “yum -y info httpd”

安装BaseOS软件仓库,放在同一个 repo 文件中,通过 file 属性指定

[alice@control ansible]$ ansible -m yum_repository prod -a “baseurl=http://study.lab0.example.com/rhel8.2/BaseOS enabled=true file=‘alex’ name=‘BaseOS’ gpgcheck=false description=‘This is BaseOS repofile’”

[alice@control ansible]$ ansible -m yum_repository prod -a “baseurl=http://study.lab0.example.com/rhel8.2/AppStream enabled=true file=‘alex’ name=‘AppStream’ gpgcheck=false description=‘This is AppStream repofile’”

发现 BaseOS 和 AppStream 都在同一个文件
[alice@control ansible]$ ansible -m shell prod -a “cat /etc/yum.repos.d/alex.repo”

查看 ansible 文档模块
[alice@control ansible]$ ansible-doc -l | grep -i copy

查看 ansible copy 模块的具体参数
[alice@control ansible]$ ansible-doc -s copy

查看管理节点(control)的文件,ansible.repo
[alice@control ansible]$ ls -l /etc/yum.repos.d/
-rw-r–r--. 1 root root 81 Oct 30 2020 ansible.repo
-rw-r–r--. 1 root root 358 Oct 30 2020 redhat.repo
-rw-r–r--. 1 root root 179 Oct 30 2020 rhel8.repo

把管理节点的文件拷贝到被管理节点
control 拷贝到 node4 和 node5 节点
[alice@control ansible]$ ansible -m copy prod -a “src=/etc/yum.repos.d/ansible.repo dest=/etc/yum.repos.d/”

查看 node4 和 node5 被管理节点的 yum 状态
[alice@control ansible]$ ansible -m shell prod -a “yum repolist -y all”

copy 模块不一定非得是 src属性,可以没有源文件,content 属性表示内容,放到目标文件,\n表示换行

这是一种覆盖的方式,类似于重定向的 > 是覆盖的方式
[alice@control ansible]$ ansible -m copy prod -a “content=‘I Love \nLinux’ dest=/opt/alex.txt”
[alice@control ansible]$ ansible -m copy prod -a “content=‘I Love \nSpark’ dest=/opt/alex.txt”
[alice@control ansible]$ ansible -m copy prod -a “content=‘I Love \nScala\n’ dest=’/opt/alex.txt’ owner=‘alex’ group=‘alex’ mode=‘0550’ setype=‘httpd_sys_content_t’”
参数解析
owner: 属主
group: 属组
mode: 权限

通过 shell 模块查看
[alice@control ansible]$ ansible -m shell prod -a “cat /opt/alex.txt”

拷贝内容到目标文件,并设置文件类型
[alice@control ansible]$ ansible -m copy prod -a “content=‘hello,alex\nSpark\n’ dest=’/var/www/html/index.html’ mode=‘0550’ setype=‘httpd_sys_content_t’”

查看文件类型
[alice@control ansible]$ ansible -m shell prod -a “ls -lZ /var/www/html/index.html”
node4.lab0.example.com | CHANGED | rc=0 >>
-r-xr-x—. 1 root root system_u:object_r:httpd_sys_content_t:s0 17 Nov 27 16:22 /var/www/html/index.html

node5.lab0.example.com | CHANGED | rc=0 >>
-r-xr-x—. 1 root root system_u:object_r:httpd_sys_content_t:s0 17 Nov 27 16:22 /var/www/html/index.html

启动 httpd 服务,并设置开机自动启动
[alice@control ansible]$ ansible -m service prod -a “name=‘httpd’ enabled=‘yes’ state=‘started’”
state 状态有 started、stoped、restarted、reloaded

重启 httpd 服务
[alice@control ansible]$ ansible -m service prod -a “name=‘httpd’ state=‘restarted’”

赋予权限
[alice@control ansible]$ ansible -m shell prod -a "chmod -R 755 /var/www/html/index.html

访问
[alice@control ansible]$ ansible -m shell prod -a “curl -l http://127.0.0.1/”

设置 SELinux 安全性上下文
[alice@control ansible]$ ansible -m copy prod -a “content=‘hello,world\n’ dest=’/opt/a.txt’ owner=‘alex’ group=‘alice’ mode=‘755’ setype=‘httpd_sys_content_t’”
参数解析
owner:属主
group:属组
mode:权限

查看
[alice@control ansible]$ ansible -m shell prod -a “ls -lZ /opt/”

创建一个连接文件,测试未看到效果
[alice@control ansible]$ ansible -m copy prod -a “src=’/opt/module/control.file’ dest=’/mnt/test1’ follow=‘yes’”

file

[alice@control ansible]$ ansible -m file prod -a “path=’/opt/a.txt’ owner=‘alice’ group=‘alice’ mode=‘666’ setype=‘samba_share_t’”
参数解析
path:目标文件
owner:属主
group:属组
mode:权限
setype:修改 SELinux 的安全性上下文

查看
[alice@control ansible]$ ansible -m shell prod -a “ls -lZ /opt/”

state=‘touch’ 表示创建文件
[alice@control ansible]$ ansible -m file prod -a “path=’/opt/software’ owner=‘alice’ group=‘alice’ mode=‘666’ setype=‘samba_share_t’ state=‘touch’”

state=‘directory’ 表示创建目录
[alice@control ansible]$ ansible -m file prod -a “path=’/opt/soft/ware’ owner=‘alice’ group=‘alice’ mode=‘666’ setype=‘samba_share_t’ state=‘directory’”

[alice@control ansible]$ ansible -m file prod -a " src=’/mnt/test1’ path=’/opt/soft/test1’ owner=‘alice’ group=‘alice’ mode=‘666’ setype=‘samba_share_t’ state=‘link’"
state=‘link’ 表示软连接
state=‘hard’ 表示硬连接
当 state 表示为 link 或者 hard 的时候,需要指定 src属性
这里的 src 和 path 都表示 prod 组中的,不是 control 服务器

fetch -> 从被管理节点上拷贝文件到控制节点上
[alice@control ansible]$ ansible -m fetch prod -a “src=’/mnt/test1’ dest=’/home/alice/’”

[alice@control ansible]$ ansible -m fetch prod -a “src=’/mnt/test1’ dest=’/home/alice/’ flat=‘yes’”
参数解析
flat=‘yes’ 不拷贝被管理节点的目录结构
src=拷贝那个文件,这时候代表被管理节点
dest=目标路径,放到那个目录下面,这时候代表管理节点

lineinfile -> 最主要的功能在于替换
[alice@control ansible]$ ansible -m lineinfile prod -a “path=’/etc/sysconfig/selinux’ regexp=’^SELINUX=’ line=‘SELINUX=disabled’”
参数解析
path=’/etc/sysconfig/selinux’ 表示你要修改那个文件
regexp=’^SELINUX=’ 使用正则表达式的方式来匹配你要修改哪一行
line= 你要替换的内容

查看
[alice@control ansible]$ ansible -m shell prod -a “cat /etc/sysconfig/selinux”

参数 state=‘absent’ 的时候,表示删除,删除匹配的行
[alice@control ansible]$ ansible -m lineinfile prod -a “path=’/etc/sysconfig/selinux’ regexp=’^SELINUX=’ state=‘absent’”

insertbefore/insertafter=’^SELINUX=’ 使用正则表达式,来匹配行
insertbefore 在匹配的行之前插入内容
[alice@control ansible]$ ansible -m lineinfile prod -a “path=’/etc/sysconfig/selinux’ state=‘present’ insertbefore=’^SELINUX=’ line=‘I think i am right’”

insertafter 在匹配的行之后插入内容
[alice@control ansible]$ ansible -m lineinfile prod -a “path=’/etc/sysconfig/selinux’ state=‘present’ insertafter=’^SELINUX=’ line=‘I think i am after’”

查看
[alice@control ansible]$ ansible -m shell prod -a “cat /etc/sysconfig/selinux”
I think i am right
SELINUX=disabled
I think i am after

create=‘yes’ 在文件的末尾添加内容
[alice@control ansible]$ ansible -m lineinfile prod -a “path=’/etc/sysconfig/selinux’ line=‘qwe\nasd’ create=‘yes’”

查看
[alice@control ansible]$ ansible -m shell prod -a “cat /etc/sysconfig/selinux”

group 模块 -> 创建组
[alice@control ansible]$ ansible -m group prod -a “name=‘alexmk’ state=‘present’”

查看
[alice@control ansible]$ ansible -m shell prod -a “cat /etc/group”

group 模块 -> 删除组
[alice@control ansible]$ ansible -m group prod -a “name=‘alexmk’ state=‘absent’”

查看
[alice@control ansible]$ ansible -m shell prod -a “cat /etc/group”

user 模块 添加用户
[alice@control ansible]$ ansible -m user prod -a “name=‘testk’ state=‘present’”
参数解析
name -> 用户名
state=‘present’ 表示添加用户

查看
[alice@control ansible]$ ansible -m shell prod -a “cat /etc/passwd”
[alice@control ansible]$ ansible -m shell prod -a “ls -l /home/”

user 模块 删除用户
[alice@control ansible]$ ansible -m user prod -a “name=‘testk’ state=‘absent’ remove=‘yes’”
参数解析
state=‘absent’ 表示删除用户
remove=‘yes’ 表示删除用户的家目录

user 模块指定更多属性
[alice@control ansible]$ ansible -m user prod -a “name=‘testa’ state=‘present’ uid=‘1009’ group=‘alex’ comment=‘create a user’ shell=’/sbin/nologin’”
参数解析
name=‘testa’ 指定添加用户的用户名
state=‘present’ present表示添加 ,absent表示删除
uid=‘1009’ 指定uid
group=‘alex’ 指定所属组
groups=‘alice’ 指定的是附加组
comment=‘create a user’ 添加描述
shell=’/sbin/nologin’ 添加shell类型,此时这个用户的shell类型是不能登陆的

查看
[alice@control ansible]$ ansible -m shell prod -a “id testa”
node5.lab0.example.com | CHANGED | rc=0 >>
uid=1009(testa) gid=1001(alex) groups=1001(alex)

node4.lab0.example.com | CHANGED | rc=0 >>
uid=1009(testa) gid=1001(alex) groups=1001(alex)

groups=‘alice’ 指定的是附加组
[alice@control ansible]$ ansible -m user prod -a “name=‘testa’ state=‘present’ groups=‘alice’”

查看
[alice@control ansible]$ ansible -m shell prod -a “id testa”
node5.lab0.example.com | CHANGED | rc=0 >>
uid=1009(testa) gid=1001(alex) groups=1001(alex),1000(alice)

node4.lab0.example.com | CHANGED | rc=0 >>
uid=1009(testa) gid=1001(alex) groups=1001(alex),1000(alice)

与防火墙有关的模块
[alice@control ansible]$ ansible -m firewalld prod -a “zone=‘home’ source=‘172.25.250.0/24’ state=‘enabled’ permanent=‘yes’ immediate=‘yes’”
参数解析
zone=‘home’ 要关联的 zone 名
source=‘172.25.250.0/24’ 那个源关联 zone 名
state=‘enabled’ 启动这个规则
permanent=‘yes’ 永久生效
immediate=‘yes’ 立即生效

防火墙->配置基本规则
[alice@control ansible]$ ansible -m firewalld prod -a “service=‘http’ state=‘enabled’ permanent=‘yes’ immediate=‘yes’”

[alice@control ansible]$ ansible -m firewalld prod -a “service=‘http’ state=‘disabled’ permanent=‘yes’ immediate=‘yes’ zone=‘home’”
参数解析
state=‘disabled’ 表示不启动这个规则

与系统命令有关的模块
[alice@control ansible]$ ansible -m shell prod -a “df -TH”

与网络工具有关的模块
[alice@control ~]$ ansible -m get_url prod -a “url=‘http://content.example.com/ks/rh294-serverarc.local’ dest=’/mnt’ mode=‘0644’”
参数解析
url:资源路径
dest:存放路径
mode:权限

[alice@control ansible]$ ansible -m uri prod -a “url=‘http://content.example.com’”
uri:用户 和 web http 进行交互

[alice@control ansible]$ ansible -m shell prod -a “ip addr show”

day09 ============================================================================================================================ day09
Playbook

查看资产清单
[alice@control ansible]$ ansible-inventory --list
[alice@control ansible]$ ansible --list all
[alice@control ansible]$ cat alice-inventory
[network]
node1.lab0.example.com

[linux]
node[2:3].lab0.example.com

[os:children]
linux

[prod]
node[4:5].lab0.example.com

查看模块
[alice@control ansible]$ ansible-doc -l | grep -i yum

查看某一个模块的具体参数
[alice@control ansible]$ ansible-doc -s yum_repository

打开浏览器
[root@server1 ~]# firefox

查看主机名称
[alice@control ~]$ hostnamectl

查看yum repo文件
[alice@control ~]$ cat /etc/yum.repos.d/rhel8.repo
[appstream]
name=appstream
baseurl=http://study.lab0.example.com/rhel8.2/AppStream
gpgcheck=0
[baseos]
name=baseos
baseurl=http://study.lab0.example.com/rhel8.2/BaseOS
gpgcheck=0

[alice@control ansible]$ pwd
/home/alice/ansible
[alice@control ansible]$ touch yum.sh
[alice@control ansible]$ chmod 755 yum.sh
[alice@control ansible]$ vim yum.sh
:set paste 进入粘贴模式
i
#!/bin/bash
ansible -m yum_repository all -a “name=‘EX294_BASE’ file=‘EX294_BASE’ description=‘EX294 base software’ baseurl=‘http://content.example.com/rhel8.2/BaseOS’ gpgcheck=‘yes’ gpgkey=‘http://content.example.com/rhel8.2/RPM-GPG-KEY-redhat-release’ enabled=‘yes’”
ansible -m yum_repository all -a “name=‘EX294_STREAM’ file=‘EX294_STREAM’ description=‘EX294 stream software’ baseurl=‘http://content.example.com/rhel8.2/AppStream’ gpgcheck=‘yes’ gpgkey=‘http://content.example.com/rhel8.2/RPM-GPG-KEY-redhat-release’ enabled=‘yes’”
ansible -m shell all -a “rpm --import http://content.example.com/rhel8.2/RPM-GPG-KEY-redhat-release”

查看并验证
[alice@control ansible]$ ansible -m shell all -a “ls -l /etc/yum.repos.d/”
[alice@control ansible]$ ansible -m shell all -a “yum repolist --all”
[alice@control ansible]$ ansible -m shell all -a “cat /etc/yum.repos.d/EX294*”

创建 yml 文件
[alice@control ansible]$ touch test.yml

编辑 yml 文件
[alice@control ansible]$ vim test.yml

  • name: this is a test yml file
    hosts: network,os,prod
    tasks:
    • name: test install vsftpd package
      yum:
      name: vsftpd
      state: latest

查看 ansible-playbook 帮助文档
[alice@control ansible]$ ansible-playbook --help

通过 --syntax-check 参数,检查 yml 文件语法是否有问题
[alice@control ansible]$ ansible-playbook --syntax-check test.yml
playbook: test.yml

通过 -C 参数,进行预执行测试,不是真的执行
#空运行,确认模块的参数、执行的效果是否达到我们的预期
[alice@control ansible]$ ansible-playbook -C test.yml

检查是否有安装上
[alice@control ansible]$ ansible -m shell network -a “yum info -y vsftpd”

#真正的执行playbook
[alice@control ansible]$ ansible-playbook test.yml

再次检查是否有安装上
[alice@control ansible]$ ansible -m shell network -a “yum info -y vsftpd”

#设置vim支持对yaml格式的识别以及格式上的自动对齐。
[alice@control ansible]$ vim ~/.vimrc
autocmd FileType yaml setlocal ai ts=2 sw=2 et

编写一个简单的playbook
[alice@control ansible]$ touch adduser.yml
[alice@control ansible]$ vim adduser.yml

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check adduser.yml

假执行
[alice@control ansible]$ ansible-playbook -C adduser.yml

真执行
[alice@control ansible]$ ansible-playbook -C adduser.yml

查看验证
[alice@control ansible]$ ansible -m shell prod -a “id alex123”

编写一个较为复杂的 playbook
在 node[1:5] 主机组中,安装 httpd 服务,并且配置防火墙等等操作
1)任务安装包
2)给一个页面文件
3)8080 端口访问,修改配置文件
4)防火墙
[alice@control ansible]$ touch http.yml
[alice@control ansible]$ vim http.yml

  • name: httpd
    hosts: network,os,prod
    tasks:
    • name: install httpd package
      yum:
      name: httpd
      state: latest

    • name: web content
      copy:
      content: “Test first playbook\n”
      dest: /var/www/html/index.html
      setype: httpd_sys_content_t
      mode: 0666

    • name: modify httpd configurations
      lineinfile:
      path: /etc/httpd/conf/httpd.conf
      regexp: ^Listen
      line: “Listen 8080”
      state: present

    • name: start firewalld service
      service:
      name: firewalld
      enabled: true
      state: started

    • name: modify firewalld rule
      firewalld:
      port: 8080/tcp
      immediate: yes
      permanent: yes
      state: enabled

    • name: start httpd service
      service:
      name: httpd
      enabled: true
      state: started

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check http.yml
playbook: http.yml

空执行,假执行,做检查使用
[alice@control ansible]$ ansible-playbook -C http.yml

真执行
[alice@control ansible]$ ansible-playbook http.yml

查看并验证
[alice@control ansible]$ ansible -m shell network -a “systemctl status httpd”
[alice@control ansible]$ ansible -m shell network -a “firewall-cmd --list-all”

[alice@control ansible]$ touch install.yml
[alice@control ansible]$ vim install.yml

  • name: this is a test yml file
    hosts: network,os,prod
    tasks:
    • name: test install vsftpd package
      yum:
      name: vsftpd
      state: latest

    • name: start vsftpd service
      service:
      name: vsftpd
      state: started
      enabled: yes

    • name: start firewalld service
      service:
      name: firewalld
      state: started
      enabled: yes

    • name: modify firewalld port
      firewalld:
      port: 21/tcp
      permanent: yes
      immediate: yes
      state: enabled

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check install.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook -C install.yml

真执行
[alice@control ansible]$ ansible-playbook install.yml

验证
[alice@control ansible]$ ansible -m shell network -a “systemctl status vsftpd”
[alice@control ansible]$ ansible -m shell network -a “firewall-cmd --list-all”

变量1 -> 在 playbook 中定义变量
[alice@control ansible]$ cp install.yml install-vars.yml
[alice@control ansible]$ vim install-vars.yml

  • name: this is a test yml file
    hosts: network,os,prod
    vars:
    package_name: httpd
    service_name: httpd
    service_port: 80
    tasks:
    • name: install httpd package
      yum:
      name: “{{ package_name }}”
      state: latest

    • name: start httpd service
      service:
      name: “{{ service_name }}”
      state: started
      enabled: yes

    • name: start firewalld service
      service:
      name: firewalld
      state: started
      enabled: yes

    • name: modify firewalld port
      firewalld:
      port: “{{ service_port }}/tcp”
      permanent: yes
      immediate: yes
      state: enabled

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check install-vars.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook -C install-vars.yml

真执行
[alice@control ansible]$ ansible-playbook install-vars.yml

查看并验证
[alice@control ansible]$ ansible -m shell network -a “systemctl status httpd”
[alice@control ansible]$ ansible -m shell network -a “firewall-cmd --list-all”

变量2 -> 在 Playbook 外部中加载变量文件
[alice@control ansible]$ touch packages.yml
[alice@control ansible]$ vim packages.yml

  • package_name: httpd
    service_name: httpd
    service_port: 80

[alice@control ansible]$ cp install-vars.yml install-vars2.yml
[alice@control ansible]$ vim install-vars2.yml

  • name: this is a test yml file
    hosts: network,os,prod
    vars_files:
    • /home/alice/ansible/packages.yml
      tasks:

    • name: install httpd package
      yum:
      name: “{{ package_name }}”
      state: latest

    • name: start httpd service
      service:
      name: “{{ service_name }}”
      state: started
      enabled: yes

    • name: start firewalld service
      service:
      name: firewalld
      state: started
      enabled: yes

    • name: modify firewalld port
      firewalld:
      port: “{{ service_port }}/tcp”
      permanent: yes
      immediate: yes
      state: enabled

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check install-vars2.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook -C install-vars2.yml

真执行
[alice@control ansible]$ ansible-playbook install-vars2.yml

查看并验证
[alice@control ansible]$ ansible -m shell network -a “systemctl status httpd”
[alice@control ansible]$ ansible -m shell network -a “firewall-cmd --list-all”

变量3 -> 在执行剧本的时候,定义变量
[alice@control ansible]$ cp install-vars2.yml install-vars3.yml
[alice@control ansible]$ vim install-vars3.yml

  • name: this is a test yml file
    hosts: network,os,prod
    tasks:
    • name: install httpd package
      yum:
      name: “{{ package_name }}”
      state: latest

    • name: start httpd service
      service:
      name: “{{ service_name }}”
      state: started
      enabled: yes

    • name: start firewalld service
      service:
      name: firewalld
      state: started
      enabled: yes

    • name: modify firewalld port
      firewalld:
      port: “{{ service_port }}/tcp”
      permanent: yes
      immediate: yes
      state: enabled

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check install-vars3.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook -e package_name=httpd -e service_name=httpd -e service_port=83 -C install-vars3.yml

真执行
[alice@control ansible]$ ansible-playbook -e package_name=httpd -e service_name=httpd -e service_port=82 install-vars3.yml

查看并验证
[alice@control ansible]$ ansible -m shell network -a “systemctl status httpd”
[alice@control ansible]$ ansible -m shell network -a “firewall-cmd --list-all”

变量3 -> 在执行剧本的时候,定义变量 -> 安装 mariadb
[alice@control ansible]$ vim install-vars3.yml

  • name: this is a test yml file
    hosts: network,os,prod
    tasks:
    • name: install {{ package_name }} package
      yum:
      name: “{{ package_name }}”
      state: latest

    • name: start {{ service_name }} service
      service:
      name: “{{ service_name }}”
      state: started
      enabled: yes

    • name: start firewalld service
      service:
      name: firewalld
      state: started
      enabled: yes

    • name: modify firewalld port
      firewalld:
      port: “{{ service_port }}/tcp”
      permanent: yes
      immediate: yes
      state: enabled

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check install-vars3.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook -e package_name=mariadb-server -e service_name=mariadb -e service_port=3306 -C install-vars3.yml

真执行
[alice@control ansible]$ ansible-playbook -e package_name=mariadb-server -e service_name=mariadb -e service_port=3306 install-vars3.yml

查看并验证
[alice@control ansible]$ ansible -m shell network -a “systemctl status mariadb”
[alice@control ansible]$ ansible -m shell network -a “firewall-cmd --list-all”
[alice@control ansible]$ ansible -m shell network -a “ss -tunpa | grep 3306”

变量4 -> 在 inventory 资产清单文件内定义变量
[alice@control ansible]$ vim alice-inventory

[network]
node1.lab0.example.com

[linux]
node[2:3].lab0.example.com

[os:children]
linux

[prod]
node[4:5].lab0.example.com

[network:vars]
package_name=httpd
service_name=httpd
service_port=80

[alice@control ansible]$ cp install-vars3.yml install-vars4.yml
[alice@control ansible]$ vim install-vars4.yml

  • name: this is a test yml file
    hosts: network,os,prod
    tasks:
    • name: install {{ package_name }} package
      yum:
      name: “{{ package_name }}”
      state: latest
      when: inventory_hostname in groups[‘network’]

    • name: start {{ service_name }} service
      service:
      name: “{{ service_name }}”
      state: started
      enabled: yes
      when: inventory_hostname in groups.network

    • name: start firewalld service
      service:
      name: firewalld
      state: started
      enabled: yes
      when: inventory_hostname in groups[‘network’]

    • name: modify firewalld port
      firewalld:
      port: “{{ service_port }}/tcp”
      permanent: yes
      immediate: yes
      state: enabled
      when: inventory_hostname in groups[‘network’]

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check install-vars4.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook -C install-vars4.yml

真执行
[alice@control ansible]$ ansible-playbook install-vars4.yml

查看并验证
[alice@control ansible]$ ansible -m shell network -a “systemctl status httpd”
[alice@control ansible]$ ansible -m shell network -a “firewall-cmd --list-all”

#when条件 -> 筛选主机组
when: inventory_hostname in groups.network
when: inventory_hostname in groups[‘network’]

管理机密文件 -> ansible-vault
[alice@control ansible]$ ansible-vault -h
[alice@control ansible]$ ansible-vault --help
Usage: ansible-vault [create|decrypt|edit|encrypt|encrypt_string|rekey|view] [options] [vaultfile.yml]
encryption/decryption utility for Ansible data files
Options:
–ask-vault-pass ask for vault password
-h, --help show this help message and exit
–new-vault-id=NEW_VAULT_ID
the new vault identity to use for rekey
–new-vault-password-file=NEW_VAULT_PASSWORD_FILE
new vault password file for rekey
–vault-id=VAULT_IDS the vault identity to use
–vault-password-file=VAULT_PASSWORD_FILES
vault password file
-v, --verbose verbose mode (-vvv for more, -vvvv to enable
connection debugging)
–version show program’s version number, config file location,
configured module search path, module location,
executable location and exit
See ‘ansible-vault --help’ for more information on a specific
command.

1)新建一个具有加密的yml文件
[alice@control ansible]$ ansible-vault create vault1.yml
New Vault password: 123
Confirm New Vault password: 123

  • name: user
    hosts: all
    tasks:
    • name: delete alex user
      user:
      name: alex
      state: absent

vim 和 cat 查看都是加密文件
[alice@control ansible]$ vim vault1.yml
[alice@control ansible]$ cat vault1.yml
$ANSIBLE_VAULT;1.1;AES256
36313435326662643038623736303635636434376235336334343337343966383562343935366335
6164613266306630633837653133663565643264323736300a396137626664383430386636626131
65326461393665663864653936653136376161316265666463636533313232363030336337613138
3738393564386533650a633131626265643839626233613062316435653664373662396230316636
61323564333961386639633230313733666536343165326131333834646637666664656366313861
30353537646264336434313037303064366333353861643132313833613739306234643833316335
39353039633262303662383237326431653530343738303361653532616639356131326430666364
31353334323266313131396636663230333335323961316531323535373039326364353439653961
61363865646131316236663765346635346664323162303031346166373139316331303138373231
34636665396136383963363432363031323032393161353836613233353563636633396638353038
386262356337646361323965303364366131

查看加密文件
[alice@control ansible]$ ansible-vault view vault1.yml
Vault password: 123

  • name: user
    hosts: all
    tasks:
    • name: delete alex user
      user:
      name: alex
      state: absent

编辑加密文件
[alice@control ansible]$ ansible-vault edit vault1.yml
Vault password: 123

加密文件必须输入密码,使用 --ask-vault-pass 参数
[alice@control ansible]$ ansible-playbook --syntax-check vault1.yml
ERROR! Attempting to decrypt but no vault secrets found

检查语法
[alice@control ansible]$ ansible-playbook --ask-vault-pass --syntax-check vault1.yml
Vault password: 123
playbook: vault1.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook --ask-vault-pass -C vault1.yml

真执行
[alice@control ansible]$ ansible-playbook --ask-vault-pass vault1.yml

2)现有的 yml 文件,进行 vault 加密
对 test.yml 文件进行加密
[alice@control ansible]$ ansible-vault encrypt test.yml
New Vault password:
Confirm New Vault password:
Encryption successful

vim 和 cat 看到的都是加密文件
[alice@control ansible]$ vim test.yml
[alice@control ansible]$ cat test.yml
$ANSIBLE_VAULT;1.1;AES256
34363462376631623162356132643334313938656635376232363430323862383035356362343939
3036306337333636346161313535653766363238383833610a333635373632323132363530633437
61383566656436666132616161346334613131346135373934396137373161303538343335643830
6536633964633032310a383761333631653265323663383533333234643335306637646530663131
62666135343061386235313632633063626134346164663434393161316334306362386537376238
34343937333263383133316166633635343562663865386531653538313438653431646333376666
63366239326134346536343137616231373264373135316661396137313866646234376534333933
31363334343833623865343562326432393733386238626634626366633339323365356237356533
34386139656339383966643935353231353937323435373964663162306338616666326265363264
31633063623136376338313634303334303032633162353532396162336335356164376363363436
36303633666337653931646236393931346438636439303365383332313666343933656133623630
61343533613131363862336363653434656538323730363531303566643030343363363736376264
63653933643430303832373831303962613830626165356536353464313536653132

编辑加密文件
[alice@control ansible]$ ansible-vault edit test.yml
Vault password: 123

  • name: this is a test yml file
    hosts: network,os,prod
    tasks:
    • name: test install vsftpd package
      yum:
      name: vsftpd
      state: latest

3)指定 vault 密码文件的方式
[alice@control ansible]$ echo ‘123’ > password
[alice@control ansible]$ ansible-vault encrypt --vault-password-file=password test1.yml
Encryption successful

编辑
[alice@control ansible]$ ansible-vault edit --vault-password-file=password test1.yml

查看
[alice@control ansible]$ ansible-vault view --vault-password-file=password test1.yml

  • name: this is a test yml file
    hosts: network,os,prod
    tasks:
    • name: test install vsftpd package
      yum:
      name: vsftpd
      state: latest

检查语法
[alice@control ansible]$ ansible-playbook --vault-password-file=password --syntax-check test1.yml
playbook: test1.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook --vault-password-file=password -C test1.yml

真执行
[alice@control ansible]$ ansible-playbook --vault-password-file=password test1.yml

4)更新现有的key
[alice@control ansible]$ ansible-vault rekey vault1.yml
Vault password: 123
New Vault password: qwe
Confirm New Vault password: qwe
Rekey successful

5)解密key,解密加密文件
[alice@control ansible]$ ansible-vault decrypt vault1.yml
Vault password: qwe
Decryption successful

解密后的文件,cat 和 vim 编辑都可以看到明文了
[alice@control ansible]$ vim vault1.yml
[alice@control ansible]$ cat vault1.yml

  • name: user
    hosts: all
    tasks:
    • name: delete alex user
      user:
      name: alex
      state: absent

管理事实
管理事实 -> 设置内置变量
gather_facts: no|yes
默认为yes,如果设置为no,则在此playbook中是不能调用内置变量

编写创建用户 createuser.yml
[alice@control ansible]$ touch createuser.yml
[alice@control ansible]$ vim createuser.yml

  • name: users
    hosts: all
    tasks:
    • name: create users
      user:
      name: “{{ item.user_name }}”
      comment: “{{ item.user_comment }}”
      shell: “{{ item.user_shell }}”
      state: present
      loop:
      • { user_name: “alex666”,user_comment: “IT”,user_shell: “/bin/bash” }
      • { user_name: “alex777”,user_comment: “dev”,user_shell: “/sbin/nologin” }
      • { user_name: “alex888”,user_comment: “prod”,user_shell: “/bin/bash” }
        when: inventory_hostname in groups.linux

loop 是遍历的意思

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check createuser.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook -C createuser.yml

设置 gather_facts: no
[alice@control ansible]$ cp createuser.yml gather_facts.yml
[alice@control ansible]$ vim gather_facts.yml

  • name: users
    hosts: all
    gather_facts: no
    tasks:
    • name: create users
      user:
      name: “{{ item.user_name }}”
      comment: “{{ item.user_comment }}”
      shell: “{{ item.user_shell }}”
      state: present
      loop:
      • { user_name: “alex666”,user_comment: “IT”,user_shell: “/bin/bash” }
      • { user_name: “alex777”,user_comment: “dev”,user_shell: “/sbin/nologin” }
      • { user_name: “alex888”,user_comment: “prod”,user_shell: “/bin/bash” }
        when: inventory_hostname in groups.linux

loop 是遍历的意思

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check gather_facts.yml
playbook: gather_facts.yml

空执行,假执行,发现不收集内置变量了
[alice@control ansible]$ ansible-playbook -C gather_facts.yml

查看 debug 模块的参数信息
[alice@control ansible]$ ansible-doc -s debug

gather_facts 设置为 yes,添加debug模块
[alice@control ansible]$ cp gather_facts.yml gather_facts2.yml
[alice@control ansible]$ vim gather_facts2.yml

  • name: users
    hosts: all
    gather_facts: yes
    tasks:
    • name: create users
      user:
      name: “{{ item.user_name }}”
      comment: “{{ item.user_comment }}”
      shell: “{{ item.user_shell }}”
      state: present
      loop:

      • { user_name: “alex666”,user_comment: “IT”,user_shell: “/bin/bash” }
      • { user_name: “alex777”,user_comment: “dev”,user_shell: “/sbin/nologin” }
      • { user_name: “alex888”,user_comment: “prod”,user_shell: “/bin/bash” }
        when: inventory_hostname in groups.linux
    • name: debug
      debug:
      var: ansible_facts

loop 是遍历的意思

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check gather_facts2.yml
playbook: gather_facts2.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook -C gather_facts2.yml

setup 模块进行查看
[alice@control ansible]$ ansible -m setup network > a.txt

[alice@control ansible]$ vim a.txt
[alice@control ansible]$ grep ‘hostname’ a.txt
“ansible_hostname”: “node1”,
[alice@control ansible]$ cat a.txt | grep -i hostname
“ansible_hostname”: “node1”,

ansible_hostname
ansible_eth0 ipv4 address = IP地址

##获取主机名(基于简单的变量)
[alice@control ansible]$ cp gather_facts2.yml gather_facts3.yml
[alice@control ansible]$ vim gather_facts3.yml

  • name: users
    hosts: all
    gather_facts: yes
    tasks:
    • name: debug
      debug:
      var: ansible_facts[‘hostname’]

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check gather_facts3.yml
playbook: gather_facts3.yml

空执行,假执行 -> 获取hostname变量
[alice@control ansible]$ ansible-playbook -C gather_facts3.yml

##获取IP地址:(基于带有层级结构的变量)
[alice@control ansible]$ cp gather_facts3.yml gather_facts4.yml
[alice@control ansible]$ vim gather_facts4.yml

  • name: users
    hosts: all
    gather_facts: yes
    tasks:
    • name: debug
      debug:
      var: ansible_facts[‘eth0’][‘ipv4’][‘address’]

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check gather_facts4.yml
playbook: gather_facts4.yml

空执行,假执行 -> 获取 IP 地址变量值
[alice@control ansible]$ ansible-playbook -C gather_facts4.yml

#循环:
循环1 -> 简单循环
[alice@control ansible]$ touch useradd.yml
[alice@control ansible]$ vim useradd.yml

  • name: users
    hosts: all
    tasks:
    • name: create users
      user:
      name: “{{ item }}”
      state: present
      loop:
      • alex123
      • alex456
        when: inventory_hostname in groups.linux

loop 是遍历的意思

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check useradd.yml
playbook: useradd.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook -C useradd.yml

真执行
[alice@control ansible]$ ansible-playbook useradd.yml

查看验证
[alice@control ansible]$ ansible -m shell linux -a “tail -2 /etc/passwd”

循环2 -> 数组方式循环
[alice@control ansible]$ cp useradd.yml useradd2.yml
[alice@control ansible]$ vim useradd2.yml

  • name: users
    hosts: all
    vars:
    user_name:
    - mk111
    - mk222
    tasks:
    • name: create users
      user:
      name: “{{ item }}”
      state: present
      loop: “{{ user_name }}”
      when: inventory_hostname in groups.linux

loop 是遍历的意思

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check useradd2.yml
playbook: useradd2.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook -C useradd2.yml

真执行
[alice@control ansible]$ ansible-playbook useradd2.yml

查看验证
[alice@control ansible]$ ansible -m shell linux -a “tail -2 /etc/passwd”

循环3 -> 字典方式循环
[alice@control ansible]$ cp useradd2.yml useradd3.yml
[alice@control ansible]$ vim useradd3.yml

  • name: users
    hosts: all
    tasks:
    • name: create users
      user:
      name: “{{ item.user_name }}”
      comment: “{{ item.user_comment }}”
      shell: “{{ item.user_shell }}”
      state: present
      loop:
      • { user_name: “alex666”,user_comment: “IT”,user_shell: “/bin/bash” }
      • { user_name: “alex777”,user_comment: “dev”,user_shell: “/sbin/nologin” }
      • { user_name: “alex888”,user_comment: “prod”,user_shell: “/bin/bash” }
        when: inventory_hostname in groups.linux

loop 是遍历的意思

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check useradd3.yml
playbook: useradd3.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook -C useradd3.yml

真执行
[alice@control ansible]$ ansible-playbook useradd3.yml

查看验证
[alice@control ansible]$ ansible -m shell linux -a “tail -2 /etc/passwd”

playbook 卸载安装包
[alice@control ansible]$ touch remove.yml
[alice@control ansible]$ vim remove.yml

  • name: remove httpd
    hosts: all
    tasks:
    • name: remove httpd packages
      yum:
      name: httpd
      state: absent

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check remove.yml
playbook: remove.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook -C remove.yml

真执行
[alice@control ansible]$ ansible-playbook remove.yml

查看验证
[alice@control ansible]$ ansible -m shell all -a “rpm -qa | grep -i httpd”

when -> 通过查找变量 rc 的值来进行判断
[alice@control ansible]$ touch when-httpd.yml
[alice@control ansible]$ vim when-httpd.yml

  • name: when httpd
    hosts: all
    tasks:
    • name: test if installed httpd
      shell: rpm -qa | grep -i httpd
      register: package_name

    • name: install httpd packages
      yum:
      name: httpd
      state: latest
      when: “package_name.rc == 0”

    • name: debug
      debug:
      var: package_name

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check when-httpd.yml
playbook: when-httpd.yml

执行
[alice@control ansible]$ ansible-playbook when-httpd.yml

查看并验证
[alice@control ansible]$ ansible -m shell all -a “rpm -qa | grep -i httpd”

when: “package_name.rc == 0” 表示安装
when: “not package_name.rc != 0” 表示安装

when -> 通过判断 卸载 httpd 服务
[alice@control ansible]$ cp when-httpd.yml when-httpd2.yml
[alice@control ansible]$ vim when-httpd2.yml

  • name: when httpd
    hosts: all
    tasks:
    • name: test if installed httpd
      shell: rpm -qa | grep -i httpd
      register: package_name

    • name: uninstall httpd packages
      yum:
      name: httpd
      state: absent
      when: “not package_name.rc”

    • name: debug
      debug:
      var: package_name

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check when-httpd2.yml
playbook: when-httpd2.yml

查看并验证
[alice@control ansible]$ ansible -m shell all -a “rpm -qa | grep -i httpd”

day10 =============================================================================================================================================================================== day10

程序处理
程序处理 -> lineinfile 进行内容替换

查看 lineinfile 模块的详细参数
[alice@control ansible]$ ansible-doc -s lineinfile

当查看到参数有(required)的参数时,表示这个参数是必须的

lineinfile 模块 ansible 实现方式,初体验

lineinfile -> 最主要的功能在于替换
[alice@control ansible]$ ansible -m lineinfile all -a “path=’/etc/sysconfig/selinux’ regexp=’^SELINUX=’ line=‘SELINUX=disabled’”
参数解析
path=’/etc/sysconfig/selinux’ 表示你要修改那个文件
regexp=’^SELINUX=’ 使用正则表达式的方式来匹配你要修改哪一行
line= 你要替换的内容

查看
[alice@control ansible]$ ansible -m shell all -a “cat /etc/sysconfig/selinux”

insertbefore/insertafter=’^SELINUX=’ 使用正则表达式,来匹配行
insertbefore 在匹配的行之前插入内容
[alice@control ansible]$ ansible -m lineinfile all -a “path=’/etc/sysconfig/selinux’ state=‘present’ insertbefore=’^SELINUX=’ line=‘I think i am right’”

insertafter 在匹配的行之后插入内容
[alice@control ansible]$ ansible -m lineinfile all -a “path=’/etc/sysconfig/selinux’ state=‘present’ insertafter=’^SELINUX=’ line=‘I think i am after’”

查看
[alice@control ansible]$ ansible -m shell all -a “cat /etc/sysconfig/selinux”
I think i am right
SELINUX=disabled
I think i am after

参数 state=‘absent’ 的时候,表示删除,删除匹配的行
[alice@control ansible]$ ansible -m lineinfile all -a “path=’/etc/sysconfig/selinux’ regexp=’^I think’ state=‘absent’”

create=‘yes’ 在文件的末尾添加内容
[alice@control ansible]$ ansible -m lineinfile all -a “path=’/etc/sysconfig/selinux’ line=‘qweasd’ create=‘yes’”

查看
[alice@control ansible]$ ansible -m shell all -a “cat /etc/sysconfig/selinux”

参数 state=‘absent’ 的时候,表示删除,删除匹配的行
[alice@control ansible]$ ansible -m lineinfile all -a “path=’/etc/sysconfig/selinux’ regexp=’^qweasd’ state=‘absent’”

查看
[alice@control ansible]$ ansible -m shell all -a “cat /etc/sysconfig/selinux”

lineinfile 模块 ansible-playbook 实现方式

获取 SELinux
[alice@control ansible]$ ansible -m shell linux -a “getenforce”

临时修改
[alice@control ansible]$ ansible -m shell linux -a “setenforce 0”

[alice@control ansible]$ touch lineinfile.yml
[alice@control ansible]$ vim lineinfile.yml

  • name: Linux SELinux
    hosts: all
    tasks:
    • name: disable selinux
      lineinfile:
      path: /etc/selinux/config
      regexp: ‘^SELINUX=’
      line: ‘SELINUX=disabled’

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check lineinfile.yml
playbook: lineinfile.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook -C lineinfile.yml

真执行
[alice@control ansible]$ ansible-playbook lineinfile.yml

查看验证
[alice@control ansible]$ ansible -m shell all -a “getenforce”

临时修改
[alice@control ansible]$ ansible -m shell linux -a “setenforce 0”

[alice@control ansible]$ touch lineinfile-httpd.yml
[alice@control ansible]$ vim lineinfile-httpd.yml

  • name: lineinfile httpd
    hosts: all
    tasks:
    • name: install httpd
      yum:
      name: httpd
      state: present

    • name: modify httpd’s website
      copy:
      content: “hello,alex”
      dest: /var/www/html/index.html

    • name: modify httpd’s main configuration file
      lineinfile:
      path: /etc/httpd/conf/httpd.conf
      regexp: “^Listen 80”
      line: “Listen 8080”

    • name: start httpd service
      service:
      name: httpd
      state: started
      enabled: true

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check lineinfile-httpd.yml
playbook: lineinfile-httpd.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook -C lineinfile-httpd.yml

真执行
[alice@control ansible]$ ansible-playbook lineinfile-httpd.yml

查看验证
[alice@control ansible]$ ansible -m shell all -a “dnf info -y httpd”
[alice@control ansible]$ ansible -m shell all -a “rpm -qa | grep -i httpd”

[alice@control ansible]$ ansible -m shell all -a “ss -tunpla | grep 8080”
[alice@control ansible]$ ansible -m shell all -a “lsof -i:80”

handlers 进行程序处理
[alice@control ansible]$ touch handlers.yml
[alice@control ansible]$ vim handlers.yml

  • name: handlers
    hosts: all
    tasks:

    • name: install httpd
      yum:
      name: httpd
      state: present

    • name: modify httpd’s website
      copy:
      content: “hello,alex”
      dest: /var/www/html/index.html
      setype: httpd_sys_content_t

    • name: modify httpd’s main configuration file
      lineinfile:
      path: /etc/httpd/conf/httpd.conf
      regexp: “^Listen 80”
      line: “Listen 8080”
      notify:

      • restart httpd
    • name: firewalld add http services
      firewalld:
      state: enabled
      service: http
      permanent: yes
      immediate: yes

    • name: install vsftpd services
      dnf:
      name: vsftpd
      state: latest
      notify:

      • restart vsftpd

    handlers:

    • name: restart httpd
      service:
      name: httpd
      state: restarted

    • name: restart vsftpd
      service:
      name: vsftpd
      state: restarted

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check handlers.yml
playbook: handlers.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook -C handlers.yml

真执行,通过 -vv 参数 验证
[alice@control ansible]$ ansible-playbook handlers.yml -v
[alice@control ansible]$ ansible-playbook handlers.yml -vv
[alice@control ansible]$ ansible-playbook handlers.yml -vvv

任务控制
ignore_errors -> 处理任务失败
添加
ignore_errors: yes

尖叫提示: 不是所有的问题,都可以进行忽略,当任务的执行成功或者失败对后面的任务没有直接关联的时候是可以忽略的。

[alice@control ansible]$ cp handlers.yml ignore.yml
[alice@control ansible]$ vim ignore.yml

  • name: handlers
    hosts: all
    tasks:

    • name: install httpd
      yum:
      name: http
      state: present
      ignore_errors: yes

    • name: modify httpd’s website
      copy:
      content: “hello,alex”
      dest: /var/www/html/index.html
      setype: httpd_sys_content_t

    • name: modify httpd’s main configuration file
      lineinfile:
      path: /etc/httpd/conf/httpd.conf
      regexp: “^Listen 80”
      line: “Listen 8080”
      notify:

      • restart httpd
    • name: firewalld add http services
      firewalld:
      state: enabled
      service: http
      permanent: yes
      immediate: yes

    • name: install vsftpd services
      dnf:
      name: vsftpd
      state: latest
      notify:

      • restart vsftpd

    handlers:

    • name: restart httpd
      service:
      name: httpd
      state: restarted

    • name: restart vsftpd
      service:
      name: vsftpd
      state: restarted

语法检查
[alice@control ansible]$ ansible-playbook --syntax-check ignore.yml
playbook: ignore.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook -C ignore.yml

##验证:错误的task,会出现…ignoring
[alice@control ansible]$ ansible-playbook ignore.yml

force_handlers: yes -> 强制执行失败的任务
添加
force_handlers: yes

虽然有excute错误的任务,handlers中的任务会根据已经发生changed的任务中的notify进行触发。
[alice@control ansible]$ cp ignore.yml force_handlers.yml
[alice@control ansible]$ vim force_handlers.yml

  • name: handlers
    hosts: all
    force_handlers: yes
    tasks:

    • name: install httpd
      yum:
      name: httpd
      state: present

    • name: modify httpd’s website
      copy:
      content: “hello,alex”
      dest: /var/www/html/index.html
      setype: httpd_sys_content_t

    • name: modify httpd’s main configuration file
      lineinfile:
      path: /etc/httpd/conf/httpd.conf
      regexp: “^Listen 80”
      line: “Listen 8080”
      notify:

      • restart httpd
    • name: firewalld add http services
      firewalld:
      state: enabled
      service: http
      permanent: yes
      immediate: yes

    • name: install vsftpd services
      dnf:
      name: vsftpd
      state: latest
      notify:

      • restart vsftpd
    • name: excute /bin/false
      command: /bin/false

    handlers:

    • name: restart httpd
      service:
      name: httpd
      state: restarted

    • name: restart vsftpd
      service:
      name: vsftpd
      state: restarted

语法检查
[alice@control ansible]$ ansible-playbook --syntax-check force_handlers.yml
playbook: force_handlers.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook -C force_handlers.yml

真执行
[alice@control ansible]$ ansible-playbook force_handlers.yml

验证
[alice@control ansible]$ ansible-playbook force_handlers.yml -vv

[alice@control ansible]$ ansible -m shell all -a “cat /var/www/html/index.html”
[alice@control ansible]$ ansible -m shell all -a “systemctl status httpd”

failed_when -> 指定任务失败的条件
failed_when 来指定任务失败的条件,某些任务默认永远不可能报告失败,但是我们可以人为的指定报告,指定任务失败的条件
添加
register: command_result
failed_when: command_result.rc == 0

[alice@control ansible]$ touch failed_when.yml
[alice@control ansible]$ vim failed_when.yml

  • name: failed_when
    hosts: all
    tasks:
    • name: failed
      command: /bin/false

    • name: add web content
      copy:
      content: “hello alex”
      dest: /opt/testfile.txt

语法检查
[alice@control ansible]$ ansible-playbook --syntax-check failed_when.yml
playbook: failed_when.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook -C failed_when.yml

真执行,报错 rc:1
[alice@control ansible]$ ansible-playbook failed_when.yml

failed_when 使用策略
(1)在 shell | command 中定义一个 register 变量
(2)在后续的任务中,通过 register 变量中的值,决定该任务以及后续任务是否需要执行

[alice@control ansible]$ vim failed_when.yml

  • name: failed_when
    hosts: all
    tasks:
    • name: failed
      command: /bin/false
      register: command_result
      failed_when: command_result.rc == 0

    • name: add web content
      copy:
      content: “hello alex”
      dest: /opt/testfile.txt

语法检查
[alice@control ansible]$ ansible-playbook --syntax-check failed_when.yml
playbook: failed_when.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook -C failed_when.yml
[alice@control ansible]$ ansible-playbook -C failed_when.yml -vv

真执行
[alice@control ansible]$ ansible-playbook failed_when.yml -vv

Ansible 块和错误处理(block、rescue、always)
block 与 when、rescue、always 是同一级别,位于 tasks 之下
block 包含 when 关键字
block 中的子任务失败后,会执行 rescue 模块,always 模块是无论如何都会执行的

[alice@control ansible]$ touch block.yml
[alice@control ansible]$ vim block.yml
[alice@control ansible]$ cat block.yml

  • name: block rescue always
    hosts: all
    tasks:
    • name: install and configure httpd
      block:

      • name: install
        yum:
        name: httpd
        state: latest

      • name: configure
        copy:
        content: “hello,alex”
        dest: /var/www/html/index.html

      • name : start servie
        service:
        name: httpd
        state: started
        enabled: true
        when: ansible_distribution == “RedHat”

      rescue:

      • name: shell command failure
        shell: echo “hello,failure”

      always:

      • name: shell command failure or success
        shell: echo “hello,always”

语法检查
[alice@control ansible]$ ansible-playbook --syntax-check block.yml
playbook: block.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook -C block.yml

真执行
[alice@control ansible]$ ansible-playbook block.yml -vv

jinjia2
在被管理节点上创建文件或者目录

如果要使用 template 模块,需要使用具体语法
src: 指定来源 jinjia2 模块
dest: 指定要在目标主机上创建文件

{% EXPR %} -> 用于表达式或者逻辑式
{{ EXPR }} -> 用于向最终用户输出表达式或者变量的结果

##简单的facts变量
1、ansible_distribution
2、ansible_facts[‘distribution’]
ansible_facts[‘hostname’]

##复杂一点的facts变量
通过ansible_facts变量获取IP地址:
1、ansible_eth0.ipv4.address =IP地址
2、ansible_facts[‘eth0’][‘ipv4’][‘address’]

实操实验
[alice@control ansible]$ vim hosts.j2
Welcome {{ ansible_fqdn }} to {{ ansible_facts[‘hostname’] }} on {{ ansible_facts[‘eth0’][‘ipv4’][‘address’] }}

[alice@control ansible]$ touch template.yml
[alice@control ansible]$ vim template.yml

  • name: jinjia2
    hosts: all
    tasks:
    • name: install httpd
      yum:
      name: httpd
      state: latest

    • name: get information
      template:
      src: /home/alice/ansible/hosts.j2
      dest: /var/www/html/index.html
      mode: 0666
      setype: httpd_sys_content_t
      owner: apache
      group: apache

    • name: start httpd
      service:
      name: httpd
      state: started
      enabled: true

语法检查
[alice@control ansible]$ ansible-playbook --syntax-check template.yml
playbook: template.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook -C template.yml

真执行
[alice@control ansible]$ ansible-playbook template.yml

验证
[alice@control ansible]$ curl -l http://node1/
Welcome node1.lab0.example.com to node1 on 172.25.254.101

[alice@control ansible]$ curl -l http://node2/
Welcome node2.lab0.example.com to node2 on 172.25.254.102

[alice@control ansible]$ curl -l http://node3/
Welcome node3.lab0.example.com to node3 on 172.25.254.103

[alice@control ansible]$ curl -l http://node4/
Welcome node4.lab0.example.com to node4 on 172.25.254.104

jinjia2 模板还可以如下定义,还有如下语法使用
[alice@control ansible]$ vim alex_hosts.j2
{% for host in groups[‘var’] %}
{{ ansible_facts[‘hostname’] }}
{% endfor %}
{% if ansible_facts[‘hostname’] != “s1” %}
{{ ansible_facts[‘hostname’] }}
{% endif %}

防火墙开放端口
[alice@control ansible]$ vim firewall.yml

  • name: firewall
    hosts: all
    tasks:
    • name: modify firewalld rule 81
      firewalld:
      port: 81/tcp
      immediate: yes
      permanent: yes
      state: enabled

    • name: modify firewalld rule 82
      firewalld:
      port: 82/tcp
      immediate: yes
      permanent: yes
      state: enabled

    • name: modify firewalld rule 8080
      firewalld:
      port: 8080/tcp
      immediate: yes
      permanent: yes
      state: enabled

语法检查
[alice@control ansible]$ ansible-playbook --syntax-check firewall.yml
playbook: firewall.yml

空执行,假执行
[alice@control ansible]$ ansible-playbook -C firewall.yml

真执行
[alice@control ansible]$ ansible-playbook firewall.yml

[alice@control ansible]$ ansible -m shell all -a “systemctl status httpd”
[alice@control ansible]$ ansible -m shell all -a “firewall-cmd --list-all”

一、管理大项目
1、定义主机列表(资产清单 inventory)
1)静态资产清单
[var]
node1.lab.example.com
172.25.250.10

yml 中单一主机域名,单一IP

  • hosts: 10.60.100.111
  • hosts: node1.lab.example.com

资产清单中所有的主机

  • hosts: ‘*’
  • hosts: all

资产清单中多个主机

  • hosts: ‘10.60.100.*’

列表的形式

  • hosts: 10.60.100.110,10.60.100.111

2)动态资产清单
[alice@control ansible]$ touch inventry2.py
[alice@control ansible]$ vim inventry2.py
#!/usr/bin/env python3
#coding:utf8
import json
import sys

def all():
info_dict = {
“all”: [
“172.25.254.102”,
“172.25.254.103”
]
}
print(json.dumps(info_dict,indent=4))
def group():
host1 = [‘172.25.254.102’]
host2 = [‘172.25.254.102’,‘172.25.254.103’]
group1 = ‘alex-g1’
group2 = ‘alex-g2’
hostdata = {
group1: {“hosts”:host1},
group2: {“hosts”:host2}
}
print(json.dumps(hostdata,indent=4))
def host(ip):
info_dict = {
“172.25.254.102”: {
“ansible_ssh_host”: “172.25.254.102”,
“ansible_ssh_port”: 22,
“ansible_ssh_user”: “root”,
“ansible_ssh_pass”: “redhat”,
},
“172.25.254.103”: {
“ansible_ssh_host”: “172.25.254.103”,
“ansible_ssh_port”: 22,
“ansible_ssh_user”: “root”,
“ansible_ssh_pass”: “redhat”,
}
}
print(json.dumps(info_dict,indent=4))
if len(sys.argv) == 2 and (sys.argv[1] == ‘–list’):
group()
elif len(sys.argv) == 3 and (sys.argv[1] == ‘–host’):
host(sys.argv[2])
else:
print("Usage: %s --list or --host " % sys.argv[0])
sys.exit(1)

赋予权限
[alice@control ansible]$ chmod 755 inventry2.py

安装python3环境
[alice@control ansible]$ dnf info -y python*
[alice@control ansible]$ sudo dnf install -y python36
[alice@control ansible]$ python3 --version
Python 3.6.8
[alice@control ansible]$ python3 -V
Python 3.6.8
[alice@control ansible]$ dnf list -y installed | grep -i python

查看资产清单 通过-i 参数指定资产清单文件
[alice@control ansible]$ ansible-inventory --list
[alice@control ansible]$ ansible-inventory -i inventry2.py --list

ansible 中 ping 模块可以使用,其它模块也可以使用,其它模块就不再演示了
[alice@control ansible]$ ansible -m ping alex-g1 -i inventry2.py

管理多个资产清单文件(通过目录的方式)

[alice@control ansible]$ mkdir inven

[alice@control ansible]$ cp -rfvp alice-inventory inven/
[alice@control ansible]$ cp -rfvp inventry2.py inven/

查看(静态+动态)资产清单文件
[alice@control ansible]$ ansible all -i inven/ --list
[alice@control ansible]$ ansible all -i inven/ --list-host
[alice@control ansible]$ ansible all -i inven/ --list-hosts

ansible 配置并行,默认是5
[alice@control ansible]$ cat ansible.cfg | grep -i forks
#forks = 5
[alice@control ansible]$ grep ‘forks’ ansible.cfg
#forks = 5

包含和导入剧本(include 与 import)
import 静态操作,解析剧本时,对所有 import * 语句进行处理。
include 动态操作,所有include * 语句均在执行playbook 时候进行处理。

[alice@control ansible]$ touch install-tasks.yml
[alice@control ansible]$ vim install-tasks.yml

  • hosts: all
    tasks:
    • name: install httpd packages
      yum:
      name: httpd
      state: latest

[alice@control ansible]$ touch service-tasks.yml
[alice@control ansible]$ vim service-tasks.yml

  • hosts: all
    tasks:
    • name: start httpd service
      service:
      name: httpd
      state: started
      enabled: true

[alice@control ansible]$ touch install-packages.yml
[alice@control ansible]$ vim install-packages.yml

  • name: install packages
    hosts: all
    tasks:
    • name: import tasks
      import_tasks: install-tasks.yml

    • name: include
      include_tasks: service-tasks.yml

语法检查
[alice@control ansible]$ ansible-playbook --syntax-check install-tasks.yml
playbook: install-tasks.yml

[alice@control ansible]$ ansible-playbook --syntax-check service-tasks.yml
playbook: service-tasks.yml

[alice@control ansible]$ ansible-playbook install-packages.yml

通过角色简化 playbook
角色定义

配置 roles 目录
[alice@control ansible]$ mkdir roles

ansible.cfg 指定默认的角色路径
[alice@control ansible]$ vim ansible.cfg
68 roles_path = /home/alice/ansible/roles
[alice@control ansible]$ grep roles_path ansible.cfg
roles_path = /home/alice/ansible/roles

查看帮助
[alice@control ansible]$ ansible-galaxy --help

查看版本
[alice@control ansible]$ ansible-galaxy --version
ansible-galaxy 2.8.5

创建 apache 角色
创建角色的的时候,一定要切换到默认的角色路径目录下进行初始化的创建
[alice@control roles]$ ansible-galaxy init apache

  • apache was created successfully

[alice@control roles]$ pwd
/home/alice/ansible/roles

[alice@control roles]$ ll
drwxrwxr-x. 10 alice alice 135 Dec 1 11:50 apache

安装 tree 服务
[alice@control roles]$ sudo dnf install -y tree

[alice@control roles]$ tree -d -L 2
.
└── apache
├── defaults
├── files
├── handlers
├── meta
├── tasks
├── templates
├── tests
└── vars

[alice@control roles]$ tree
.
└── apache
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml

并非每个角色都拥有所有这些目录
defaults -> 此目录中的main.yml 文件包含角色变量的默认值,使用角色时可以覆盖这些默认值,这些变量的优先级较低,应该在play中更改和自定义。

files -> 次目录包含由角色任务引用的静态文件。

handlers 此目录中的 main.yml 文件包含角色的处理程序定义。

meta -> 此目录中 main.yml 文件包含与角色相关的信息,如作者、许可证、平台和可先的角色依赖项。

tasks -> 此目录中的 main.yml 文件包含角色的任务定义。

templates -> 此目录包含由角色任务引用的 jinjia2 模板。

tests -> 此目录可以包含清单和 test.yml playbook,k可用于测试角色。

vars -> 此目录中的 main.yml 文件,定义角色的变量值。这些变量通常用于角色内部用途,这些变量的优先级较高,在 playbook 中 使用时不应更改

配置角色
[alice@control roles]$ cp …/hosts.j2 apache/templates/
[alice@control roles]$ vim apache/tasks/main.yml

  • name: install web packages
    dnf:
    name: httpd
    state: latest

  • name: start httpd service
    service:
    name: httpd
    state: started
    enabled: true

  • name: copy website index.html
    template:
    src: templates/hosts.j2
    dest: /var/www/html/index.html
    mode: 0644
    owner: apache
    group: apache
    setype: httpd_sys_content_t

  • name: modify httpd.conf listener
    lineinfile:
    path: /etc/httpd/conf/httpd.conf
    regexp: “^Listen 80”
    line: “Listen 8080”
    notify:

    • restart httpd service
  • name: firewalld policy
    firewalld:
    state: enabled
    port: 8080/tcp
    permanent: yes
    immediate: yes

[alice@control roles]$ vim apache/handlers/main.yml

  • name: restart httpd service
    service:
    name: httpd
    state: restarted

列出可以使用的角色
[alice@control ansible]$ ansible-galaxy list

/home/alice/ansible/roles

  • apache, (unknown version)

使用角色
来到roles目录之外的目录比如/home/alice/ansible,创建一个roles.yml
[alice@control ansible]$ touch roles.yml
[alice@control ansible]$ vim roles.yml

  • hosts: all
    roles:
    • apache

语法检查
[alice@control ansible]$ ansible-playbook --syntax-check roles.yml
playbook: roles.yml

空执行,假执行,验证执行
[alice@control ansible]$ ansible-playbook -C roles.yml

真执行
[alice@control ansible]$ ansible-playbook roles.yml

查看并验证
[alice@control ansible]$ ansible -m shell all -a “curl -l http://localhost:8080/”

使用系统角色
安装系统角色
[alice@control ~]$ sudo dnf install -y rhel-system-roles

查看系统角色
[alice@control ~]$ ls -l /usr/share/ansible/
[alice@control ~]$ ls -l /usr/share/ansible/roles/

复制系统角色到自定义目录
[alice@control ansible]$ cp -arfvp /usr/share/ansible/roles/rhel-system-roles.timesync/ ~/ansible/roles/

修改名称,只因名称太长
[alice@control ansible]$ mv roles/rhel-system-roles.timesync roles/timesync

查看角色
[alice@control ansible]$ ansible-galaxy list

/home/alice/ansible/roles

  • apache, (unknown version)
  • timesync, (unknown version)

查看 readme 文件
[alice@control ansible]$ less roles/timesync/README.md
模板
yaml

  • hosts: targets
    vars:
    timesync_ntp_servers:
    - hostname: foo.example.com
    iburst: yes
    - hostname: bar.example.com
    iburst: yes
    - hostname: baz.example.com
    iburst: yes
    roles:
    • rhel-system-roles.timesync

[alice@control ansible]$ touch timesync.yml
[alice@control ansible]$ vim timesync.yml

  • hosts: network,linux,prod
    vars:
    timesync_ntp_servers:
    - hostname: classromm
    iburst: yes
    roles:
    • timesync

语法检查
[alice@control ansible]$ ansible-playbook --syntax-check timesync.yml
playbook: timesync.yml

安装 chronyd 服务
[alice@control ansible]$ ansible -m shell all -a “dnf install -y chrony”

空执行,假执行,验证执行
[alice@control ansible]$ ansible-playbook -C timesync.yml

真执行
[alice@control ansible]$ ansible-playbook timesync.yml

查看验证
[alice@control ansible]$ ansible -m shell all -a “chronyc sources -v”
[alice@control ansible]$ ansible -m shell all -a “timedatectl”

自定义 role 角色,部署 httpd 服务
创建角色的的时候,一定要切换到默认的角色路径目录下进行初始化的创建
[alice@control ansible]$ cd roles/
[alice@control roles]$ ansible-galaxy init httpd

  • httpd was created successfully

列出可以使用的角色
[alice@control ansible]$ ansible-galaxy list

/home/alice/ansible/roles

  • apache, (unknown version)
  • timesync, (unknown version)
  • httpd, (unknown version)

安装 httpd 的软件包
[alice@control ansible]$ vim roles/httpd/tasks/main.yml

  • name: install httpd
    yum:
    name: httpd
    state: latest

通过 fetch 配置 httpd 服务
fetch -> 从被管理节点上拷贝文件到控制节点上
[alice@control ansible]$ ansible -m fetch all -a “src=’/usr/share/doc/httpd/httpd-vhosts.conf’ dest=’/home/alice/ansible/roles/httpd/files/’ flat=‘yes’”
flat=‘yes’ 不拷贝被管理节点的目录结构

修改文件名
[alice@control ansible]$ mv roles/httpd/files/httpd-vhosts.conf roles/httpd/files/server.conf

编辑 httpd_configuration.yml 文件
[alice@control ansible]$ vim roles/httpd/tasks/httpd_configuration.yml

  • name: copy httpd configuration file
    copy:
    src: files/server.conf
    dest: /etc/httpd/conf.d/server.conf

上传代码
[alice@control ansible]$ echo “hello,alex” > roles/httpd/files/index.html

编辑 httpd_webcontent.yml 文件
[alice@control ansible]$ vim roles/httpd/tasks/httpd_webcontent.yml

  • name: copy source code
    copy:
    src: files/index.html
    dest: /var/www/html/index.html
    setype: httpd_sys_content_t

启动 httpd 服务
[alice@control ansible]$ vim roles/httpd/tasks/httpd_service.yml

  • name: start httpd service
    service:
    name: httpd
    state: started
    enabled: true

配置 firewalld
[alice@control ansible]$ vim roles/httpd/tasks/firewalld_service.yml

  • name: start firewalld service
    service:
    name: firewalld
    state: started
    enabled: true

[alice@control ansible]$ vim roles/httpd/tasks/firewalld_rules.yml

  • name: modify firewalld rules
    firewalld:
    zone: public
    state: enabled
    permanent: yes
    rich_rule: rule family=ipv4 source address=“172.25.254.101/24” port port=“80” protocol=“tcp” accept

添加 notify 模块
[alice@control ansible]$ vim roles/httpd/tasks/httpd_configuration.yml

  • name: copy httpd configuration file
    copy:
    src: files/server.conf
    dest: /etc/httpd/conf.d/server.conf
    notify: restart httpd

[alice@control ansible]$ vim roles/httpd/handlers/httpd_install.yml

  • name: restart httpd
    service:
    name: httpd
    state: restarted

[alice@control ansible]$ vim roles/httpd/tasks/main.yml

  • name: import httpd playbook
    import_tasks: tasks/httpd_install.yml

  • name: import configuration httpd playbook
    import_tasks: tasks/httpd_configuration.yml

  • name: import webcontent httpd playbook
    import_tasks: tasks/httpd_webcontent.yml

  • name: import start httpd service playbook
    import_tasks: tasks/httpd_service.yml

  • name: import start firewalld service playbook
    import_tasks: tasks/firewalld_service.yml

  • name: import configuration firewalld rules playbook
    import_tasks: tasks/firewalld_rules.yml

[alice@control ansible]$ ls -l roles/httpd/tasks/
-rw-rw-r–. 1 alice alice 219 Dec 1 15:11 firewalld_rules.yml
-rw-rw-r–. 1 alice alice 114 Dec 1 15:07 firewalld_service.yml
-rw-rw-r–. 1 alice alice 151 Dec 1 15:12 httpd_configuration.yml
-rw-rw-r–. 1 alice alice 75 Dec 1 15:15 httpd_install.yml
-rw-rw-r–. 1 alice alice 106 Dec 1 15:05 httpd_service.yml
-rw-rw-r–. 1 alice alice 140 Dec 1 15:03 httpd_webcontent.yml
-rw-rw-r–. 1 alice alice 549 Dec 1 15:21 main.yml

定义访问入口
[alice@control ansible]$ touch site.yml
[alice@control ansible]$ vim site.yml

  • hosts: all
    roles:
    • httpd

检查语法
[alice@control ansible]$ ansible-playbook --syntax-check site.yml
playbook: site.yml

空执行,假执行,验证执行
[alice@control ansible]$ ansible-playbook -C site.yml

真执行
[alice@control ansible]$ ansible-playbook site.yml

[alice@control ansible]$ tree roles/httpd/
roles/httpd/
├── defaults
│ └── main.yml
├── files
│ ├── index.html
│ └── server.conf
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ ├── firewalld_rules.yml
│ ├── firewalld_service.yml
│ ├── httpd_configuration.yml
│ ├── httpd_install.yml
│ ├── httpd_service.yml
│ ├── httpd_webcontent.yml
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml

通过模板方式进行定义变量
[alice@control ansible]$ mv roles/httpd/files/server.conf roles/httpd/templates/

[alice@control ansible]$ vim roles/httpd/templates/server.conf
{% if PORT != 8080 %}
Listen 80
{% endif %}
<VirtualHost *:{{ PORT }}>
ServerAdmin webmaster@dummy-host.example.com
DocumentRoot “/var/www/dummy-host.example.com”
ServerName dummy-host.example.com
ServerAlias www.dummy-host.example.com
ErrorLog “/var/log/httpd/dummy-host.example.com-error_log”
CustomLog “/var/log/httpd/dummy-host.example.com-access_log” common

[alice@control ansible]$ vim roles/httpd/tasks/httpd_configuration.yml

  • name: copy httpd configuration file
    template:
    src: templates/server.conf
    dest: /etc/httpd/conf.d/server.conf
    notify: restart httpd

[alice@control ansible]$ vim roles/httpd/vars/main.yml

PORT: 80

[alice@control ansible]$ vim roles/httpd/tasks/firewalld_rules.yml

  • name: modify firewalld rules
    firewalld:
    zone: public
    state: enabled
    permanent: yes
    rich_rule: rule family=ipv4 source address=“172.25.254.101/24” port port={{ PORT }} protocol=“tcp” accept

空执行,假执行,验证执行
[alice@control ansible]$ ansible-playbook -C site.yml

真执行
[alice@control ansible]$ ansible-playbook site.yml

使用 Ansible galaxy 部署角色
Ansible 内容公共资源库: https://galaxy.ansible.com

[alice@control ansible]$ touch requirements.yml
[alice@control ansible]$ vim requirements.yml

  • src: http://content.example.com/roles/haproxy.tar
    name: balancer

[alice@control ansible]$ ansible-galaxy install -r requirements.yml -p roles/

  • downloading role from http://content.example.com/roles/haproxy.tar
  • extracting balancer to /home/alice/ansible/roles/balancer
  • balancer was installed successfully

[alice@control ansible]$ ansible-galaxy list

/home/alice/ansible/roles

  • apache, (unknown version)
  • timesync, (unknown version)
  • httpd, (unknown version)
  • balancer, (unknown version)

[alice@control ansible]$ touch roles_balancer.yml
[alice@control ansible]$ vim roles_balancer.yml

  • name: use balancer roles
    hosts: linux
    roles:
    • balancer

[alice@control ansible]$ ansible-playbook --syntax-check roles_balancer.yml
playbook: roles_balancer.yml

空执行,假执行,验证执行
[alice@control ansible]$ ansible-playbook -C roles_balancer.yml

Ansible 故障排除
1)配置 Ansible 日志
[alice@control ansible]$ vim +/log_path ansible.cfg
[alice@control ansible]$ grep log_path ansible.cfg
log_path = /var/log/ansible.log

2)使用 Ansible debug 模块显示输出
[alice@control ansible]$ ansible-doc debug
[alice@control ansible]$ ansible-doc -s debug

[alice@control ansible]$ touch debug_test.yml
[alice@control ansible]$ vim debug_test.yml

  • name: test debug yml
    hosts: network
    tasks:
    • name: debug
      debug:
      msg: “This is a test yml”

语法检查
[alice@control ansible]$ ansible-playbook --syntax-check debug_test.yml
[WARNING]: log file at /var/log/ansible.log is not writeable and we cannot create it, aborting
playbook: debug_test.yml

[alice@control ansible]$ ansible-playbook debug_test.yml -vvv

setup 模块进行查看
[alice@control ansible]$ ansible -m setup network > a.txt

自动执行 Linux 管理任务
1、软件包管理模块
1)yum
2)yum_repository

[alice@control ansible]$ ansible -m shell network -a “dnf grouplist -y”

[alice@control ansible]$ touch groupinstall.yml

基于软件包组的安装
[alice@control ansible]$ vim groupinstall.yml

  • name: group install
    hosts: network
    tasks:
    • name: install
      yum:
      name: “@RPM Development Tools”
      state: present

语法检查
[alice@control ansible]$ ansible-playbook --syntax-check groupinstall.yml
playbook: groupinstall.yml

空执行,假执行,验证执行
[alice@control ansible]$ ansible-playbook -C groupinstall.yml

真执行
[alice@control ansible]$ ansible-playbook groupinstall.yml

查看并验证
[alice@control ansible]$ ansible -m shell network -a “dnf grouplist -y”

2、用户管理模块
1)user
2)group
[alice@control ansible]$ ansible-doc -s user
[alice@control ansible]$ ansible-doc -s group
[alice@control ansible]$ ansible-doc -s user | grep -i group

[alice@control ansible]$ useradd test1 -g alex -G mk
-g 私有组
-G 附加组

[alice@control ansible]$ touch user.yml
[alice@control ansible]$ vim user.yml

  • name: user
    hosts: network
    vars:
    • user_name: alex
    • user_passwd: redhat
      tasks:
    • name: create user
      user:
      name: “{{ user_name }}”
      password: “{{user_passwd | password_hash(‘sha512’)}}”

语法检查
[alice@control ansible]$ ansible-playbook --syntax-check user.yml
playbook: user.yml

空执行,假执行,验证执行
[alice@control ansible]$ ansible-playbook -C user.yml

真执行
[alice@control ansible]$ ansible-playbook user.yml

存储管理模块
lvg
lvol
filesystem
mount

[alice@control ansible]$ ansible -m shell network -a “lsblk -fp”
node1.lab0.example.com | CHANGED | rc=0 >>
NAME FSTYPE LABEL UUID MOUNTPOINT
/dev/sr0
/dev/vda
├─/dev/vda1 xfs 32810515-85c4-4919-b519-fc340bc07086 /boot
└─/dev/vda2 LVM2_member vvxScI-37RQ-oaX3-TyHa-Gz1k-iknv-abLH4D
├─/dev/mapper/rhel-root xfs bd4d478b-e2fb-4cad-8ec0-8a265a82ebd1 /
└─/dev/mapper/rhel-swap swap 3573749e-344d-401f-aa2a-d3946dbb51da [SWAP]

[root@server1 ~]# systemctl start cockpit
[root@server1 ~]# lsof -i:9090

https://172.25.254.250:9090/system
username:root
password:Asimov

在 node1 上添加磁盘,然后重启 node1 服务器

再次查看,发现 node1 多了一块磁盘 /dev/vdb
[alice@control ansible]$ ansible -m shell network -a “lsblk -fp”
node1.lab0.example.com | CHANGED | rc=0 >>
NAME FSTYPE LABEL UUID MOUNTPOINT
/dev/sr0
/dev/vda
├─/dev/vda1 xfs 32810515-85c4-4919-b519-fc340bc07086 /boot
└─/dev/vda2 LVM2_member vvxScI-37RQ-oaX3-TyHa-Gz1k-iknv-abLH4D
├─/dev/mapper/rhel-root xfs bd4d478b-e2fb-4cad-8ec0-8a265a82ebd1 /
└─/dev/mapper/rhel-swap swap 3573749e-344d-401f-aa2a-d3946dbb51da [SWAP]
/dev/vdb

[alice@control ansible]$ ansible-doc -l | grep -i vg
[alice@control ansible]$ ansible-doc -s lvg
[alice@control ansible]$ ansible-doc -l | grep -i lv
[alice@control ansible]$ ansible-doc -s lvol
[alice@control ansible]$ ansible-doc -s filesystem
[alice@control ansible]$ ansible-doc -s mount

[alice@control ansible]$ touch disk_lv.yml
[alice@control ansible]$ vim disk_lv.yml

  • name: disk pe pv vg lv filesystem
    hosts: network
    tasks:
    • name: create vg
      lvg:
      vg: alexvg
      pesize: 64m
      pvs: /dev/vdb

    • name: create lv
      lvol:
      vg: alexvg
      lv: alexlv001
      size: 500m

    • name: create filesystem
      filesystem:
      fstype: xfs
      dev: /dev/alexvg/alexlv001

    • name: mount
      mount:
      src: /dev/alexvg/alexlv001
      path: /opt/alexdir
      fstype: xfs
      state: mounted

语法检查
[alice@control ansible]$ ansible-playbook --syntax-check disk_lv.yml
playbook: disk_lv.yml

空执行,假执行,验证执行
[alice@control ansible]$ ansible-playbook -C disk_lv.yml

真执行 -vv查看详细信息
[alice@control ansible]$ ansible-playbook disk_lv.yml -vv

查看并验证
[alice@control ansible]$ ansible network -m shell -a “tail -1 /etc/fstab”
node1.lab0.example.com | CHANGED | rc=0 >>
/dev/alexvg/alexlv001 /opt/alexdir xfs defaults 0 0

查看并验证
[alice@control ansible]$ ansible network -m shell -a “df -Th”
node1.lab0.example.com | CHANGED | rc=0 >>
Filesystem Type Size Used Avail Use% Mounted on
devtmpfs devtmpfs 473M 0 473M 0% /dev
tmpfs tmpfs 490M 0 490M 0% /dev/shm
tmpfs tmpfs 490M 6.7M 484M 2% /run
tmpfs tmpfs 490M 0 490M 0% /sys/fs/cgroup
/dev/mapper/rhel-root xfs 47G 1.9G 45G 4% /
/dev/vda1 xfs 1014M 160M 855M 16% /boot
tmpfs tmpfs 98M 0 98M 0% /run/user/1000
/dev/mapper/alexvg-alexlv001 xfs 507M 30M 478M 6% /opt/alexdir

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值