使用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.
我收到了16个失败和两个警告。
接下来我会进行修正。
请提供要指摘的内容。
-
- 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.
在中文中,不触发失败和警告的方法。
首先,我们在根目录下创建一个.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]
如果想要忽略,请按照以下方式记录。
skip_list:
- yaml[truthy]
失败和警告都已经归零。
请参考下方的内容,其中还有其他不适用于特定路径下规则的排除路径(exclude_paths)。
通过使用ansible-lint,我意识到不要使用不保证幂等性的shell脚本,还能给代码带来统一性,我觉得它是个很好的工具!
请参考
模块列表
错误内容
(Error content)
ansible-lint的使用方法