はじめに
前回、ansibleでEC2 (Amazon Linux2) のport番号を変更を行いました。
そのコードに対して、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のfailure
と2つのwarning
をもらいました。
これから修正していきます。
指摘内容
-
yaml[truthy]
Truthy value should be one of [false, true]- true、falseにしましょう
- 今回、
False
にしていました。
- 今回、
- true、falseにしましょう
-
yaml[new-line-at-end-of-file]
No new line character at the end of file- ファイルの最下部に空行をいれましょう
-
fqcn[action-core]
Use FQCN for builtin module actions (lineinfile).- モジュール名は、FQCN(Fully Qualified Class Nameの略。完全修飾クラス名。)で表記しましょう。
-
service
ではなく、ansible.builtin.service
と記載します。
-
- モジュール名は、FQCN(Fully Qualified Class Nameの略。完全修飾クラス名。)で表記しましょう。
-
deprecated-local-action
Do not use 'local_action', use 'delegate_to: localhost'.-
local_action
ではなく、delegate_to: localhost
を使いましょう
-
-
name[casing]
All names should start with an uppercase letter.- namesは、最初の文字の頭文字を大文字しましょう
修正後のファイル
修正後のファイルになります。
- 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.
failureとwarningを出さない方法
以下のようにfailure
が1つ表示されていますが、特定のfailure
は、warning
、もしくは、無視させたい場面がでると思います。
その方法について説明します。
まず、ルートディレクトリに.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]
) に対してfailture
からwarning
に変更させたい場合、.config/ansible-lint.yml
を以下のように変更します。
warn_list:
- yaml[truthy]
無視させたい場合、以下のように記載します。
skip_list:
- yaml[truthy]
failure
とwarning
が0になりました。
他にも特定のパス配下のみルールを適用しないexclude_paths
などがあります。
下記を参照して下さい。
ansible-lintを使うことで、冪等性が担保されないshell
を使わないように意識付けになったり、コードに統一感をもたせることができたり、よいツールだと感じました!
参考
モジュール一覧
エラー内容
ansible-lint使い方