LoginSignup
4
4

More than 1 year has passed since last update.

ansible-lint を用いて、コードの記述方法に統一感をもたせた

Last updated at Posted at 2022-12-01

はじめに

前回、ansibleでEC2 (Amazon Linux2) のport番号を変更を行いました。
そのコードに対して、ansible-lintをかけて、適切な統一感のあるコードに変更します。

現状のディレクトリ構造

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

4 directories, 4 files

現状のファイルの内容

playbook.yml
- name: Change port
  hosts: web
  become: yes
  gather_facts: false
  roles:
    - sshd
roles/sshd/handlers/main.yml
- name: Restart sshd
  service:
    name: sshd
    state: restarted
roles/sshd/tasks/main.yml
# 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.

terminalなどカラーになっていて分かりやすいです。
スクリーンショット 2022-11-27 23.46.27.png

16のfailureと2つのwarningをもらいました。
これから修正していきます。

指摘内容

  1. yaml[truthy] Truthy value should be one of [false, true]
    • true、falseにしましょう
      • 今回、Falseにしていました。
  2. yaml[new-line-at-end-of-file] No new line character at the end of file
    • ファイルの最下部に空行をいれましょう
  3. fqcn[action-core] Use FQCN for builtin module actions (lineinfile).
    • モジュール名は、FQCN(Fully Qualified Class Nameの略。完全修飾クラス名。)で表記しましょう。
      • serviceではなく、ansible.builtin.serviceと記載します。
  4. deprecated-local-action Do not use 'local_action', use 'delegate_to: localhost'.
    • local_actionではなく、delegate_to: localhostを使いましょう
  5. name[casing] All names should start with an uppercase letter.
    • namesは、最初の文字の頭文字を大文字しましょう

修正後のファイル

修正後のファイルになります。

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

roles/sshd/tasks/main.yml
# 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、もしくは、無視させたい場面がでると思います。
その方法について説明します。
スクリーンショット 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]) に対してfailtureからwarningに変更させたい場合、.config/ansible-lint.ymlを以下のように変更します。

.config/ansible-lint.yml
warn_list:
  - yaml[truthy]

failureからwarningに変わりました。
スクリーンショット 2022-11-27 23.53.37.png

無視させたい場合、以下のように記載します。

.config/ansible-lint.yml
skip_list:
  - yaml[truthy]

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

failurewarningが0になりました。

他にも特定のパス配下のみルールを適用しないexclude_pathsなどがあります。
下記を参照して下さい。

ansible-lintを使うことで、冪等性が担保されないshellを使わないように意識付けになったり、コードに統一感をもたせることができたり、よいツールだと感じました!

参考

モジュール一覧

エラー内容

ansible-lint使い方

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4