Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a multi_ansible provisioner #1579

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

wbclark
Copy link
Contributor

@wbclark wbclark commented Sep 9, 2022

A box may be configured with `multi_ansible`, which
specifies an ordered  list of ansible provisioner
names, at least one of which must be the standard
name 'ansible'.

Forklift will expect to find a key corresponding
to each provisioner name within the top level box
configuration.

Each provisioner may be configured with any of
the same options supported by the base ansible
provisioner; you may also pass `reuse_vars: true`
as a shorthand to simply copy all variables from
the base 'ansible' named provisioner. For example,

example-box:
  multi_ansible:
    - 'bootstrap'
    - 'ansible'
    - 'post'
  boostrap:
    reuse_vars: true
    config_file: ansible_bootstrap.cfg
    playbook:
      - 'playbooks/bootstrap.yml'
  ansible:
    variables:
      var1: "value1"
    playbook:
      - 'playbooks/main.yml'
  post:
    variables:
      var1: "value2"
    playbook:
      - 'user_playbooks/editor.yml'
      - 'user_playbooks/dotfiles.yml'

Forklift will run the Ansible provisioners in
stages, in the order defined by `multi_ansible`.

Files named ansible_*.cfg are added to .gitignore
so that the user may define additional ansible
config files for their custom provisioner stages.

@wbclark wbclark marked this pull request as draft September 9, 2022 14:31
A box may be configured with `multi_ansible`, which
specifies an ordered  list of ansible provisioner
names, at least one of which must be the standard
name 'ansible'.

Forklift will expect to find a key corresponding
to each provisioner name within the top level box
configuration.

Each provisioner may be configured with any of
the same options supported by the base ansible
provisioner; you may also pass `reuse_vars: true`
as a shorthand to simply copy all variables from
the base 'ansible' named provisioner. For example,

example-box:
  multi_ansible:
    - 'bootstrap'
    - 'ansible'
    - 'post'
  boostrap:
    reuse_vars: true
    config_file: ansible_bootstrap.cfg
    playbook:
      - 'playbooks/bootstrap.yml'
  ansible:
    variables:
      var1: "value1"
    playbook:
      - 'playbooks/main.yml'
  post:
    variables:
      var1: "value2"
    playbook:
      - 'user_playbooks/editor.yml'
      - 'user_playbooks/dotfiles.yml'

Forklift will run the Ansible provisioners in
stages, in the order defined by `multi_ansible`.

Files named ansible_*.cfg are added to .gitignore
so that the user may define additional ansible
config files for their custom provisioner stages.
Copy link
Member

@ekohl ekohl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than going this route, wouldn't it make sense to treat playbooks as a hash for this?

example-box:
  ansible:
    bootstrap:
      playbook: 'playbooks/bootstrap.yml'
      config_file: 'ansible_bootstrap.cfg'
      reuse_vars: true
    main:
      playbook: 'playbooks/main.yml'
      variables:
        var1: "value1"

@wbclark wbclark mentioned this pull request Sep 9, 2022
@wbclark
Copy link
Contributor Author

wbclark commented Sep 9, 2022

Rather than going this route, wouldn't it make sense to treat playbooks as a hash for this?

A primary concern was that everyone's existing boxes with a single ansible provisioner (actually, there is already a 2nd one, due to resize_disks but it isn't presented that way in the box yaml) should just continue to work.

My thinking is that organizing the data this way was the best way to achieve that. Forklift always expects to find a portion of the yaml hash called Ansible, and if the list multi_ansible is defined then it knows the names to look for similar structured hashes as well as the order to run them.

What looks to me like the hard part of your proposal is 1. cleanly distinguishing the case of the single named Ansible provisioner vs. the case where it has sub-hashes, and 2. properly inferring the execution order.

@ekohl
Copy link
Member

ekohl commented Sep 10, 2022

I imagined it'd be similar to GH actions where triggers can be an array or a hash: https://docs.github.com/en/actions/using-workflows/triggering-a-workflow#using-events-to-trigger-workflows

Normally I'm not a big fan of that style of programming, but in this case I think it provides a better user experience.

I'll admit I haven't fully thought this through. Other things that come to mind is using some sort of inventory file. Essentially the box gains state.

A whole different approach is to change things up completely and instead focus on building a base box that has all these steps set up. Then you don't need all this complex provisioning, but instead move it into the box building phase. We already do a similar thing for Katello's stable dev box using packer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants