在 Ansible 中,copy 和 template 模块都可以将变量的值写入文件,但它们在功能和使用场景上有所不同。以下是对这两个模块的比较和详细示例。

Ansible 模块:copy vs template

1. ansible.builtin.copy 模块

copy 模块用于将文本内容直接写入文件。它处理空白字符和换行符,但对引号和转义字符的处理可能不够灵活。

优点:

  • 简单直接,适合写入简单的文本内容。
  • 可以在同一个 Playbook 文件中完成所有操作。

缺点:

  • 对复杂的格式化支持较差,尤其是当内容包含变量时。

示例代码:

---
- name: copy module demo
  hosts: all
  vars:
    fruit: "banana"
    output: "output.txt"
  tasks:
    - name: write to file
      ansible.builtin.copy:
        content: "{{ fruit }}"
        dest: "{{ output }}"

执行命令:

$ ansible-playbook -i virtualmachines/demo/inventory variables/write-file-copy.yml

执行结果:

PLAY [copy module demo] *********************************
TASK [Gathering Facts] **********************************
ok: [demo.example.com]
TASK [write to file] ************************************
changed: [demo.example.com]
PLAY RECAP **********************************************
demo.example.com           : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

幂等性测试:

$ ansible-playbook -i virtualmachines/demo/inventory variables/write-file-copy.yml

幂等性结果:

PLAY [copy module demo] *********************************
TASK [Gathering Facts] **********************************
ok: [demo.example.com]
TASK [write to file] ************************************
ok: [demo.example.com]
PLAY RECAP **********************************************
demo.example.com           : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

执行前状态:

$ ssh devops@demo.example.com
[devops@demo ~]$ ls
[devops@demo ~]$

执行后状态:

$ ssh devops@demo.example.com
[devops@demo ~]$ ls
output.txt
[devops@demo ~]$ cat output.txt 
banana
[devops@demo ~]$

2. ansible.builtin.template 模块

template 模块用于将 Jinja2 模板文件渲染到目标文件中。它支持复杂的格式化和变量处理,适合处理包含变量的内容。

优点:

  • 支持复杂的格式化和变量处理。
  • 更安全,适合动态内容。

缺点:

  • 需要创建一个单独的模板文件。

示例代码:

---
- name: template module demo
  hosts: all
  vars:
    fruit: "apple"
    output: "output.txt"
  tasks:
    - name: write to file
      ansible.builtin.template:
        src: "mytemplate.j2"
        dest: "{{ output }}"

模板文件(mytemplate.j2):

{{ fruit }}

执行命令:

$ ansible-playbook -i virtualmachines/demo/inventory variables/write-file-template.yml

执行结果:

PLAY [template module demo] *********************************
TASK [Gathering Facts] **********************************
ok: [demo.example.com]
TASK [write to file] ************************************
changed: [demo.example.com]
PLAY RECAP **********************************************
demo.example.com           : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

幂等性测试:

$ ansible-playbook -i virtualmachines/demo/inventory variables/write-file-template.yml

幂等性结果:

PLAY [template module demo] *********************************
TASK [Gathering Facts] **********************************
ok: [demo.example.com]
TASK [write to file] ************************************
ok: [demo.example.com]
PLAY RECAP **********************************************
demo.example.com           : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

执行前状态:

$ ssh devops@demo.example.com
[devops@demo ~]$ ls
[devops@demo ~]$

执行后状态:

$ ssh devops@demo.example.com
[devops@demo ~]$ cat output.txt 
apple
[devops@demo ~]$

总结

  • copy 模块:
    • 适用场景:适合写入简单的文本内容,尤其是当内容不包含变量时。
    • 优点:简单直接,适合快速操作。
    • 缺点:对复杂格式和变量支持较差。
  • template 模块:
    • 适用场景:适合写入包含变量或需要复杂格式化的文本内容。
    • 优点:支持变量处理和复杂格式化,更灵活和安全。
    • 缺点:需要创建模板文件,操作稍显复杂。

建议:

  • 如果需要写入简单的静态内容,使用 copy 模块。
  • 如果需要写入包含变量或需要动态处理的内容,优先使用 template 模块。