Ansible Vaultで暗号化されたインベントリやvarsみたいなAnsible本体が入力とするファイルは、Ansible実行時に(復号のパスワードが与えられていれば)自動的に元のファイルに復号されて処理される。
一方で、パラメタにファイルのパスを指定するタイプのモジュールでAnsible Vaultで暗号化されたファイルを指定した場合は、同じように自動的に復号されて処理されるのか?というのが気になったので確認してみた。
結論から言うとモジュールの実装次第の模様。
復号されるモジュール例
簡単にピックアップした中では、以下のモジュールはAnsible Vaultの復号に対応してた。
ansible.builtin.copyのsrcansible.builtin.templateのsrc
このsrcにAnsible Vaultで暗号化されたファイルを指定した場合、復号パスワードの指定なしに実行すると「A vault password or secret must be specified to decrypt ...」とエラーになるし、CLIなら--ask-vault-passでパスワードを与えれば復号されて処理される。
ちなみにあとからドキュメントをチェックした限り、以下モジュールは自動復号に対応しているっぽい。
- copy
- template
- unarchive
- script
- assemble
assembleって初めて聞いたかも。知らない。。
復号されないモジュール例
これも適当にピックアップしたが、以下は復号処理は入っておらず、暗号化された内容のファイルとして処理されるため、正しく動作しない。
community.crypto.openssl_csrのprivatekey_pathcommunity.crypto.acme_certificateのaccount_key_src
どちらもcommunity.crypto.openssl_privatekeyで作成できる秘密鍵のパスを指定するものだがこの鍵がAnsible Vaultで暗号化されていると、CSR作成の場合は「Wrong passphrase provided for private key」とパスフレーズが必要と認識され(実際はパスフレーズでガードされているわけではないが)、ACMEのアカウントキーの場合は鍵のパースエラーとなった。
もちろんAnsible Vaultで暗号化されていると認識もされないため、--ask-vault-passを指定しても動作に変化は無し。
これは想像だが、前述のドキュメントの書きっぷりからして、おそらくAnsible Vaultの復号に対応してるモジュールは基本的には無いような感じがする。
自前で作成したモジュールを使った動作確認
サンプルとして、srcとdestの二つのファイルパスをパラメタに持ち、srcからdestへ単純にファイルコピーするモジュールを用意。
呼び出し元タスクの実装としては以下の通り。
--- - name: sample module test hosts: localhost gather_facts: false tasks: - zaki_lknr.sample.copy: src: template.txt.j2 dest: /var/tmp/ansible-sample.txt
自前でファイルコピーするモジュール
モジュール本体はChatGPTに出力してもらったけど、モジュールのみで入力処理を実装(例えばPythonライブラリを使ってモジュールのPythonコード内でファイルのI/Oを完結)すると、Ansible Vaultによって暗号化されてるかどうかは関与しない動作なのを確認。
コピーそのものはshutil.copy2(src, dest)で処理している。
このモジュールを使ったタスクを実際に動作させると、srcにAnsible Vaultで暗号化されたファイルを指定した場合、暗号化された状態のままコピーする動作となる。
前述opensslの鍵ファイルの場合と同様に--ask-vault-passの有無に関係なく動作する。
Ansible Vaultの復号処理対応
これもChatGPTに出力されたコード。
srcがローカルにあるファイルということでActionプラグインで「事前処理」として復号することで、モジュールプラグインのcopyへの変更は無しに実現できる。
ポイントは下記の実装で、この内容で「ファイルをロード、Ansible Vaultで暗号化されているなら復号した上で」という処理になる。
# Resolve the real file. # # decrypt=True: # If source is an Ansible Vault encrypted file, # Ansible decrypts it on the controller. try: source = self._loader.get_real_file( source, decrypt=decrypt, )
まとめ?
まとめるには情報がそこまで出そろってない感じはするが、既存モジュールでAnsible Vaultによる暗号化ファイルをパラメタに指定したい場合は、そもそもモジュールが対応しているか確認が必要。
対応していない場合は全く違うやり方を考えるか、モジュールを改造したりラッパーコレクションを作るかするなど一工夫が必要かも。この辺は別途暇があったら試そうかな。。(試さないフラグ)
そういやAction Pluginってあまり知らないなぁ