web-dev-qa-db-ja.com

現在のAnsibleロールのファイルセクションでファイル名を検索する

私はAnsibleにかなり慣れていないので、ファイルをリモートサーバーにコピーするロールを作成しようとしています。ローカルファイルは、プレイブックを実行するたびに異なる名前を持つことができますが、次のように、リモートで同じ名前にコピーする必要があります。

- name: copy file
  copy:
    src=*.txt
    dest=/path/to/fixedname.txt

Ansibleはワイルドカードを許可しないため、メインのプレイブックのタスクを使用して簡単なプレイブックを作成すると、次のことが可能になります。

- name: find the filename
    connection: local
    Shell: "ls -1 files/*.txt"
    register: myfile

- name: copy file
  copy:
    src="files/{{ item }}"
    dest=/path/to/fixedname.txt
  with_items:
   - myfile.stdout_lines

ただし、タスクをロールに移動すると、プレイブックが「roles」ディレクトリのルートディレクトリで実行されている間、相対パスがロールに相対パスであるため、最初のアクションは機能しなくなりました。ロールのファイルディレクトリにパスを追加することもできますが、もっとエレガントな方法はありますか?

12
hepabolu

ローカルで情報を検索し、その情報をコピーモジュールへの入力として使用するタスクにアクセスする必要があるようです。

ローカル情報を取得する方法は2つあります。

  • local_action:を使用します。これは、127.0.0.1に対してタスクを実行するための省略形であり、詳細が見つかりました ここ 。 (これはあなたが使ってきたものです)

  • lookupを使用します。これは、ローカルで情報を取得するために特別に設計されたプラグインシステムです。詳細 ここ

あなたの場合、私はlookupを使用して2番目の方法を選びます。このように設定できます

vars:
  local_file_name: "{{ lookup('pipe', 'ls -1 files/*.txt') }}"

tasks:
  - name: copy file
    copy: src="{{ local_file_name }}" dest=/path/to/fixedname.txt    

または、より直接的に:

tasks:
  - name: copy file
    copy: src="{{ lookup('pipe', 'ls -1 files/*.txt') }}" dest=/path/to/fixedname.txt    

パスに関して

ルックアッププラグインは、タスクのコンテキスト(プレイブックとロール)から実行されます。これは、使用場所によって動作が異なることを意味します。

上記の設定では、タスクはプレイブックから直接実行されるため、作業ディレクトリは次のようになります。

/path/to/project-これはプレイブックがあるフォルダーです。

タスクをロールに追加する場所の場合、作業ディレクトリは次のようになります。

/path/to/project/roles/role_name/tasks

さらに、fileおよびpipeプラグインは、role/filesフォルダー(存在する場合)内から実行されます。

/path/to/project/roles/role_name/files-これはコマンドがls -1 *.txtであることを意味します

警告:

プラグインは、変数にアクセスするたびに呼び出されます。つまり、プレイブック内の変数のデバッグを信頼できず、後でロールで使用するときに変数が同じ値を持つことに依存することはできません。

プロジェクトのansibleフォルダー内にあるファイルのユースケースについては疑問に思いますが、誰の名前が事前にわかっていません。そのようなファイルはどこから来たのですか?ファイルの生成とAnsibleでの使用の間にレイヤーを追加することはできませんか...または変数として固定ローカルパスを持つことはできませんか?ちょっと興味があるんだけど ;)

13

追加の回答を入れたかっただけです...私はあなたと同じ問題を抱えています。その場でansibleバンドルを構築し、アーティファクト(rpm)をロールのファイルフォルダーにコピーし、rpmのファイル名にバージョンがあります。

Ansible playを実行するときは、ファイル名に関係なく、すべてのrpmをインストールする必要があります。

私はansibleでwith_fileglobメカニズムを使用してこれを解決しました:

- name: Copy RPMs
  copy: src="{{ item }}" dest="{{ rpm_cache }}"
  with_fileglob: "*.rpm"
  register: rpm_files

- name: Install RPMs
  yum: name={{ item }} state=present
  with_items: "{{ rpm_files.results | map(attribute='dest') | list }}"

ルックアップメカニズムよりも少しクリーンだと思います。

8
zedix