Skip to content
This repository has been archived by the owner on Oct 17, 2024. It is now read-only.

Latest commit

 

History

History
191 lines (135 loc) · 6.28 KB

iteration-conditionals.md

File metadata and controls

191 lines (135 loc) · 6.28 KB

Iteration and Conditionals

Iteration and Conditionals

$ cd $INTRO_ANSIBLE_DIR/working-with-playbooks
.
├── ansible.cfg
├── hosts
├── playbook-dict.yml
├── playbook-lists.yml

Iterating through lists

Iterating with_items

  • Step through an array
  • Each element in iteration is assigned to item variable

 vars:
  list_of_files: 
    - file1.txt
    - file2.txt
       .
       .
  tasks:
   - name: Process a list of items        
     copy:                               
       src: "/path/to/local/{{ item }}"   
       dest: "/path/to/remote/{{ item }}" 
     with_items: "{{ list_of_files }}"    

Configuring our fake application myapp

  • Have a look at playbook-lists.yml
  • Run the playbook and then have a look in /etc/myapp/config
  • Playbook adds lines to a configuration file for a fake app
  • There are a number of things we can optimise
Exercise: Remove repetitive allowed_host tasks from playbook
  • Use with_items to refactor tasks
  • Replace all allowed host tasks with
    
          - name: Add allowed_hosts entries
            lineinfile:
              path: /etc/myapp/config
              line: "allow_from: {{ item }}"
              insertafter: EOF
            with_items:
              - "{{ allowed_host1 }}"
              - "{{ allowed_host2 }}"
              - "{{ allowed_host3 }}"
    
    
Exercise: Remove repetitive listen tasks from playbook
  • Use with_items to simply listen tasks
  • Replace all the listen tasks with:
    
      - name: Add listen port entries
        lineinfile:
          path: /etc/myapp/config
          line: "listen: {{ item }}"
          insertafter: EOF
        with_items: "{{ listen_ports }}"
      

Nesting Loops with_nested

  • It is possible to loop over two lists at once
    - name: Add allowed ports for each host
      lineinfile:
        path: /etc/myapp/config
        line: "host: {{ item[0] }}:{{ item[1] }}"
        insertafter: EOF
      with_nested:
        - [ "{{ allowed_host1 }}", "{{ allowed_host2 }}", "{{ allowed_host3 }}"]
        - "{{ listen_ports }}"
    
    

Iterating through dictionaries with_dict

  • Takes a dictionary argument
  • Each item has
    • Key
    • Value

- name: Task that iterates over a dictionary
  somemodule:
    arg: "{{ item.key }}"
    arg2: "{{ item.value }}"
  with_dict: "{{ dictionary }}"

More configuration for myapp

  • `playbook-dict.yml` sets up database config for our fake application
  • Adds each element of database variable to config
  • Run the playbook and have a look at /etc/myapp/app_config
    ansible-playbook playbook-dict.yml
    
Exercise: Remove repetition from playbook-dict.yml
  • Refactor the playbook using with_dict to remove repetitive tasks

 - name: Add database config to /etc/myapp/config
   lineinfile:
     path: /etc/myapp/app_config
     line: "database_{{ item.key }}={{ item.value }}"
     regexp: '^database_{{ item.key}}.*'
   with_dict: "{{ database[env_name] }}"

Conditionals

The when clause

  • The main way to conditionally do something in Ansible is by using the when clause
  • `when` has identical semantics to a Python _if_ block
    • `when: some_variable is defined`
    • `when: env_name == 'staging'`

- name: Some task
  command: do something
  when: <condition is true>
Exercise: Make our tasks conditional
  • Tasks in playbook-dict.yml assume a staging environment

  vars:
    .
    env_name: staging
  • Add a conditional to the lineinfile tasks
    • Only execute if env_name is production
  • Re-run the playbook

  - name: Add database config to /etc/myapp/config
    lineinfile:
    .
    .
    when: env_name == 'production'
Exercise: Override default env_name to run tasks
  • env_name is set to staging by default
  • Override this to be production and re-run playbook
  • Hint: What type of variable has precedence in this situation?

ansible-playbook playbook-dict.yml -e env_name=production