web-dev-qa-db-fra.com

ansible: lineinfile pour plusieurs lignes?

De la même manière, il existe un module lineinfile pour ajouter une ligne dans un fichier, existe-t-il un moyen d'ajouter plusieurs lignes?

Je ne veux pas utiliser de modèle car vous devez fournir le fichier entier. Je veux juste ajouter quelque chose à un fichier existant sans nécessairement savoir ce que le fichier contient déjà, donc un modèle n'est pas une option.

144
Michael

Vous pouvez utiliser un boucle pour le faire. Voici un exemple utilisant une boucle with_items:

- name: Set some kernel parameters
  lineinfile:
    dest: /etc/sysctl.conf
    regexp: "{{ item.regexp }}"
    line: "{{ item.line }}"
  with_items:
    - { regexp: '^kernel.shmall', line: 'kernel.shmall = 2097152' }
    - { regexp: '^kernel.shmmax', line: 'kernel.shmmax = 134217728' }
    - { regexp: '^fs.file-max', line: 'fs.file-max = 65536' }
198
Ben Whaley

Vous pouvez essayer d'utiliser blockinfile .

Vous pouvez faire quelque chose comme

- blockinfile: |
    dest=/etc/network/interfaces backup=yes
    content="iface eth0 inet static
        address 192.168.0.1
        netmask 255.255.255.0"
160
Soichi Hayashi

Si vous devez configurer un ensemble de lignes uniques propriété = valeur, je recommande une boucle plus concise. Par exemple:

- name: Configure kernel parameters
  lineinfile:
    dest: /etc/sysctl.conf
    regexp: "^{{ item.property | regex_escape() }}="
    line: "{{ item.property }}={{ item.value }}"
  with_items:
    - { property: 'kernel.shmall', value: '2097152' }
    - { property: 'kernel.shmmax', value: '134217728' }
    - { property: 'fs.file-max', value: '65536' }

En utilisant un dict comme suggéré par Alix Axel et en ajoutant la suppression automatique des entrées mises en commentaire correspondantes,

- name: Configure IPV4 Forwarding
  lineinfile:
    path: /etc/sysctl.conf
    regexp: "^#? *{{ item.key | regex_escape() }}="
    line: "{{ item.key }}={{ item.value }}"
  with_dict:
    'net.ipv4.ip_forward': 1
15
Nicholas Sushkin

Voici une version sans bruit de la solution qui consiste à utiliser with_items:

- name: add lines
  lineinfile: 
    dest: fruits.txt
    line: '{{ item }}'
  with_items:
    - 'Orange'
    - 'Apple'
    - 'Banana' 

Pour chaque élément, s'il existe dans fruits.txt, aucune action n'est entreprise.

Si l'élément n'existe pas, il sera ajouté à la fin du fichier.

Peasy facile.

14
Rick O'Shea

J'ai pu le faire en utilisant \n dans le paramètre line.

Cela est particulièrement utile si le fichier peut être validé et que l'ajout d'une seule ligne génère un fichier non valide.

Dans mon cas, j'ajoutais AuthorizedKeysCommand et AuthorizedKeysCommandUser à sshd_config, à l'aide de la commande suivante:

- lineinfile: dest=/etc/ssh/sshd_config line='AuthorizedKeysCommand /etc/ssh/ldap-keys\nAuthorizedKeysCommandUser nobody' validate='/usr/sbin/sshd -T -f %s'

L'ajout d'une seule des options génère un fichier dont la validation échoue.

4
Penz

Ce n'est pas idéal, mais vous avez le droit de faire plusieurs appels à lineinfile. En utilisant cela avec insert_after, vous pouvez obtenir le résultat souhaité:

- name: Set first line at EOF (1/3)
  lineinfile: dest=/path/to/file regexp="^string 1" line="string 1"
- name: Set second line after first (2/3)
  lineinfile: dest=/path/to/file regexp="^string 2" line="string 2" insertafter="^string 1"
- name: Set third line after second (3/3)
  lineinfile: dest=/path/to/file regexp="^string 3" line="string 3" insertafter="^string 2"
4
Ramon de la Fuente