0

Is there any way to have Ansible run a build script locally on the control node, and then deploy the resulting artifact to various managed nodes?

Please let me know if there's something I've missed, but I looked at the docs for the shell, command and script modules, and they each only seem to allow execution on the managed node. I'm really surprised I can't find a way to run a command on the control node.

Maybe this isn't in Ansible's wheelhouse? Is the idea that you're supposed to use some other tool like Make to do the build, and then Ansible only handles copying it to servers?

bjmc
  • 147
  • 3

2 Answers2

2

You can create a simple task to invoke a make command in the localhost like this:

    - name: make an executable
      command: make
      tags: compile
      delegate_to: localhost
      connection: local
      run_once: True
      become: no

This will run the make command and execute whatever your Makefile has. Then in the next task you can create a copy task to copy the result to the managed nodes.

João Alves
  • 606
  • 3
  • 6
  • 1
    The important bit is [`delegate_to: localhost`](https://docs.ansible.com/ansible/latest/user_guide/playbooks_delegation.html). – Michael Hampton Feb 28 '21 at 22:54
  • Thank you! It seems like `delegate_to` was the piece I was missing! – bjmc Feb 28 '21 at 23:00
  • 2
    I don't like this style, I find starting a new play more clear. delegate_to and run_once are both needed because there may be multiple hosts in the play and you only want to run on one, and force it to localhost. connection really only needs to be set in inventory. – John Mahowald Feb 28 '21 at 23:07
2

For Ansible, to run a thing on a different set of hosts, try starting a new play.

- name: Build thing
  # localhost is the node running Ansible
  # By default, this already is connection local
  #   exec instead of ssh
  hosts: localhost
  
  tasks:
  # Assuming make based build scripts
  # make module reports not changed if nothing to do
  - make: 
      chdir: /home/builduser/source/thing/
    
    
- name: Install thing
  hosts: various
  
  tasks:
  - copy:
      # copy is an action plugin that handles the copy from localhost to remote for yoy
      src: /home/builduser/source/thing/output/thing.rpm
      dest: /tmp/thing.rpm

  # TODO Use custom repo for content management rather than copying one-off packages

  - package:
      name: /tmp/thing.rpm

Although you can run Ansible in CI/CD pipelines or whatever, and it can run whatever you like, Ansible is not amazing at being a build system. It is not artifact oriented.

John Mahowald
  • 32,050
  • 2
  • 19
  • 34