acquia/moonshot

View on GitHub
docs/1.x-upgrade.md

Summary

Maintainability
Test Coverage
# Moonshot 0.7.x to 1.x upgrade guide #

There have been a lot of changes in the 1.x release that we're very
excited about. However, we've taken this opportunity to make some
serious changes that are not backwards compatible, hence the major
version release.

This guide serves as a listing of the major changes.

## Moonfile, and the removal of Moonshot::CLI ##

Thor was proving to be quite difficult to work with in the architecture
we were trying to build. We've swapped it out for OptionParser. In
addition, we no longer have a superclass that must be subclassed in
your own file. Instead, we now ship a `moonshot` commandline tool with
the Gem. This tool searches the directory hierachy for a `Moonfile.rb`
file with the configuration for `Moonshot::Controller`, similar to the
behavior of Bundler.

An example of what this means:

### Before: bin/environment derived from Moonshot::CLI ##
```ruby
class MyProject < Moonshot::CLI
  self.application_name     = 'my-project'
  self.artifact_repository  = S3Bucket.new('my-project-builds')
  self.deployment_mechanism = CodeDeploy.new(asg: 'MyProjectASG')
  self.build_mechanism      = Script.new('scripts/build.sh')
end
```

### After: Moonfile.rb in project root ###
```ruby
Moonshot.config do |c|
  c.app_name             = 'my-project'
  c.artifact_repository  = S3Bucket.new('my-project-builds')
  c.deployment_mechanism = CodeDeploy.new(asg: 'MyProjectASG')
  c.build_mechanism      = Script.new('scripts/build.sh')
end
```

## Plugin and CLI Extension auto-loading ##

With the addition of Moonfile.rb, we've changed how plugin source and
custom commands should be loaded.

### Plugin Source auto-loading ###

Any files located in `moonshot/plugins` ending in `.rb` will be loaded
after the invocation of the `moonshot` CLI tool. These files can
contain class defitions added as a plugin.

For example:
```ruby
# moonshot/plugins/my_plugin.rb
class MyPlugin
  def pre_create
    # ..
  end
end

# Moonfile.rb
Moonshot.config do |c|
  # ...
  c.plugins << MyPlugin.new
end
```

We're hoping this layout allows better organization of Moonshot
customizations within you project.

### CLI Extensions and Moonshot::Command ###

All built-in commands are defined as subclasses of `Moonshot::Command`
in the `Moonshot::Commands` module. Any additional classes that
subclass this base class will be added as commands. An OptionParser is
built by calling `#parser` on the subclass, allowing additional
options for you command. The command name is automatically derived
from the class name.

For example:
```ruby
# moonshot/cli_extensions/my_commands.rb
class MyCoolCommands < Moonshot::Command
  self.usage = "my-cool-command MODE"
  self.description = "Do a really cool thing!"

  def execute(arg)
    puts "The mode is #{arg}!"
  end
end
```

The Commands have full access to a configured `Moonshot::Controller`,
via the `#controller` method, just as they did in the previous
`Moonshot::CLI` subclasses.

## Parameters files removed ##

When Moonshot was first conceived, UsePreviousValue was not a
supported feature of the UpdateStack API. This meant that if you used
NoEcho to secure sensitive parameters, there was no way to update a
stack without having all of the original parameters. This is what lead
to the decision to support files in the `cloud_formation/parameters`
directory for each stack. Since then, CloudFormation's APIs have
improved a great deal, and now with the introduction of
UsePreviousValue and ChangeSets it's far more reasonable to use AWS as
the source of truth for the configuration of a Stack.

As such, we no longer require caching all parameters in a file and
committing it to source control. Instead, we support an "answer file"
for automating the arguments to stack creation and update. This file
is passed to `create` or `update` with the `--answer-file` option and
has the same format as the previous parameters file, but there's no
reason to commit it to source control. Multiple developers can make
changes to production environments with confidence knowning that only
the changes they want to make are the changes that will be made.

In interactive environments (and when `--no-interactive` is not
passed), the `create` and `update` commands will ask the user for any
missing parameters. In addition, `create` will ask the user if they
want to use default values for parameters. In future versions, we'll
add support for more of the native CloudFormation properties that
define input validation, etc.

The system which prompts users for information is pluggable on a
per-parameter basis, allowing you to write custom plugins to get input
configuration from third-party sources.

## AWS_CREDENTIAL_FILE support removed ##

This legacy form of credential management hasn't been supported by the
Ruby SDK for quite some time, but when we originally wrote Moonshot
some teams at Acquia were still using this file for credentials. We
felt that moving away from these legacy formats was important to the
1.x release, so if you are using AWS_CREDENTIAL_FILE you will need to
switch to a [supported credentials management strategy][1].

[1]: http://docs.aws.amazon.com/sdk-for-ruby/v1/developer-guide/set-up-creds.html

## And much more! ##

This guide highlights only the changes one should make to get from
version 0.7.x to 1.0.0, but there are numerious bugfixes and
improvements not documented here. For more information, see the
[release notes][1].

[1]: https://github.com/acquia/moonshot/releases/tag/1.0.0.rc1