ansibleに存在しないディレクトリを自動作成する簡単な方法は何ですか


117

私のAnsibleプレイブックでは何度もそこにファイルを作成する必要があります

 - name: Copy file
   template:
     src: code.conf.j2
     dest: "{{project_root}}/conf/code.conf"

今度confはdirがそこにありません。次に、そのディレクトリを最初に作成するためのタスクをさらに作成する必要があります。

オプションが存在しない場合にディレクトリを自動作成する簡単な方法はありますか



これはまだansible 2.9の問題であるとは信じられません。これらのモジュールで、デフォルトでオフになっているdir切り替えを作成するのはどれほど難しいでしょうか。以下の答えのような事前テストに対処しなければならないため、プレイブックのざらつきを大幅に節約できます
クラート

回答:


139

今、これが唯一の方法です

- name: Ensures {{project_root}}/conf dir exists
  file: path={{project_root}}/conf state=directory
- name: Copy file
  template:
    src: code.conf.j2
    dest: "{{project_root}}/conf/code.conf"

2
ここで正しいことを確認してください。確信:「疑いを払拭するために誰かに積極的に何かを伝えてください」、確実にしてください:「(何か)が起こるか、またはそうであることを確認してください」。
Daniel Compton 2016年

これは、ディレクトリが存在するかどうかを確認するようですが、作成するようには見えません。
マット

8
型の動作を取得するrecurse=yesためにfile呼び出しに追加する必要がある場合があることに注意してくださいmkdir -p
ミッチ

1
役立つもう1つのパズルは、ファイルを含むディレクトリを取得するansible固有のdirnameフィルターです。
Caspar

1
@radtekファイルモジュールは、state = directoryですでにそれを行っています。提案されたファイルパスがディレクトリを指していることを確認できない場合、失敗します。
アレクサンダージャーディム

21

フルパスでの成功を保証するには、recurse = yesを使用します

- name: ensure custom facts directory exists
    file: >
      path=/etc/ansible/facts.d
      recurse=yes
      state=directory

2
ドキュメント(および私のテスト)によると、サブディレクトリは常に作成され、recurse=yesアクセス許可は再帰的にのみ適用されます。ただし、ドキュメントでは、これはv1.7以降自動的にrecurse行われるため、廃止されている可能性があります。
To마SE、2016

16

Ansible> = 2.0を実行している場合は、パスのディレクトリ部分を抽出するために使用できるdirnameフィルターもあります。このようにして、1つの変数を使用してパス全体を保持し、両方のタスクが同期しないようにすることができます。

たとえば、次のdest_pathような変数で定義されたプレイブックがある場合、同じ変数を再利用できます。

- name: My playbook
  vars:
    dest_path: /home/ubuntu/some_dir/some_file.txt
  tasks:

    - name: Make sure destination dir exists
      file:
        path: "{{ dest_path | dirname }}"
        state: directory
        recurse: yes

    # now this task is always save to run no matter how dest_path get's changed arround
    - name: Add file or template to remote instance
      template: 
        src: foo.txt.j2
        dest: "{{ dest_path }}"

1
この解決策はまだ冗長ですが、筆者の意図に最も近いと思います。私は考え愛する塩のような単純な「makedirs」パラメータがあった場合にそれをしていますdocs.saltstack.com/en/latest/ref/states/all/...
LSH

7

AFAIK、これを行うことができる唯一の方法は、state=directoryオプションを使用することです。一方でtemplate、ほとんどのモジュールがサポートするcopyターンサポートにほとんどのオプション、fileオプションは、あなたがのようなものを使用することはできませんstate=directoryそれとを。さらに、それは非常に混乱します(それ{{project_root}}/conf/code.confがディレクトリであるという意味ですか?それとも{{project_root}}/conf/最初に作成する必要があるという意味ですか?)

そのため、前のfileタスクを追加しない限り、これは現在可能ではないと思います。

- file: 
    path: "{{project_root}}/conf"
    state: directory
    recurse: yes

7

最新のドキュメントによると、状態がディレクトリに設定されている場合、親ディレクトリを作成するためにパラメータ再帰を使用する必要はありません。ファイルモジュールがそれを処理します。

- name: create directory with parent directories
  file:
    path: /data/test/foo
    state: directory

これは、親ディレクトリの作成するための運賃は十分であるデータテストをしてFOO

パラメータの説明を参照してください-「状態http://docs.ansible.com/ansible/latest/modules/file_module.html


将来壊れる可能性のあるリンクの代わりに、ソリューションをここに追加してください。
Ignacio Ara

@IgnacioAra貴重なコメントをありがとう、私は解決策を追加しました。
アルビー


1

存在しない場合は、copyモジュールがディレクトリを作成します。この場合、それはresolved.conf.dディレクトリを作成しました

- name: put fallback_dns.conf in place                                                                 
  copy:                                                                                                
    src: fallback_dns.conf                                                                             
    dest: /etc/systemd/resolved.conf.d/                                                                
    mode: '0644'                                                                                       
    owner: root                                                                                        
    group: root                                                                                        
  become: true                                                                                         
  tags: testing
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.