如何使用 Ansible 打补丁以及安装应用
Ansible

> 
> 使用 Ansible IT 自动化引擎节省更新的时间。
> 
> 
> 


![](/data/attachment/album/201805/20/035937k1jc6t90wi80je66.jpg)


你有没有想过，如何打补丁、重启系统，然后继续工作？


如果你的回答是肯定的，那就需要了解一下 [Ansible](https://www.ansible.com/overview/how-ansible-works) 了。它是一个配置管理工具，对于一些复杂的有时候需要几个小时才能完成的系统管理任务，又或者对安全性有比较高要求的时候，使用 Ansible 能够大大简化工作流程。


以我作为系统管理员的经验，打补丁是一项最有难度的工作。每次遇到<ruby> 公共漏洞批露 <rt>  Common Vulnearbilities and Exposure </rt></ruby>（CVE）通知或者<ruby> 信息保障漏洞预警 <rt>  Information Assurance Vulnerability Alert </rt></ruby>（IAVA）时都必须要高度关注安全漏洞，否则安全部门将会严肃追究自己的责任。


使用 Ansible 可以通过运行[封装模块](https://docs.ansible.com/ansible/latest/list_of_packaging_modules.html)以缩短打补丁的时间，下面以 [yum 模块](https://docs.ansible.com/ansible/latest/yum_module.html)更新系统为例，使用 Ansible 可以执行安装、更新、删除、从其它地方安装（例如持续集成/持续开发中的 `rpmbuild`）。以下是系统更新的任务：



```
  - name: update the system
    yum:
      name: "*"
      state: latest

```

在第一行，我们给这个任务命名，这样可以清楚 Ansible 的工作内容。第二行表示使用 `yum` 模块在CentOS虚拟机中执行更新操作。第三行 `name: "*"` 表示更新所有程序。最后一行 `state: latest` 表示更新到最新的 RPM。


系统更新结束之后，需要重新启动并重新连接：



```
  - name: restart system to reboot to newest kernel
    shell: "sleep 5 && reboot"
    async: 1
    poll: 0

  - name: wait for 10 seconds
    pause:
      seconds: 10

  - name: wait for the system to reboot
    wait_for_connection:
      connect_timeout: 20
      sleep: 5
      delay: 5
      timeout: 60

  - name: install epel-release
    yum:
      name: epel-release
      state: latest

```

`shell` 模块中的命令让系统在 5 秒休眠之后重新启动，我们使用 `sleep` 来保持连接不断开，使用 `async` 设定最大等待时长以避免发生超时，`poll` 设置为 0 表示直接执行不需要等待执行结果。暂停 10 秒钟以等待虚拟机恢复，使用 `wait_for_connection` 在虚拟机恢复连接后尽快连接。随后由 `install epel-release` 任务检查 RPM 的安装情况。你可以对这个剧本执行多次来验证它的幂等性，唯一会显示造成影响的是重启操作，因为我们使用了 `shell` 模块。如果不想造成实际的影响，可以在使用 `shell` 模块的时候 `changed_when: False`。


现在我们已经知道如何对系统进行更新、重启虚拟机、重新连接、安装 RPM 包。下面我们通过 [Ansible Lightbulb](https://github.com/ansible/lightbulb/tree/master/examples/nginx-role) 来安装 NGINX:



```
  - name: Ensure nginx packages are present
    yum:
      name: nginx, python-pip, python-devel, devel
      state: present
    notify: restart-nginx-service

  - name: Ensure uwsgi package is present
    pip:
      name: uwsgi
      state: present
    notify: restart-nginx-service

  - name: Ensure latest default.conf is present
    template:
      src: templates/nginx.conf.j2
      dest: /etc/nginx/nginx.conf
      backup: yes
    notify: restart-nginx-service

  - name: Ensure latest index.html is present
    template:
      src: templates/index.html.j2
      dest: /usr/share/nginx/html/index.html

  - name: Ensure nginx service is started and enabled
    service:
      name: nginx
      state: started
      enabled: yes

  - name: Ensure proper response from localhost can be received
    uri:
      url: "http://localhost:80/"
      return_content: yes
    register: response
    until: 'nginx_test_message in response.content'
    retries: 10
    delay: 1

```

以及用来重启 nginx 服务的操作文件：



```
# 安装 nginx 的操作文件
  - name: restart-nginx-service
    service:
      name: nginx
      state: restarted

```

在这个角色里，我们使用 RPM 安装了 `nginx`、`python-pip`、`python-devel`、`devel`，用 PIP 安装了 `uwsgi`，接下来使用 `template` 模块复制 `nginx.conf` 和 `index.html` 以显示页面，并确保服务在系统启动时启动。然后就可以使用 `uri` 模块检查到页面的连接了。


这个是一个系统更新、系统重启、安装 RPM 包的剧本示例，后续可以继续安装 nginx，当然这里可以替换成任何你想要的角色和应用程序。



```
  - hosts: all
    roles:
      - centos-update
      - nginx-simple

```

 


这只是关于如何更新系统、重启以及后续工作的示例。简单起见，我只添加了不带[变量](https://docs.ansible.com/ansible/latest/playbooks_variables.html)的包，当你在操作大量主机的时候，你就需要修改其中的一些设置了：


* [async & poll](https://docs.ansible.com/ansible/latest/playbooks_async.html)
* [serial](https://docs.ansible.com/ansible/latest/playbooks_delegation.html#rolling-update-batch-size)
* [forks](https://docs.ansible.com/ansible/latest/intro_configuration.html#forks)


这是由于在生产环境中如果你想逐一更新每一台主机的系统，你需要花相当一段时间去等待主机重启才能够继续下去。




---


via: <https://opensource.com/article/18/3/ansible-patch-systems>


作者：[Jonathan Lozada De La Matta](https://opensource.com/users/jlozadad) 译者：[HankChow](https://github.com/HankChow) 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


OK
Have you ever wondered how to patch your systems, reboot, and continue working?


If so, you'll be interested in [Ansible](https://www.ansible.com/overview/how-ansible-works), a simple configuration management tool that can make some of the hardest work easy. For example, system administration tasks that can be complicated, take hours to complete, or have complex requirements for security.

**[ Advance your automation expertise. Get the Ansible checklist: 5 reasons to migrate to Red Hat Ansible Automation Platform 2 ]**

In my experience, one of the hardest parts of being a sysadmin is patching systems. Every time you get a Common Vulnerabilities and Exposure (CVE) notification or Information Assurance Vulnerability Alert (IAVA) mandated by security, you have to kick into high gear to close the security gaps. (And, believe me, your security officer will hunt you down unless the vulnerabilities are patched.)

Ansible can reduce the time it takes to patch systems by running [packaging modules](https://docs.ansible.com/ansible/latest/list_of_packaging_modules.html). To demonstrate, let's use the [yum module](https://docs.ansible.com/ansible/latest/yum_module.html) to update the system. Ansible can install, update, remove, or install from another location (e.g., `rpmbuild`

from continuous integration/continuous development). Here is the task for updating the system:

```
``````
- name: update the system
yum:
name: "*"
state: latest
```


In the first line, we give the task a meaningful `name`

so we know what Ansible is doing. In the next line, the `yum module`

updates the CentOS virtual machine (VM), then `name: "*"`

tells yum to update everything, and, finally, `state: latest`

updates to the latest RPM.

After updating the system, we need to restart and reconnect:

```
``````
- name: restart system to reboot to newest kernel
shell: "sleep 5 && reboot"
async: 1
poll: 0
- name: wait for 10 seconds
pause:
seconds: 10
- name: wait for the system to reboot
wait_for_connection:
connect_timeout: 20
sleep: 5
delay: 5
timeout: 60
- name: install epel-release
yum:
name: epel-release
state: latest
```


The `shell module`

puts the system to sleep for 5 seconds then reboots. We use `sleep`

to prevent the connection from breaking, `async`

to avoid timeout, and `poll`

to fire & forget. We pause for 10 seconds to wait for the VM to come back and use `wait_for_connection`

to connect back to the VM as soon as it can make a connection. Then we `install epel-release`

to test the RPM installation. You can run this playbook multiple times to show the `idempotent`

, and the only task that will show as changed is the reboot since we are using the `shell`

module. You can use `changed_when: False`

to ignore the change when using the `shell`

module if you expect no actual changes.

So far we've learned how to update a system, restart the VM, reconnect, and install a RPM. Next we will install NGINX using the role in [Ansible Lightbulb](https://github.com/ansible/lightbulb/tree/master/examples/nginx-role).

```
``````
- name: Ensure nginx packages are present
yum:
name: nginx, python-pip, python-devel, devel
state: present
notify: restart-nginx-service
- name: Ensure uwsgi package is present
pip:
name: uwsgi
state: present
notify: restart-nginx-service
- name: Ensure latest default.conf is present
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
backup: yes
notify: restart-nginx-service
- name: Ensure latest index.html is present
template:
src: templates/index.html.j2
dest: /usr/share/nginx/html/index.html
- name: Ensure nginx service is started and enabled
service:
name: nginx
state: started
enabled: yes
- name: Ensure proper response from localhost can be received
uri:
url: "http://localhost:80/"
return_content: yes
register: response
until: 'nginx_test_message in response.content'
retries: 10
delay: 1
```


And the handler that restarts the nginx service:

```
``````
# handlers file for nginx-example
- name: restart-nginx-service
service:
name: nginx
state: restarted
```


In this role, we install the RPMs `nginx`

, `python-pip`

, `python-devel`

, and `devel`

and install `uwsgi`

with PIP. Next, we use the `template`

module to copy over the `nginx.conf`

and `index.html`

for the page to display. After that, we make sure the service is enabled on boot and started. Then we use the `uri`

module to check the connection to the page.

Here is a playbook showing an example of updating, restarting, and installing an RPM. Then continue installing nginx. This can be done with any other roles/applications you want.

```
``````
- hosts: all
roles:
- centos-update
- nginx-simple
```


Watch this demo video for more insight on the process.

This was just a simple example of how to update, reboot, and continue. For simplicity, I added the packages without [variables](https://docs.ansible.com/ansible/latest/playbooks_variables.html). Once you start working with a large number of hosts, you will need to change a few settings:

This is because on your production environment you might want to update one system at a time (not fire & forget) and actually wait a longer time for your system to reboot and continue.

For more ways to automate your work with this tool, take a look at the other [Ansible articles on Opensource.com](https://opensource.com/tags/ansible).

## 1 Comment