使用ansible-lint来统一代码编写方式

首先

上次,我使用Ansible更改了EC2(Amazon Linux 2)的端口号。
现在我要对那段代码进行ansible-lint处理,以确保代码具有适当的一致性。

 

当前的目录结构

$ tree
.
├── hosts
├── playbook.yml
└── roles
    └── sshd
        ├── handlers
        │   └── main.yml
        └── tasks
            └── main.yml

4 directories, 4 files

当前文件的内容

- name: Change port
  hosts: web
  become: yes
  gather_facts: false
  roles:
    - sshd
- name: Restart sshd
  service:
    name: sshd
    state: restarted
# port22 でSSH接続する。タイムアウトは5秒で、接続失敗しても次に進む
- name: Connect default ssh port
  local_action: wait_for port={{ansible_ssh_port}} timeout=5 host={{inventory_hostname}}
  register: default_port
  ignore_errors: true
  become: False

# port22 で失敗した場合、port 50001でSSH接続する。タイムアウトは5秒
- name: Connect custom ssh port
  local_action: wait_for port={{custom_ssh_port}} timeout=5 host={{inventory_hostname}}
  register: custom_port
  when: default_port.elapsed >= 5
  become: False

# port22 でタイムアウトし、port50001でSSH接続成功した場合、ansible_ssh_portを50001に変える
- name: set ansible_ssh_port custom_ssh_port
  set_fact: ansible_ssh_port={{custom_ssh_port}}
  when: default_port.elapsed >= 5 and custom_port.elapsed < 5
  become: False

# 現在port22でSSH接続している場合、/etc/ssh/sshd_configのPortを50001に書き換える
- name: Rewrite custom_ssh_port
  lineinfile:
    dest: /etc/ssh/sshd_config
    regexp: '^#Port'
    line: 'Port {{custom_ssh_port}}'
  notify: Restart sshd
  when: ansible_ssh_port == 22

# ssh接続時のパスワード認証を無効
- name: Disabling password authentication
  lineinfile:
    dest: /etc/ssh/sshd_config
    regexp: '^PasswordAuthentication'
    insertafter: '^#PasswordAuthentication'
    line: PasswordAuthentication no
  notify: Restart sshd

# ssh接続時のチャレンジ/レスポンス認証を無効
- name: Disabling Challenge-Response Authentication
  lineinfile:
    dest: /etc/ssh/sshd_config
    regexp: '^ChallengeResponseAuthentication'
    insertafter: '^#ChallengeResponseAuthentication'
    line: ChallengeResponseAuthentication no
  notify: Restart sshd

# rootユーザーのログイン無効
- name: Disabling root user login
  lineinfile:
    dest: /etc/ssh/sshd_config
    regexp: '^PermitRootLogin'
    insertafter: '^#PermitRootLogin'
    line: PermitRootLogin no
  notify: Restart sshd

安装ansible-lint

若談到Mac的情况下

$ brew install ansible-lint

可以使用pip

$ pip install ansible-lint

尝试运行ansible-lint

% ansible-lint playbook.yml
WARNING  Ignore loading rule from /usr/local/Cellar/ansible-lint/6.9.0/libexec/lib/python3.10/site-packages/ansiblelint/rules/jinja.py due to No module named 'black'
WARNING  Listing 18 violation(s) that are fatal
yaml[truthy]: Truthy value should be one of [false, true]
playbook.yml:3

yaml[new-line-at-end-of-file]: No new line character at the end of file
playbook.yml:6

fqcn[action-core]: Use FQCN for builtin module actions (service).
roles/sshd/handlers/main.yml:1 Use `ansible.builtin.service` or `ansible.legacy.service` instead.

yaml[new-line-at-end-of-file]: No new line character at the end of file
roles/sshd/handlers/main.yml:4

deprecated-local-action: Do not use 'local_action', use 'delegate_to: localhost'.
roles/sshd/tasks/main.yml:2 Task/Handler: Connect default ssh port

fqcn[action-core]: Use FQCN for builtin module actions (wait_for).
roles/sshd/tasks/main.yml:2 Use `ansible.builtin.wait_for` or `ansible.legacy.wait_for` instead.

yaml[truthy]: Truthy value should be one of [false, true]
roles/sshd/tasks/main.yml:6

deprecated-local-action: Do not use 'local_action', use 'delegate_to: localhost'.
roles/sshd/tasks/main.yml:9 Task/Handler: Connect custom ssh port

fqcn[action-core]: Use FQCN for builtin module actions (wait_for).
roles/sshd/tasks/main.yml:9 Use `ansible.builtin.wait_for` or `ansible.legacy.wait_for` instead.

yaml[truthy]: Truthy value should be one of [false, true]
roles/sshd/tasks/main.yml:13

fqcn[action-core]: Use FQCN for builtin module actions (set_fact).
roles/sshd/tasks/main.yml:16 Use `ansible.builtin.set_fact` or `ansible.legacy.set_fact` instead.

name[casing]: All names should start with an uppercase letter. (warning)
roles/sshd/tasks/main.yml:16 Task/Handler: set ansible_ssh_port custom_ssh_port

no-free-form: Avoid using free-form when calling module actions. (set_fact) (warning)
roles/sshd/tasks/main.yml:16 Task/Handler: set ansible_ssh_port custom_ssh_port

yaml[truthy]: Truthy value should be one of [false, true]
roles/sshd/tasks/main.yml:19

fqcn[action-core]: Use FQCN for builtin module actions (lineinfile).
roles/sshd/tasks/main.yml:22 Use `ansible.builtin.lineinfile` or `ansible.legacy.lineinfile` instead.

fqcn[action-core]: Use FQCN for builtin module actions (lineinfile).
roles/sshd/tasks/main.yml:31 Use `ansible.builtin.lineinfile` or `ansible.legacy.lineinfile` instead.

fqcn[action-core]: Use FQCN for builtin module actions (lineinfile).
roles/sshd/tasks/main.yml:39 Use `ansible.builtin.lineinfile` or `ansible.legacy.lineinfile` instead.

fqcn[action-core]: Use FQCN for builtin module actions (lineinfile).
roles/sshd/tasks/main.yml:48 Use `ansible.builtin.lineinfile` or `ansible.legacy.lineinfile` instead.

You can skip specific rules or tags by adding them to your configuration file:
# .config/ansible-lint.yml
warn_list:  # or 'skip_list' to silence them completely
  - deprecated-local-action  # Do not use 'local_action', use 'delegate_to: localhost'.
  - experimental  # all rules tagged as experimental
  - fqcn[action-core]  # Use FQCN for builtin actions.
  - yaml[new-line-at-end-of-file]  # Violations reported by yamllint.
  - yaml[truthy]  # Violations reported by yamllint.

                               Rule Violation Summary                                
 count tag                           profile    rule associated tags                 
     2 deprecated-local-action       basic      deprecations                         
     2 yaml[new-line-at-end-of-file] basic      formatting, yaml                     
     4 yaml[truthy]                  basic      formatting, yaml                     
     1 name[casing]                  moderate   idiom (warning)                      
     1 no-free-form                  moderate   syntax, risk, experimental (warning) 
     8 fqcn[action-core]             production formatting                           

Failed after min profile: 16 failure(s), 2 warning(s) on 3 files.
スクリーンショット 2022-11-27 23.46.27.png

我收到了16个失败和两个警告。
接下来我会进行修正。

请提供要指摘的内容。

    1. yaml[truthy] 真值应该是 [false, true] 中的一个。

true、false 应该是其中之一。

yaml[new-line-at-end-of-file] 文件末尾不应该有换行符。

在文件末尾添加一个空行。

fqcn[action-core] 对于内置模块动作(如lineinfile),应使用FQCN(完全限定类名)进行标识。

不要使用service,而是使用ansible.builtin.service。

deprecated-local-action 不要使用 ‘local_action’,而是使用 ‘delegate_to: localhost’。

不要使用 ‘local_action’,而是使用 ‘delegate_to: localhost’。

name[casing] 所有名称应以大写字母开头。

所有名称应以大写字母开头。

修正后的文件 de

这是修正后的文件。

- name: Change port
  hosts: web
  become: true
  gather_facts: false
  roles:
    - sshd
- name: Restart sshd
  ansible.builtin.service:
    name: sshd
    state: restarted

# port22 でSSH接続する。タイムアウトは5秒で、接続失敗しても次に進む
- name: Connect default ssh port
  ansible.builtin.wait_for:
    port: '{{ansible_ssh_port}}'
    timeout: 5
    host: '{{inventory_hostname}}'
  delegate_to: localhost
  register: default_ssh
  ignore_errors: true
  become: false

# port22 で失敗した場合、port 50001でSSH接続する。タイムアウトは5秒
- name: Connect custom ssh port
  ansible.builtin.wait_for:
    port: '{{custom_ssh_port}}'
    timeout: 5
    host: '{{inventory_hostname}}'
  delegate_to: localhost
  register: high_ssh
  when: default_ssh.elapsed >= 5
  become: false

# port22 でタイムアウトし、port50001でSSH接続成功した場合、ansible_ssh_portを50001に変える
- name: Set ansible_ssh_port custom_ssh_port
  ansible.builtin.set_fact:
    ansible_ssh_port: '{{custom_ssh_port}}'
  when: default_ssh.elapsed >= 5 and high_ssh.elapsed < 5
  become: false

# 現在port22でSSH接続している場合、/etc/ssh/sshd_configのPortを50001に書き換える
- name: Rewrite custom_ssh_port
  ansible.builtin.lineinfile:
    dest: /etc/ssh/sshd_config
    regexp: '^#Port'
    line: 'Port {{custom_ssh_port}}'
  notify: Restart sshd
  when: ansible_ssh_port == 22

# ssh接続時のパスワード認証を無効
- name: Disabling password authentication
  ansible.builtin.lineinfile:
    dest: /etc/ssh/sshd_config
    regexp: '^PasswordAuthentication'
    insertafter: '^#PasswordAuthentication'
    line: PasswordAuthentication no
  notify: Restart sshd

# ssh接続時のチャレンジ/レスポンス認証を無効
- name: Disabling Challenge-Response Authentication
  ansible.builtin.lineinfile:
    dest: /etc/ssh/sshd_config
    regexp: '^ChallengeResponseAuthentication'
    insertafter: '^#ChallengeResponseAuthentication'
    line: ChallengeResponseAuthentication no
  notify: Restart sshd

# rootユーザーのログイン無効
- name: Disabling root user login
  ansible.builtin.lineinfile:
    dest: /etc/ssh/sshd_config
    regexp: '^PermitRootLogin'
    insertafter: '^#PermitRootLogin'
    line: PermitRootLogin no
  notify: Restart sshd

修正后,failure和warning均变为了0。

$ ansible-lint playbook.yml
WARNING  Ignore loading rule from /usr/local/Cellar/ansible-lint/6.9.0/libexec/lib/python3.10/site-packages/ansiblelint/rules/jinja.py due to No module named 'black'

Passed with production profile: 0 failure(s), 0 warning(s) on 3 files.

在中文中,不触发失败和警告的方法。

スクリーンショット 2022-11-27 23.45.45.png

首先,我们在根目录下创建一个.config/ansible-lint.yml文件。

$ tree
.
├── hosts
├── playbook.yml
└── roles
    └── sshd
        ├── handlers
        │   └── main.yml
        └── tasks
            └── main.yml
$ mkdir .config
$ touch ansible-lint.yml
$ vim ansible-lint.yml

如果要将特定规则(yaml[truthy])从failure更改为warning,您可以按照以下方式更改.config/ansible-lint.yml文件。

warn_list:
  - yaml[truthy]
スクリーンショット 2022-11-27 23.53.37.png

如果想要忽略,请按照以下方式记录。

skip_list:
  - yaml[truthy]
スクリーンショット 2022-11-27 23.54.43.png

失败和警告都已经归零。

请参考下方的内容,其中还有其他不适用于特定路径下规则的排除路径(exclude_paths)。

 

通过使用ansible-lint,我意识到不要使用不保证幂等性的shell脚本,还能给代码带来统一性,我觉得它是个很好的工具!

请参考

模块列表

 

错误内容
(Error content)

 

ansible-lint的使用方法

 

广告
将在 10 秒后关闭
bannerAds