Ansible 执行 Playbook

Ansible 执行 Playbook

提权

设置提权

Ansible 通过 become 进行提权。become 有如下几个参数:

  • become:设置为 true 表示进行提权
  • become_user:设置提权到哪个用户
  • become_method:设置提权方法,默认为 sudo
  • become_flags:用于设置提权后使用的额外配置参数

以上四个参数都可以在 Playbook 或者 Task 级别进行设置。

下边是一个官网的提权示例:

- name: Run a command as nobody
  command: somecommand
  become: true
  become_method: su
  become_user: nobody
  become_flags: '-s /bin/sh'

提权相关的连接变量

以下是提权相关的连接变量:

  • ansible_become:是否提权
  • ansible_become_method:提权方法
  • ansible_become_user:提权到哪个用户
  • ansible_become_password:提权密码
  • ansible_common_remote_group:要给临时的 Ansible 目录设置的组

这个变量可以在主机清单中设置:

webserver ansible_user=manager ansible_become=true

提权相关命令行参数

  • --become-b:是否提权
  • --ask-become-pass-K:提权密码
  • --become-methos=BECOME_METHOD:提权方法,默认 sudo
  • --become-user=BECOME_USER:要提权到的用户,默认 root

通过标记控制任务执行范围

为任务设置标记

通过标记可以设置只执行部分任务。

通过 tags: 参数可以给 tasks 设置标记:

[root@study ansible]# cat tag.yml
- name: test tag
  hosts: localhost
  gather_facts: false
  tasks:
  - name: print one
    ansible.builtin.debug:
      msg: "one"
    tags:
    - example
  - name: print two
    ansible.builtin.debug:
      msg: "two"
    tags:
    - example
    - example2
  - name: print three
    ansible.builtin.debug:
      msg: "three"

这里给第二个 tasks 添加了一个标记为 example,此时如果直接执行 Playbook,结果如下:

[root@study ansible]# ansible-playbook tag.yml

PLAY [test tag] *************************************************************************************************************

TASK [print one] ************************************************************************************************************
ok: [localhost] => {
    "msg": "one"
}

TASK [print two] ************************************************************************************************************
ok: [localhost] => {
    "msg": "two"
}

TASK [print three] **********************************************************************************************************
ok: [localhost] => {
    "msg": "three"
}

PLAY RECAP ******************************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

可以看到三个任务都执行了,如果指定 tag 后在执行,结果如下:

[root@study ansible]# ansible-playbook --tag example tag.yml

PLAY [test tag] *************************************************************************************************************

TASK [print one] ************************************************************************************************************
ok: [localhost] => {
    "msg": "one"
}

TASK [print two] ************************************************************************************************************
ok: [localhost] => {
    "msg": "two"
}

PLAY RECAP ******************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@study ansible]# ansible-playbook --tag example2 tag.yml

PLAY [test tag] *************************************************************************************************************

TASK [print two] ************************************************************************************************************
ok: [localhost] => {
    "msg": "two"
}

PLAY RECAP ******************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

可以看到只有第二个 tasks 执行了。

一个标记可以用于多个 tasks,一个 tasks 也可以打多个标记。

handlers 会忽略标记。

如果要给 block 打标记,记得给 rescuealways 也打上标记,否则 rescuealways 的任务就不会执行。

标记不仅仅支持 tasks,也支持给 Playbook 打标记,跟 hosts 一个层级。

为导入任务设置标记

include_*

include_* 是动态导入,有 include_tasksinclude_role,这里以 include_tasks 为例:

[root@study ansible]# cat include_tag.yml
- name: test tag
  hosts: localhost
  gather_facts: false
  tasks:
  - name: include
    ansible.builtin.include_tasks: include_import_tasks.yml
    tags: test_include
[root@study ansible]# cat include_import_tasks.yml
---
- name: print one
  ansible.builtin.debug:
    msg: "one"
  tags:
  - example
- name: print two
  ansible.builtin.debug:
    msg: "two"
  tags:
  - example
  - example2
- name: print three
  ansible.builtin.debug:
    msg: "three"

# 执行任务测试
[root@study ansible]# ansible-playbook include_tag.yml --tag example2

PLAY [test tag] ****************************************************************************************************

PLAY RECAP *********************************************************************************************************

[root@study ansible]# ansible-playbook include_tag.yml --tag test_include

PLAY [test tag] ****************************************************************************************************

TASK [include] *****************************************************************************************************
included: /root/ansible/include_import_tasks.yml for localhost

PLAY RECAP *********************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@study ansible]# ansible-playbook include_tag.yml --tag example2,test_include

PLAY [test tag] ****************************************************************************************************

TASK [include] *****************************************************************************************************
included: /root/ansible/include_import_tasks.yml for localhost

TASK [print two] ***************************************************************************************************
ok: [localhost] => {
    "msg": "two"
}

PLAY RECAP *********************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

可以看到 include_taskstags 只限制 include_tasks 是否执行,只使用 include_taskstags 虽然会执行任务动态导入,但是导入后的任务也只会执行带有对应 tags 的任务,使用时需要额外指定被导入任务里的 tags

简单测试了一下 include_role 应该跟 include_tasks 一样。

import_*

import_* 是静态导入,有 import_tasksimport_roleimport_playbook

这里以 import_tasks 为例:

[root@study ansible]# cat import_tag.yml
- name: test tag
  hosts: localhost
  gather_facts: false
  tasks:
  - name: import
    ansible.builtin.import_tasks: include_import_tasks.yml
    tags: test_import
[root@study ansible]# cat include_import_tasks.yml
---
- name: print one
  ansible.builtin.debug:
    msg: "one"
  tags:
  - example
- name: print two
  ansible.builtin.debug:
    msg: "two"
  tags:
  - example
  - example2
- name: print three
  ansible.builtin.debug:
    msg: "three"

# 执行任务测试
[root@study ansible]# ansible-playbook import_tag.yml --tag test_import

PLAY [test tag] ****************************************************************************************************

TASK [print one] ***************************************************************************************************
ok: [localhost] => {
    "msg": "one"
}

TASK [print two] ***************************************************************************************************
ok: [localhost] => {
    "msg": "two"
}

TASK [print three] *************************************************************************************************
ok: [localhost] => {
    "msg": "three"
}

PLAY RECAP *********************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@study ansible]# ansible-playbook import_tag.yml --tag example2

PLAY [test tag] ****************************************************************************************************

TASK [print two] ***************************************************************************************************
ok: [localhost] => {
    "msg": "two"
}

PLAY RECAP *********************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

和动态导入不同,import_tasks 在导入任务的时候会将自己的 tags 附加给被导入的任务,使用 import_taskstags 会执行所有被导入的任务,因为是静态导入,所以直接使用被导入任务里的 tags 也能执行任务。

简单测试了一下,import_roleimport_playbook,还有通过 roles 使用角色,效果都和 import_tasks 一样。

为动态导入集成标记

include_* 默认不会将自己的 tags 传递给被导入的任务,想要将标记传递给被导入的任务可以使用如下两种方式:

- name: include
  ansible.builtin.include_tasks:
    file: include_import_tasks.yml
    apply:
      tags:
      - test_apply
  tags: test_include

或者

- block:
   - name: include
     ansible.builtin.include_tasks: include_import_tasks.yml
  tags: test_apply

特殊标记

Ansible 有几个特殊标记:alwaysnevertaggeduntaggedall。其中 alwaysnever 用于标记任务。

  • always:用于标记任务,表示不管指定什么 tags ,这个任务都会执行
  • never:用于标记任务,表示如果每有显式指定 tags,则任务不会执行
  • tagged:用于 ansible-playbook --tags,表示执行所有被设置 tags 的任务(带有 never 标记任务除外)
  • untagged:用于 ansible-playbook --tags,表示执行所有未设置 tags 的任务
  • all:用于 ansible-playbook --tags,执行所有带 tags 和不带 tags 的任务(带有 never 标记任务除外)

alwaysnever 就不做过多介绍了,可以自己测试,前者加上之后任务始终运行,后者任务始终不运行。

后边三个简单说一下:

[root@study ansible]# cat tag.yml
- name: test tag
  hosts: localhost
  gather_facts: false
  tasks:
  - name: print one
    ansible.builtin.debug:
      msg: "one"
    tags:
    - example
    - always
  - name: print two
    ansible.builtin.debug:
      msg: "two"
    tags:
    - example
    - example2
    - never
  - name: print three
    ansible.builtin.debug:
      msg: "three"
[root@study ansible]# ansible-playbook tag.yml --tags tagged

PLAY [test tag] ****************************************************************************************************

TASK [print one] ***************************************************************************************************
ok: [localhost] => {
    "msg": "one"
}

PLAY RECAP *********************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

[root@study ansible]# ansible-playbook tag.yml --tags untagged

PLAY [test tag] ****************************************************************************************************

TASK [print one] ***************************************************************************************************
ok: [localhost] => {
    "msg": "one"
}

TASK [print three] *************************************************************************************************
ok: [localhost] => {
    "msg": "three"
}

PLAY RECAP *********************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

[root@study ansible]# ansible-playbook tag.yml --tags all

PLAY [test tag] ****************************************************************************************************

TASK [print one] ***************************************************************************************************
ok: [localhost] => {
    "msg": "one"
}

TASK [print three] *************************************************************************************************
ok: [localhost] => {
    "msg": "three"
}

PLAY RECAP *********************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@study ansible]# ansible-playbook tag.yml --tags never

PLAY [test tag] ****************************************************************************************************

TASK [print one] ***************************************************************************************************
ok: [localhost] => {
    "msg": "one"
}

TASK [print two] ***************************************************************************************************
ok: [localhost] => {
    "msg": "two"
}

PLAY RECAP *********************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

上边可以看到,always 始终运行,tagged 执行所有带标记且不带 never 标记的任务,untagged 执行所有不带标记和带有 always 标记的任务

列出标记和跳过标记

通过 --list-tags 可以列出标记:

[root@study ansible]# ansible-playbook --list-tags tag.yml

playbook: tag.yml

  play #1 (localhost): test tag TAGS: []
      TASK TAGS: [always, example, example2, never]

通过 --skip-tags 可以跳过标记的任务:

[root@study ansible]# cat tag.yml
- name: test tag
  hosts: localhost
  gather_facts: false
  tasks:
  - name: print one
    ansible.builtin.debug:
      msg: "one"
    tags:
    - example
    - always
  - name: print two
    ansible.builtin.debug:
      msg: "two"
    tags:
    - example
    - example2
    - never
  - name: print three
    ansible.builtin.debug:
      msg: "three"
[root@study ansible]# ansible-playbook --skip-tags example tag.yml

PLAY [test tag] ****************************************************************************************************

TASK [print three] *************************************************************************************************
ok: [localhost] => {
    "msg": "three"
}

PLAY RECAP *********************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

--skip-tags 优先级比 --tags 高。

--skip-tags 可以跳过带有 always 标记的任务。

设置 Playbook 开始位置和交互式确认

设置 Playbook 开始位置

通过 --start-at-task 和 Playbook 的名字来设置从哪开始执行 Playbook。

[root@study ansible]# cat tag.yml
- name: test tag
  hosts: localhost
  gather_facts: false
  tasks:
  - name: print one
    ansible.builtin.debug:
      msg: "one"
    tags:
    - example
    - always
  - name: print two
    ansible.builtin.debug:
      msg: "two"
    tags:
    - example
    - example2
  - name: print three
    ansible.builtin.debug:
      msg: "three"
[root@study ansible]# ansible-playbook tag.yml --start-at-task "print two"

PLAY [test tag] ****************************************************************************************************

TASK [print two] ***************************************************************************************************
ok: [localhost] => {
    "msg": "two"
}

TASK [print three] *************************************************************************************************
ok: [localhost] => {
    "msg": "three"
}

PLAY RECAP *********************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

交互式确认执行

通过 --step 设置交互式执行任务。

交互式有三种选项:

  • yes:执行这个任务
  • no:不执行这个任务
  • continue:自动执行后续所有任务
[root@study ansible]# ansible-playbook tag.yml

PLAY [test tag] ****************************************************************************************************

TASK [print one] ***************************************************************************************************
ok: [localhost] => {
    "msg": "one"
}

TASK [print two] ***************************************************************************************************
ok: [localhost] => {
    "msg": "two"
}

TASK [print three] *************************************************************************************************
ok: [localhost] => {
    "msg": "three"
}

PLAY RECAP *********************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

[root@study ansible]# ansible-playbook --step tag.yml

PLAY [test tag] ****************************************************************************************************
Perform task: TASK: print one (N)o/(y)es/(c)ontinue: y

Perform task: TASK: print one (N)o/(y)es/(c)ontinue: ***************************************************************

TASK [print one] ***************************************************************************************************
ok: [localhost] => {
    "msg": "one"
}
Perform task: TASK: print two (N)o/(y)es/(c)ontinue: n

Perform task: TASK: print two (N)o/(y)es/(c)ontinue: ***************************************************************
Perform task: TASK: print three (N)o/(y)es/(c)ontinue: y

Perform task: TASK: print three (N)o/(y)es/(c)ontinue: *************************************************************

TASK [print three] *************************************************************************************************
ok: [localhost] => {
    "msg": "three"
}

PLAY RECAP *********************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

[root@study ansible]# ansible-playbook --step tag.yml

PLAY [test tag] ****************************************************************************************************
Perform task: TASK: print one (N)o/(y)es/(c)ontinue: n

Perform task: TASK: print one (N)o/(y)es/(c)ontinue: ***************************************************************
Perform task: TASK: print two (N)o/(y)es/(c)ontinue: c

Perform task: TASK: print two (N)o/(y)es/(c)ontinue: ***************************************************************

TASK [print two] ***************************************************************************************************
ok: [localhost] => {
    "msg": "two"
}

TASK [print three] *************************************************************************************************
ok: [localhost] => {
    "msg": "three"
}

PLAY RECAP *********************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Ansible Playbook 执行策略

设置主机执行策略

通过 strategy: 设置主机执行策略。

- name: test
  hosts: all
  gather_facts: false
  strategy: free
  tasks:

通过 ansible-doc -t strategy -l 可以查看有哪些策略插件:

[root@study ansible]# ansible-doc -t strategy -l
ansible.builtin.debug       Executes tasks in interactive debug session
ansible.builtin.free        Executes tasks without waiting for all hosts
ansible.builtin.host_pinned Executes tasks on each host without interruption
ansible.builtin.linear      Executes tasks in a linear fashion
strategy 名称 特点 使用场景 Ansible 版本
linear 默认策略,所有主机执行完某个任务后在继续执行下一个任务 一般情况 所有版本
free 主机之间并发执行任务,不等其他主机完成 性能测试、节点独立部署 所有版本
host_pinned 每个主机独立执行整个 play 中的所有任务(有点类似 serial: 1 针对节点完整生命周期操作 Ansible 2.11+
debug 每执行一步打印所有细节 排错场景 所有版本(较少用)
  • linear:所有主机同步推进任务。

    task1:  host1 host2 host3
    task2:  host1 host2 host3
    task3:  host1 host2 host3
  • free:主机各自独立运行,不等待其他主机。

    host1: task1 -> task2 -> task3
    host2: task1 -> task2 -> task3
    host3: task1 -> task2 -> task3
  • host_pinned:每台主机完整执行一遍 play,再轮到下一台主机。

    host1: task1 -> task2 -> task3
            |
    host2:    └───task1 -> task2 -> task3
                      |
    host3:              └───task1 -> task2 -> task3
    • 每个主机的 play 中所有 taskhandlerrescuealways 等都会执行完整流程
    • 主机之间严格串行执行
    • 常见于需要:
    • 整台机器部署生命周期控制
    • 避免并发时资源冲突
    • 精准排查单主机问题

示例:

[root@remote-host ansible]# ansible all --list-hosts
  hosts (3):
    base-k8s-master-1
    base-k8s-worker-1
    base-k8s-worker-2

# 默认情况
[root@remote-host ansible]# cat test.yml
- name: test environment
  hosts: all
  gather_facts: true
  #strategy: host_pinned
  tasks:
  - name: get env
    ansible.builtin.shell: /bin/env
    register: shell_result
    notify: test
  - name: print env
    ansible.builtin.debug:
      var: shell_result.rc
  - name: print env1
    ansible.builtin.debug:
      var: shell_result.rc
  handlers:
  - name: test
    debug:
      msg: "1"

# 执行结果
[root@remote-host ansible]# ansible-playbook test.yml

PLAY [test environment] ************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************
ok: [base-k8s-worker-2]
ok: [base-k8s-worker-1]
ok: [base-k8s-master-1]

TASK [get env] *********************************************************************************************************
changed: [base-k8s-worker-2]
changed: [base-k8s-worker-1]
changed: [base-k8s-master-1]

TASK [print env] *******************************************************************************************************
ok: [base-k8s-master-1] => {
    "shell_result.rc": "0"
}
ok: [base-k8s-worker-1] => {
    "shell_result.rc": "0"
}
ok: [base-k8s-worker-2] => {
    "shell_result.rc": "0"
}

TASK [print env1] ******************************************************************************************************
ok: [base-k8s-master-1] => {
    "shell_result.rc": "0"
}
ok: [base-k8s-worker-1] => {
    "shell_result.rc": "0"
}
ok: [base-k8s-worker-2] => {
    "shell_result.rc": "0"
}

PLAY RECAP *************************************************************************************************************
base-k8s-master-1          : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
base-k8s-worker-1          : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
base-k8s-worker-2          : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

# 修改策略为 host_pinned
[root@remote-host ansible]# cat test.yml
- name: test environment
  hosts: all
  gather_facts: true
  strategy: host_pinned
  tasks:
  - name: get env
    ansible.builtin.shell: /bin/env
    register: shell_result
    notify: test
  - name: print env
    ansible.builtin.debug:
      var: shell_result.rc
  - name: print env1
    ansible.builtin.debug:
      var: shell_result.rc
  handlers:
  - name: test
    debug:
      msg: "1"

# 执行结果
[root@remote-host ansible]# ansible-playbook test.yml

PLAY [test environment] ************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************
ok: [base-k8s-worker-2]
ok: [base-k8s-master-1]

TASK [get env] *********************************************************************************************************
changed: [base-k8s-worker-2]

TASK [print env] *******************************************************************************************************
ok: [base-k8s-worker-2] => {
    "shell_result.rc": "0"
}

TASK [Gathering Facts] *************************************************************************************************
ok: [base-k8s-worker-1]

TASK [print env1] ******************************************************************************************************
ok: [base-k8s-worker-2] => {
    "shell_result.rc": "0"
}

TASK [get env] *********************************************************************************************************
changed: [base-k8s-master-1]

TASK [print env] *******************************************************************************************************
ok: [base-k8s-master-1] => {
    "shell_result.rc": "0"
}

TASK [print env1] ******************************************************************************************************
ok: [base-k8s-master-1] => {
    "shell_result.rc": "0"
}

TASK [get env] *********************************************************************************************************
changed: [base-k8s-worker-1]

TASK [print env] *******************************************************************************************************
ok: [base-k8s-worker-1] => {
    "shell_result.rc": "0"
}

TASK [print env1] ******************************************************************************************************
ok: [base-k8s-worker-1] => {
    "shell_result.rc": "0"
}

PLAY RECAP *************************************************************************************************************
base-k8s-master-1          : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
base-k8s-worker-1          : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
base-k8s-worker-2          : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

在使用 host_pinned 时,有的节点的 Gathering Facts 任务可能会在其他节点的任务之后执行,这个和 host_pinned 的单节点执行任务并不冲突,因为 Gathering Facts 是收集信息不会影响其他节点执行任务。

我没测试,这样的话估计会影响其他节点获取这个节点的 ansible_facts 变量。

设置并发数

Ansible 支持设置 Ansible 并发数(一次性最多对多少主机执行任务),并发数可以通过配置文件和 Ad-Hoc 设置:

配置文件:

[defaults]
forks = 30

Ad-Hoc:

[root@study ansible]# ansible-playbook -f 30 playbook.yml

设置批量管理主机数量

Ansible 通过队列执行任务,可以通过 serial 可以设置每个队列管理的主机数量(用于滚动更新)。

这个和 forks 不同,forks 是设置的是 Ansible 执行任务时一次性管理多少主机,serial 设置的是在 forks 基础上一个队列里最多有多少个主机执行任务。

serial 支持数量、百分比和列表三种种方式。

数量:

- name: test
  hosts: all
  serial: 1

一个队列执行一个主机。

百分比:

- name: test
  hosts: all
  serial: 30%

一个队列执行 30% 的主机(向下取整,最少一台)。

列表:

- name: test
  hosts: all
  serial:
  - 1
  - 5
  - 10

- name: test
  hosts: all
  serial:
  - 10%
  - 20%
  - 100%

第一个表示:

  1. 第一次队列执行 1 台
  2. 第二次队列执行 5 台
  3. 后续的队列每次 10 台

第二个表示(假设 hostsall 有 10 台):

  1. 第一次队列执行 all 的 10% 的主机(1 台)
  2. 第二次队列执行 all 的 20% 的主机(2 台)
  3. 第三次队列执行 all 的剩余所有主机(7 台)

列表还可以组合使用:

- name: test
  hosts: all
  serial:
  - 1
  - 5
  - 20%

第一次 1 台,第二次 5 台,后续每次 20%。

限制单个任务执行数量

forksserial 都是在 Playbook 级别限制,如果想在一个 tasks 上限制可以使用 throttle,不过这个可能占用大量 CPU 资源。

throttle 支持在 tasksblock 上设置。

tasks:
- command: /path/to/cpu_intensive_command
  throttle: 1

如果将 throttlsforksserial 同时使用,则 throttle 要小于它俩。

设置主机执行顺序

通过 order 可以设置主机执行顺序,order 有如下几个选项:

  • inventory:根据 Ansible 编译后的主机清单执行,主机顺序可预测但不可重现
  • reverse_inventory:和 inventory 相反
  • sorted:根据字母顺序排序
  • reverse_sorted:跟 sorted 相反
  • shuffle:随机排序
- name: test
  hosts: all
  order: sorted

设置任务只执行一次

通过 run_once 可以设置任务只执行一次(只在当前队列的第一台主机上执行

),通常与 delegate_to 组合使用,实现只在某个节点执行任务。

- name: run_once
  ansible.builtin.debug:
    msg: "run_once"
  run_once: true
Ansible 执行 Playbook
https://www.linuxstudynotes.com/2025/10/16/ansible/ansible-%e6%89%a7%e8%a1%8c-playbook/
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇