Ansibleは認証ファイルのリストを取得し、有効期限を確認します。

Ansibleは認証ファイルのリストを取得し、有効期限を確認します。

私は私たちのWebサーバーの1つからファイルのリストを取得し、これらの認証ファイルの有効期限を確認する方法を見つけようとしています.crt(実際、この証明書が特定の期間内に有効であることを確認しています)。これまで私が持っているのは次の.ymlプレイブックコードです。

#
# simple playbook to check certificates expiration date

- name: find cerfication files & expiration dates
  hosts: 10.0.1.120
  gather_facts: false

  tasks:
    - name: Find cert files under /etc/pki/tls/certs
      find:
        paths: /etc/pki/tls/certs
        file_type: file
        patterns: "*.crt"
        recurse: yes
        excludes: "localhost.crt"
      register: find_result

    - name: check validity
      openssl_certificate_info:
        path: "{{ item.path }}"
        valid_at:
          point_1: "+1w"
          point_2: "+10w"
      register: result
      loop: "{{ find_result.files|flatten(levels=1) }}"

    #- name: validate
      #assert:
        #that:
          #- result.valid_at.point_1
          #- result.valid_at.point_2

    - debug: msg= "{{ result }}"

上記の結果はdebug msg次のとおりです。

TASK [debug] ****************************************************************************
ok: [10.0.1.120] => {
    "msg": ""
}

モジュールを使用して得られた他の出力をassert確認し、各結果(point_1とpoint_2)のパススルー/失敗メッセージを取得できるように、モジュールに説明を残しました。ハードコーディングされたパスをassert提供し.crtてループを提供しないと、必要なテストが得られますが、loopコマンドを使用しようとするとモジュールがassert期待どおりに実行されず、dict object次のエラーが発生します。

fatal: [10.0.1.120]: FAILED! => {"msg": "The conditional check 'result.valid_at.point_1' failed. The error was: error while evaluating conditional (result.valid_at.point_1): 'dict object' has no attribute 'valid_at'"}

私のAnsibleホスティングサーバーに関する追加情報:

  • サーバー展開:CentOS-7
  • アンサーブルバージョン:2.8.1

それでは、あなたのパス(localhost.crtを除く).crtで見つけることができるすべてのファイル/etc/pki/tls/certsに対して私が望む合格/失敗メッセージを得るためにこのループを正しく実行する方法についての提案はありますか?

答え1

うーん...デバッグ結果が私のテストと一致しない理由を見つけるのに時間がかかりました。そこにエラーがあります:

- debug: msg= "{{ result }}"

(消える空間に注目)

- debug: msg="{{ result }}"

またはより良い方法(将来のデバッグ地獄のための完全なyaml構文を採用)

- debug:
    msg: "{{ result }}"

これで問題が解決されたので、問題がresult.someWhateverCertValue存在しないことが明らかにわかります。証明書情報操作でループを使用したため、個々のモジュールの実行がリストに報告されます。result.results[]

それでも使用するには、assert各結果に対してもう一度繰り返す必要があります。

- name: validate
  assert:
    that:
      - item.valid_at.point_1 | bool
      - item.valid_at.point_2 | bool
  loop: "{{ result.results }}"

上記のコードは操作を実行する必要があります。アサーションは各証明書情報の結果に対して実行され、チェックのいずれかが要件を満たさない場合、プレイブックは失敗して終了します。

しかし、結果を読むのは少し難しいかもしれません。より良い結果を得るには、少し異なる方法で行います。

- name: find cerfication files & expiration dates
  hosts: my_host
  gather_facts: false

  tasks:
    - name: Find cert files under /etc/pki/tls/certs
      find:
        paths: /etc/pki/tls/certs
        file_type: file
        patterns: "*.crt"
        recurse: yes
        excludes: "localhost.crt"
      register: find_result

    - name: Check validity
      openssl_certificate_info:
        path: "{{ item.path }}"
        valid_at:
          point_1: "+1w"
          point_2: "+10w"
      register: cert_info
      loop: "{{ find_result.files }}"

    - name: Filter out valid certs
      set_fact:
        outdated_certs: "{{ cert_info | json_query('results[? !(valid_at.point_1) || !(valid_at.point_2)]') }}"

    - block:
        - name: Check that all certificates are valid
          assert:
            that:
              - outdated_certs | count == 0
      
      rescue:
        - name: Show info about outdated certs
          debug:
            msg: >-
              {{ { "Outdated Certs": outdated_certs | json_query("[].item.path") } }}
        
        - fail:
            msg: "Outdated certs found. See list above"

最後の注意:なぜ日付チェックが2回必要なのかわかりません。日付エラーが原因で証明書が無効になると仮定するため、最も遠い証明書を確認するだけで十分です。例ではすべてのテストをアーカイブしているので、何かを見逃した場合は修正する方法がわかります。

関連情報