Ansible相关语法

ansible 如果未定义变量,设置默认变量

参考最后一行name的实现, 如果my_variable 变量没有定义就会通过default()方法设置一个默认值

- name: Create user
  user:
    name: "{{ my_variable | default('这里设置默认值') }}"

参考: https://www.jianshu.com/p/b9a788788a51


ansible 查找文件列表及过滤匹配

参考: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/find_module.html

- name: Recursively find /tmp files older than 2 days
  find:
    paths: /tmp
    age: 2d
    recurse: yes

- name: Recursively find /tmp files older than 4 weeks and equal or greater than 1 megabyte
  find:
    paths: /tmp
    age: 4w
    size: 1m
    recurse: yes

- name: Recursively find /var/tmp files with last access time greater than 3600 seconds
  find:
    paths: /var/tmp
    age: 3600
    age_stamp: atime
    recurse: yes

- name: Find /var/log files equal or greater than 10 megabytes ending with .old or .log.gz
  find:
    paths: /var/log
    patterns: '*.old,*.log.gz'
    size: 10m

# Note that YAML double quotes require escaping backslashes but yaml single quotes do not.
- name: Find /var/log files equal or greater than 10 megabytes ending with .old or .log.gz via regex
  find:
    paths: /var/log
    patterns: "^.*?\\.(?:old|log\\.gz)$"
    size: 10m
    use_regex: yes

- name: Find /var/log all directories, exclude nginx and mysql
  find:
    paths: /var/log
    recurse: no
    file_type: directory
    excludes: 'nginx,mysql'

# When using patterns that contain a comma, make sure they are formatted as lists to avoid splitting the pattern
- name: Use a single pattern that contains a comma formatted as a list
  find:
    paths: /var/log
    file_type: file
    use_regex: yes
    patterns: ['^_[0-9]{2,4}_.*.log$']

- name: Use multiple patterns that contain a comma formatted as a YAML list
  find:
    paths: /var/log
    file_type: file
    use_regex: yes
    patterns:
      - '^_[0-9]{2,4}_.*.log$'
      - '^[a-z]{1,5}_.*log$'

删除文件目录及文件

- name: Clean artifact path
  file:
    state: absent
    path: "{{ artifact_path }}/"

注意这也会删除目录

将变量列表全部转换成大写

  • ansible_interfaces 的值转换成大写的列表格式

    - hosts: localhost
      tasks:
        - name: print interfaces
          debug:
            msg: "{{ ansible_interfaces | map('upper') | list }}"
    
  • , 输出如下

    TASK [print interfaces] ***************************************************
    ok: [localhost] {
        "msg": [
            "DOCKER0", 
            "LO", 
            "VETH3E8C318", 
            "WLAN0", 
            "DOCKERCON", 
            "ETH0", 
            "VETHE2459C9"
        ]
    }
    

原文参考: https://www.tailored.cloud/devops/how-to-filter-and-map-lists-in-ansible
map方法 还支持其他更多功能, 详情见: https://jinja.palletsprojects.com/en/2.10.x/templates/#map


  • 例如: 实现获取/tmp下的目录列表, map(attribute='path') 用于获取files对象path对应的值

    - hosts: localhost
      tasks:
        - name: 获取目录列表
          find:
            paths: "/tmp"
            recurse: no
            file_type: directory        
          register: dirObjectList
          
        - name: 设置目录列表变量
          set_fact:
             dirList: "{{ dirObjectList.files | map(attribute='path') | list }}"
          
        - name: 显示目录列表      
          debug:
           msg: "{{ dirList}}"      
    

    显示如下:

    TASK [显示目录列表] ********************************************************************************************************************************************
    ok: [localhost] => {
        "msg": [
            "/tmp/undo",
            "/tmp/upgrade"
        ]
    }
    

在tasks中使用交互变量

  • 利用 pause 实现在tasks中读取交互变量

    - hosts: localhost
      tasks:
        - pause:
            prompt: "Please enter the value for kernel.shmmax "
            echo: yes
          register: result
        - set_fact:
            shmmax: "{{ result.user_input }}"
        - debug:
            var: shmmax
    

  • 需要注意的是下面这种用法是错误的, 会报语法错误

    - name: shmmax
          prompt: " Please enter the value for kernel.shmmax "
          private: false
    

    参考: https://serverfault.com/questions/969121/ansible-prompt-a-variable-in-a-task

使用变量作为数组下标

  • 例如 {{nics[num].ip}} 是获取nics数组下标为num变量的值
    
    # ansible-playbook test.yml --extra-vars "num=0"
    [SNIP]
    TASK: [Static IP Case - Find out Static Overlay IP] *************************** 
    fatal: [127.0.0.1] => One or more undefined variables: 'list object' has no attribute u'0'
    # cat nics.yml 
    ---
    nics:
    - {type: 'static', ip: '10.3.5.4'}
    - {type: 'dhcp'}
    - {type: 'static', ip: '10.3.5.5'}
    
    # cat test.yml 
    - hosts: 127.0.0.1
      vars_files:
        - "nics.yml"
      tasks:
    
    # Static IP Case: Find out the Overlay IP
        - name: Static IP Case - Find out Static Overlay IP
          set_fact: 
             cvmip: "{{nics[num].ip}}"
          when:  nics[num|int].type == "static"
    
        - name: Write Overlay IP to file
          shell: echo {{cvmip}} >> /tmp/staticip.txt
          when:  nics[num|int].type == "static"
    
    参考: https://groups.google.com/g/ansible-project/c/wDSJZ72KiFo?pli=1

Jinja2在ansible中操作变量

  • 变量赋值

    {% set name='xx' %}
    
  • 局部变量

    {% with foo = 42 %}
    {{ foo }}
    {% endwith %}
    
  • 变量类型转换

    {% set node = "prometheus-"+ loop.index | string %}
    
  • if/else/elif/endif

    {% if foo | bool %}
    ...
    {% elif not foo1 %}
    ...
    {% else %}
    ...
    {% endif %}
    
  • 遍历list

    {% for user in users %}
    {{ user.username | e }}
    {% endfor %}	
    
  • 遍历字典

    {% for key, value in my_dict.iteritems() %}
    {{ key|e }}
    {{ value|e }}
    {% endfor %}
    

参考: https://blog.csdn.net/weixin_42119008/article/details/109345221

传递变量到include_tasks 或import_tasks

tasks:
- import_tasks: wordpress.yml
  vars:
    wp_user: timmy
- import_tasks: wordpress.yml
  vars:
    wp_user: alice
- import_tasks: wordpress.yml
  vars:
    wp_user: bob
  • import_tasks: 静态加载,也就是 playbook 在运行一开始解析的时候,加载子任务中全部变量。

  • include_tasks: 动态加载,就是在执行到该子任务的时候,才会加载该子任务中全部变量。

  • import_tasks 调用的子任务文件名称也就不可以使用变量,但是 include_tasks 调用的子任务名称则可以加变量。

  • import_tasks 会调用子任务中的所有 tag,使用 –list-tags 参数时也能看到,但是 include_tasks 调用的子任务中如果定义了tag,则不会生效。

参考:

  • https://blog.51cto.com/liubin0505star/2572443
  • https://docs.ansible.com/ansible/2.9/user_guide/playbooks_variables.html#ansible-variable-precedence

字符串去掉空格并比较

  • 使用和python的strip一样

    {{ string | trim }} == string.strip()
    
  • 列表去空格

    "{{ runconfserafter.stdout_lines | map('trim') | list }}"
    

参考:

  • https://www.cnblogs.com/wangl-blog/p/9266359.html
  • https://qa.1r1g.com/sf/ask/3571072081/

生成指定范围内的整数列表

  • 例如user1user20
- set_fact:
    users: "{{ users | default([]) + ['user%s' | format(item)] }}"
  loop: "{{ range(1, 21) | list }}"
  • 输出
{
    "users": [
        "user1",
        "user2",
        "user3",
        "user4",
        "user5",
        "user6",
        "user7",
        "user8",
        "user9",
        "user10",
        "user11",
        "user12",
        "user13",
        "user14",
        "user15",
        "user16",
        "user17",
        "user18",
        "user19",
        "user20"
    ]
}

参考: https://stackoverflow.com/questions/66176582/how-to-generate-a-list-with-a-range-and-save-it-in-a-var-of-a-playbook

列表长度加一

- name: 测试列表
  hosts: localhost

     dirList: ["一","二","三","四","五"]
  tasks:
    - name: 遍历输出
      debug:
         msg: "{{item}}"
      loop: "{{ range(1, (dirList|length|int + 1)  ) | list }} "
  • 输出:
TASK [遍历输出] *****************************************************
ok: [localhost] => (item=1) => {
    "msg": 1
}
ok: [localhost] => (item=2) => {
    "msg": 2
}
ok: [localhost] => (item=3) => {
    "msg": 3
}
ok: [localhost] => (item=4) => {
    "msg": 4
}
ok: [localhost] => (item=5) => {
    "msg": 5
}

Ansible如何为每个主机顺序执行剧本

加上--forks=1指定要使用的并行进程数(默认= 5) , 剧本中还可以通过strategy策略来控制并行模式,
共有3种策略:linear 线性(默认),serial 串行 和 free(最快)

参考:
https://stackoverflow.com/questions/27315469/ansible-how-to-sequentially-execute-playbook-for-each-host
https://docs.ansible.com/ansible/latest/user_guide/playbooks_strategies.html#selecting-a-strategy

你可能感兴趣的:(Ansible,linux,centos,Ansible,运维,运维开发)