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

Allow 'ask' to be run at "compile" time #16

Open
mpalmer opened this issue Nov 1, 2019 · 1 comment
Open

Allow 'ask' to be run at "compile" time #16

mpalmer opened this issue Nov 1, 2019 · 1 comment

Comments

@mpalmer
Copy link

mpalmer commented Nov 1, 2019

For semi-automated runbooks, it is useful to be able to collect all the necessary information that is needed by a runbook up-front, before the steps start executing. In the simple case, you can just ask all your questions in the first step, but if you're aggregating multiple sections or runbooks together into one mega runbook o' doom, and each of the components has questions of its own, you end up having to come back to the run all the time to answer more questions. If I could answer all the questions at once, and then wander off to get a cuppa while the runbook does its thing, I would be a much happier (and well-caffeinated) person.

@pblesi
Copy link
Contributor

pblesi commented Nov 1, 2019

I like this idea, but have struggled to find a good implementation. If you can think of a good way to accomplish this, I would be interested. A couple of thoughts:

  1. Typically for gathering input at compile time, I suggest relying on environment variables.
Runbook.book "Bootstrap Servers" do
  step "Setup" do
    ruby_command do
      @rails_env ||= ENV["RAILS_ENV"]
      ask "Environment?", into: :rails_env, default: "staging" unless @rails_env
    end
  end
end
$ RAILS_ENV=production bundle exec runbook exec my_runbook.rb 

Alternatively, TTY::Prompt is a dependency of Runbook, so it could be used to collect user input before the runbook is evaluated. The main concern with this is it prevents a transition to full autonomy for the runbook. If this is unlikely to be necessary for your particular use case, then this approach may be a good route to go. Another downside of this is that you will be re-prompted every time you execute the runbook, even if you encounter an error. It also will not remember previous inputs.

  1. Switching to some OOP might be useful. You could do something like the following:
# runbooks/restart_cluster.rb
require 'rotate_leader_runbook'
require 'restart_node_runbook'

Runbook.book "Restart Cluster" do
  section "setup" do
    add RotateLeaderRunbook.input_step
    add RestartLeaderRunbook.input_step
  end

  add RotateLeaderRunbook.rotate_leader_section
  add RotateLeaderRunbook.restart_node_section
end
# lib/runbook/rotate_leader_runbook.rb

module RotateLeaderRunbook
  def self.input_step
    Runbook.step do
      ask "Server?", into: server
      ask "Timeout?", into: timeout
    end
  end

  def self.rotate_leader_section
    Runbook.section "Rotate Leader" do
      # ...
    end
  end
end

This way, you could coalesce inputs to all execute at the beginning of the runbook.

I'm also going to mention that I am planning to include this feature in the next version of Runbook: https://github.com/braintree/runbook/blob/master/TODO.md#always-executed-setup-section. This may not directly address your issue, but may be useful for your mega runbook o' doom.

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

No branches or pull requests

2 participants