How to have Ansible move a microservice?
I have created a demo with a role that can install many springboot microservices on a fleet of VMs where you name a subset of the VMs where you want to place each service. The playbook can then run on all hosts, compute whether each service should be on each host, and will either run the install.yaml or uninstall.yml tasks. 

To install two of the same microservices with different runtime args you play something like:


roles:
    - {
      role: "ansible-role-springboot",
      sb_app_name: "microservices-registration",
      sb_app_group_id: "org.springframework.samples.service.service",
      sb_app_artifact_id: "microservices-demo",
      sb_app_version: "2.0.0.RELEASE",
      sb_app_run_args: '"registration 8082"',
      sb_app_healthcheck_urls: [
        "http://localhost:8082/actuator/health"
      ],
      sb_hosts: [
        "my-test-vm"
      ]
    }
    - {
      role: "ansible-role-springboot",
      sb_app_name: "microservices-web",
      sb_app_group_id: "org.springframework.samples.service.service",
      sb_app_artifact_id: "microservices-demo",
      sb_app_version: "2.0.1.RELEASE",
      sb_app_run_args: '"web 8083"',
      sb_app_healthcheck_urls: [
        "http://localhost:8083/actuator/health"
      ],
      sb_hosts: [
        "my-test-vm"
      ]
    }


The role is based upon orachide/ansible-role-springboot which seems very comprehensive. The new bit is in bold which is simply a list of host that should run the microservice. 

Normally we would expect to use different artefact ids and versions each time we apply the role. In the example above, it is running an official springboot microservices mega jar that takes different RUN_AS args to run as different services. That seems a bit odd and not something I would recommend yet the role is agnostic to such details. 

What thing that the original role requires is that you use an executable jar file: 

        &lt;plugin&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
            &lt;configuration&gt;
                &lt;executable&gt;true&lt;/executable&gt;
            &lt;/configuration&gt;
        &lt;/plugin&gt;


It role will create a symlink to that executable and create an environment files to run it and all that good stuff. 

The modifications that I made were quite simple as the original role has logic to install or uninstall based on sb_app_state:

- import_tasks: install.yml
  when: &gt;
        sb_app_state == 'present'

- import_tasks: uninstall.yml
  when: &gt;
        sb_app_state == 'absent'


So it was simply a matter of adding some logic to check whether the current hostname is in the sb_hosts list then update the value of sb_app_state as appropriate. That is done with a single line change. 

The demo codebase uses test kitchen ansible with testinfra to unit test that the playbook works. Getting that working was well worth the effort to do automated acceptance tests of the playbook logic.