Ansible循环编写详解及示例

Ansible支持使用loop关键字对一组项目进行迭代任务。循环变量item保存每个迭代过程中使用的值。在旧版本的Ansible中,通常使用with_items方式。以下内容详细介绍了Ansible中循环的使用方法,并通过多个示例进行说明。

1. 基本循环写法

没有循环之前的写法

在没有使用循环之前,我们需要分别编写多个任务来启动不同的服务:

---
- name: 没有循环之前的写法
  hosts: web
  tasks:
    - name: 启动第一个模块vsftpd
      service:
        name: vsftpd
        state: started

    - name: 启动第二个模块httpd
      service:
        name: httpd
        state: started

使用loop循环的写法

使用loop可以简化重复任务的编写:

---
- name: loop方式循环启动两个模块
  hosts: web
  tasks:
    - name: 简单列表loop方式循环启动两个模块
      service:
        name: "{{ item }}"
        state: started
      loop:
        - httpd
        - vsftpd

2. 使用变量提供loop列表

我们也可以通过变量来提供loop所使用的列表:

---
- name: 变量提供列表loop方式循环启动两个模块
  hosts: web
  vars:
    all_services:
      - vsftpd
      - httpd
  tasks:
    - name: 变量提供列表loop方式循环启动两个模块
      service:
        name: "{{ item }}"
        state: started
      loop: "{{ all_services }}"

3. 字典方式循环

loop列表中的项也可以是一个key: value的形式(字典方式):

---
- name: 散列或字典loop方式循环管理两个模块
  hosts: web
  tasks:
    - name: 散列或字典loop方式循环管理两个模块
      service:
        name: "{{ item.name }}"
        state: "{{ item.status }}"
      loop:
        - name: httpd
          status: started
        - name: vsftpd
          status: stopped

4. 复杂示例

示例1:管理多个服务的状态

假设我们需要管理一组服务的状态,启动httpd和nginx,停止vsftpd和mariadb:

---
- name: 管理服务状态
  hosts: web
  tasks:
    - name: 通过loop循环管理多个服务的状态
      service:
        name: "{{ item.name }}"
        state: "{{ item.state }}"
      loop:
        - name: httpd
          state: started
        - name: nginx
          state: started
        - name: vsftpd
          state: stopped
        - name: mariadb
          state: stopped

示例2:安装软件包并配置服务

假设我们需要安装一组软件包并确保它们的服务已启动:

---
- name: 安装软件包并启动服务
  hosts: web
  tasks:
    - name: 安装软件包
      yum:
        name: "{{ item }}"
        state: present
      loop:
        - httpd
        - mariadb-server
        - vsftpd

    - name: 启动服务
      service:
        name: "{{ item }}"
        state: started
      loop:
        - httpd
        - mariadb
        - vsftpd

示例3:创建用户并设置权限

假设我们需要创建一组用户并为其设置权限:

---
- name: 创建用户并设置权限
  hosts: web
  tasks:
    - name: 创建用户
      user:
        name: "{{ item.name }}"
        state: present
        groups: "{{ item.groups }}"
      loop:
        - name: alice
          groups: admin
        - name: bob
          groups: users

    - name: 设置权限
      file:
        path: "/home/{{ item.name }}/.ssh/authorized_keys"
        state: touch
        owner: "{{ item.name }}"
        mode: '0600'
      loop:
        - name: alice
        - name: bob

Ansible playbook的每一行的含义。

---
- name: 创建用户并设置权限
  hosts: web
  tasks:
    - name: 创建用户
      user:
        name: "{{ item.name }}"
        state: present
        groups: "{{ item.groups }}"
      loop:
        - name: alice
          groups: admin
        - name: bob
          groups: users

    - name: 设置权限
      file:
        path: "/home/{{ item.name }}/.ssh/authorized_keys"
        state: touch
        owner: "{{ item.name }}"
        mode: '0600'
      loop:
        - name: alice
        - name: bob

Playbook结构

---

这是YAML文档的开始标记,表示该文件是一个YAML格式的文档。

- name: 创建用户并设置权限

这个任务的名称(name),描述了这个playbook的作用是创建用户并设置权限。

  hosts: web

定义了任务将要运行的目标主机组,这里是web。该主机组应该在你的Ansible inventory文件中定义。

Tasks部分

任务1:创建用户
  tasks:

这是任务列表的开始。所有的任务将在web组中的主机上运行。

    - name: 创建用户

这个任务的名称(name),描述了这个任务的作用是创建用户。

      user:

使用了user模块,该模块用于管理用户。

        name: "{{ item.name }}"

定义了用户的名称,这里使用了循环变量item,每次循环都会替换{{ item.name }}为当前循环中的用户名。

        state: present

确保用户存在。如果用户不存在,它将被创建。

        groups: "{{ item.groups }}"

定义了用户所属的组,使用了循环变量item,每次循环都会替换{{ item.groups }}为当前循环中的用户组名。

      loop:

开始一个循环,loop关键字用于循环执行任务。

        - name: alice
          groups: admin

第一个循环项目,定义了用户alice及其所属组admin

        - name: bob
          groups: users

第二个循环项目,定义了用户bob及其所属组users

任务2:设置权限
    - name: 设置权限

这个任务的名称(name),描述了这个任务的作用是设置权限。

      file:

使用了file模块,该模块用于管理文件和目录属性。

        path: "/home/{{ item.name }}/.ssh/authorized_keys"

定义了要管理的文件路径,这里使用了循环变量item,每次循环都会替换{{ item.name }}为当前循环中的用户名,生成用户的authorized_keys文件路径。

        state: touch

确保文件存在。如果文件不存在,它将被创建。

        owner: "{{ item.name }}"

定义文件的所有者,这里使用了循环变量item,每次循环都会替换{{ item.name }}为当前循环中的用户名。

        mode: '0600'

定义文件的权限模式,将文件权限设置为0600,即只有所有者有读写权限。

      loop:

开始一个循环,loop关键字用于循环执行任务。

        - name: alice

第一个循环项目,定义了用户alice

        - name: bob

第二个循环项目,定义了用户bob

本文由mdnice多平台发布


逼格高的汤圆
10 声望2 粉丝