ansible-navigator を使った場合の情報の受け渡し

Red Hat で Ansible のソリューションアーキテクトをしている中島でございます。

本エントリーは Ansible Advent Calendar 2024 の6日目の記事となります。 Ansible Advent Calendar 2024 にはAnsible 関する様々なTIPSやナレッジが投稿されておりますの、Ansible を触っている方はご一読いただくと、自動化のステップアップのきっかけを得られるかもしれません。

さて、現在の Red Hat Ansible Automation Platform(以下AAP) は Playbook を実行するためにコンテナ環境(Execution Environment: 以下EE)を使っています。EEを使うことで複雑化したモジュールの依存関係をOS本体とは切り離し、「開発環境では動いたのに!」という状況を極力抑えることができます。そして、EEを使ったPlaybook開発のための仕組みとして、ansible-navigator コマンドがあります。

ansible-navigator は ansible-playbook コマンドと表面上は概ね同じですが、大きく違うのがPlaybookを実行するためにEEを利用します。開発では ansible-navigatorを使い、本番ではAAPを利用する。そしてそのどちらにも同じEEを使用することで、開発と本番の差異をなくし、Playbookの実行環境に起因するトラブルを削減することができます。ansible-navigator を使う場合、Playbook の実行はEEという「コンテナの中」で実行され、自分が操作している開発環境のOS上の設定とは独立して動きます。これは環境の独立性を担保する意味では便利な半面、別の部分では不便な部分も出てきます。それが情報(変数)の受け渡しです。

今回は、ansible-navigator を使って情報を受け渡し、Playbook開発の効率を高める方法について紹介します(AAP上では簡単に設定して利用できる各種変数などを、ansible-navigator を使った時にどうするか、という話だと思ってください)。

ここからが本題です。今回は AWS を例にサンプルを見ながら紹介します。

以下のようなPlaybookを準備します。これはAWS EC2上のインスタンス情報を取得するPlaybookです。

---
- hosts: all
  gather_facts: false
  tasks:
    - name: Gather information about all instances
      amazon.aws.ec2_instance_info:
      register: ret

    - debug: var=ret

これをAAPで使う場合は、「AWS用の暗号化された認証オブジェクト」を作成してジョブにアタッチするだけで安全に利用できますが・・・、コマンドラインで使う場合には以下のようにします。

このAWSモジュール用に必要な環境変数をセットしておきます。

export AWS_ACCESS_KEY=xxx
export AWS_SECRET_KEY=yyy
export AWS_REGION=ap-northeast-1

ではまず、ansible-playbook コマンドで実行してみます。インベントリーファイルを準備していないので、-i localhost, -c local オプションでコマンドラインの中で接続先と接続方法を指定しています。

$ ansible-playbook -i localhost, -c local playbook.yaml

PLAY [all] ********************************************************************

TASK [Gather information about all instances] *********************************
ok: [localhost]

TASK [debug] ******************************************************************
ok: [localhost] => {
    "ret": {
        "changed": false,
        "failed": false,
        "instances": [
(省略)
    }
}

PLAY RECAP ********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

問題なく実行できています。では、同じ条件で ansible-navigator を使ってみます。

$ ansible-navigator run playbook.yaml -i localhost, -c local -m stdout -e 'ansible_python_interpreter=/usr/bin/python'

PLAY [all] *********************************************************************

TASK [Gather information about all instances] **********************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "The amazon.aws.ec2_instance_info module requires a region and none was found in configuration, environment variables or module parameters"}

PLAY RECAP *********************************************************************
localhost                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0
Please review the log for errors.
  • Note: 今回の利用しているEEのイメージ registry.redhat.io/ansible-automation-platform-25/ee-supported-rhel8 は -c local で接続すると、OS管理用の /usr/libexec/platform-python が使用されてしまうため、明示的に/usr/bin/python を使うように指定しています。

認証情報が参照できないため接続エラーがおきているのがわかります。

では、ansible-navigator に認証情報を渡してみます。一番簡単なのは--senv オプションで環境変数として渡す方法です。

$ ansible-navigator run playbook.yaml -i localhost, -c local -m stdout -e 'ansible_python_interpreter=/usr/bin/python' --senv 'AWS_ACCESS_KEY=xxx' --senv 'AWS_SECRET_KEY=yyy' --senv 'AWS_REGION=ap-northeast-1'

(省略)
PLAY RECAP ********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

うまく動きました。別の方法として、現行シェルの変数を渡す --penv というオプションもあります。

$ ansible-navigator run playbook.yaml -i localhost, -c local -m stdout -e 'ansible_python_interpreter=/usr/bin/python' --penv AWS_ACCESS_KEY --penv AWS_SECRET_KEY --penv AWS_REGION

(省略)
PLAY RECAP ********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

こちらもうまく動いています。

-e は extra_vars として ansible の変数として渡され、--penv --senv は環境変数として渡されます。似て非なるものなので、どちらで渡したいのかをモジュールの仕様を確認し、違いを意識して利用できるとトラブルを減らすことができます。

ansible-playbook から ansible-navigator に移行すると、環境のベースがコンテナに移ることで、Ansible での接続や認証等の基本的な部分で引っかかることがよくあります。特に認証周りは最初のつまづきポイントです。もし、ansible-navigator での開発で、認証周りでうまくいかないことがあれば、今回紹介したコマンドからEEへの情報の受け渡しについて確認してみてください。

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。