2

I'm migrating a group of websites from one infrastructure to another, including a fairly slow rsync operation. The migration process includes changes to both the source and target systems.

Due to a fairly slow rsync operation that is part of the process, I am looping through a var file which contains the details for each website and then run through the tasks required to move one website at a time.

I cannot find a way to target some tasks at the source system and some at the target system. I have tried doing this by adding hosts: to each task: (all tasks are in a single role)

My playbook:

---
- hosts:
    - tag_aws_autoscaling_groupName_thename
    - tag_Name_server_name
  vars_files:
    - group_vars/all

  roles:
   - unmigratesite

unmigratesite role:

---

- include_tasks: "unmigrateonesite.yml"
  loop: "{{ wordpress_websites }}"

unmigrateonesite.yml:

- name: rsync site
  hosts: tag_aws_autoscaling_groupName_thename
  shell: rsync -avz /efs/www/{{new_folder}}/htdocs/ 172.31.18.217:/www/{{item.folder}}
  run_once: true
  register: rsync_out

- name: setup proxy host file
  template: src=proxy-host.j2 dest=/efs/nginx/sites-available/{{item.name}} owner=root group=root mode=0644
  hosts: tag_aws_autoscaling_groupName_thename
  notify:
    - restart nginx
  tags:
    - site
    - nginx-host-conf
    - nginx-temp-proxy

- name: setup wp-config.php WP_CONTENT_DIR on old server
  lineinfile: name=/www/{{ folder }}/{{ configuration_file }} regexp=WP_CONTENT_DIR line="define('WP_CONTENT_DIR', '/www/{{folder}}/app');"
  hosts: tag_Name_server_name
  ignore_errors: yes
  tags:
    - wp-config.php
    - wordpress
    - site
    - WP_CONTENT_DIR

However I'm getting an error:

    fatal: [54.219.216.237]: FAILED! => {"reason": "conflicting action statements: shell, hosts\n\nThe error appears to be in '/Users/jd/projects/bizinconline/ansible/roles/unmigratesite/tasks/unmigrateonesite.yml': line 22, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: rsync site\n  ^ here\n"}
    fatal: [54.193.100.223]: FAILED! => {"reason": "conflicting action statements: shell, hosts\n\nThe error appears to be in '/Users/jd/projects/bizinconline/ansible/roles/unmigratesite/tasks/unmigrateonesite.yml': line 22, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: rsync site\n  ^ here\n"}
    fatal: [13.57.52.221]: FAILED! => {"reason": "conflicting action statements: shell, hosts\n\nThe error appears to be in '/Users/jd/projects/bizinconline/ansible/roles/unmigratesite/tasks/unmigrateonesite.yml': line 22, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: rsync site\n  ^ here\n"}

Exactly 3 times - as many times as there are hosts.

How can I run some tasks against one group and some against another group of servers?

jdog
  • 121
  • 7
  • 29

2 Answers2

3

I cannot find a way to target some tasks at the source system and some at the target system. I have tried doing this by adding hosts: to each task: (all tasks are in a single role)

My first idea reading this is to replace your hosts: by when: "'old_server' in group_names" or when: "'new_server' in group_names"

If that doesn't work, I'ld give a shot at delegate_to, here's the delegation documentation

one website at a time

If you want to be really slow, consider using serial: 1. Or even --step in the cli.

Rémy
  • 286
  • 1
  • 2
  • 8
  • Right, and it might be a good idea to structure the inventory too as I described in [Can I run on specific host or group of hosts?](https://stackoverflow.com/a/67831452/6771046). – U880D Jun 04 '21 at 04:36
1

You run tasks on different hosts by grouping the tasks into plays, each of which can define the set of hosts its tasks runs on. It's not really valid to set hosts for an individual task, which is the immediate cause of the error message.

Here is an example, with two plays, each defining a different set of hosts. Each play defines the hosts on which its tasks will run.

 - name: configure new hosts
   hosts: tag_aws_autoscaling_groupName_thename
   strategy: free
   tasks:
    - name: rsync site
      shell: rsync -avz /efs/www/{{new_folder}}/htdocs/ 172.31.18.217:/www/{{item.folder}}
      run_once: true
      register: rsync_out
    
    - name: setup proxy host file
      template: src=proxy-host.j2 dest=/efs/nginx/sites-available/{{item.name}} owner=root group=root mode=0644
      notify:
        - restart nginx
      tags:
        - site
        - nginx-host-conf
        - nginx-temp-proxy

Above is one play containing two tasks. Below is one play containing one task.

 - name: configure old hosts
   hosts: tag_Name_server_name
   strategy: free
   tasks:
    - name: setup wp-config.php WP_CONTENT_DIR on old server
      lineinfile: name=/www/{{ folder }}/{{ configuration_file }} regexp=WP_CONTENT_DIR line="define('WP_CONTENT_DIR', '/www/{{folder}}/app');"
      ignore_errors: yes
      tags:
        - wp-config.php
        - wordpress
        - site
        - WP_CONTENT_DIR
Michael Hampton
  • 244,070
  • 43
  • 506
  • 972
  • Ok, what I am looking for is looping through a list of items, then execute one play, then the second for each item. The tasks I have listed are currently running in a loop, how do I achieve this? – jdog Jan 11 '21 at 02:45
  • @jdog I don't see any loop? Please edit your question. – Michael Hampton Jan 11 '21 at 03:10
  • Thanks @michael hampton have updated – jdog Jan 11 '21 at 04:40
  • @jdog You should `import_playbook` instead, and that loop doesn't really make sense here. Did you leave out something relevant? – Michael Hampton Jan 11 '21 at 07:04
  • I want to loop through each site one by one to ensure minimal time difference between rsync and the file changes. Nothing relevant is left out – jdog Jan 11 '21 at 17:20
  • I have expanded the explanation of what I want to achieve a bit more. I cannot see how I can include a play multiple times in a loop, which is what I would need. – jdog Jan 11 '21 at 20:38
  • I suppose an unsophisticated way to do this would be to place a "marker" file onto the target server and include a when: statement for every task depending if it should run on the target system? – jdog Jan 11 '21 at 20:40
  • @jdog I think at this point I would use a network file system, rather than a whole lot of rsync to many servers. – Michael Hampton Jan 11 '21 at 20:47
  • I'm reverting back from a network file system, the purpose of my ansible use is exactly as described – jdog Jan 11 '21 at 22:25