Callbacks provide a way to inject optional functionality
or custom functionality into sfn
commands. Callbacks
are generally invoked in two places:
before
- Prior to the command’s remote API requestafter
- Following the command’s remote API requestfailed
- Following failure of remote API requestThere are also callbacks available prior to the execution of a command. These can also be isolated to specific commands:
after_config
- Prior to the execution of the command.Callbacks can be applied globally (to all commands) or to specific commands. For example, applying a before callback to all commands:
Configuration.new do
callbacks.before ['custom_callback']
end
Applying a before callback to only the create
command:
Configuration.new do
callbacks.before_create ['custom_callback']
end
The other place a callback can be invoked is after a template has been loaded. This can allow the callback to perform some action on the loaded template prior to the command being executed. Enabling a template callback:
Configuration.new do
callbacks.template ['my-custom-callback']
end
When a stack does not include nested stacks, a before
callback can be sufficient for allowing modificiations
to a template prior to the command being executed. However,
when a stack contains nested stacks, those templates will
be processed and stored prior to the invocation of any
registered before
callbacks. For this reason, it is
best to use the template
callback when registering callbacks
that modify a template contents.
Finally, because callbacks can be distributed via gem it may be required to load the libraries so the callback is accessible:
Configuration.new do
callbacks.require ['my-custom-callback']
end
Some callbacks will require being enabled immediately upon startup
instead of during configuration. This can be done by using a special
:sfn
group within your bundle. For example, to load the sfn-serverspec
callback immediately the Gemfile should look like:
# Gemfile
source 'https://rubygems.org'
gem 'sfn'
group :sfn do
gem 'sfn-serverspec'
end
Builtin callbacks distributed with sfn
:
When assuming a role via STS on AWS a temporary set of credentials and token are generated for use. This callback will cache these credentials for re-use to prevent re-generation of temporary credentials on every command request.
To enable the callback:
Configuration.new do
callbacks do
default ['aws_assume_role']
end
end
Once temporary credentials have been generated, the callback will store the credentials
within a file in the working directory named .sfn-aws
. This path can be modified via
configuration:
Configuration.new do
aws_assume_role do
cache_file '/custom/path/to/file'
end
end
Loading and storage of credentials will only occur if a role is provided to assume. Given a configuration of:
Configuration.new do
callbacks.default 'aws_assume_role'
credentials do
aws_sts_role_arn ENV['AWS_STS_ROLE']
end
end
The callback will be enabled when the environment variable is provided:
$ AWS_STS_ROLE="arn:...MY_ROLE" sfn list
and will not be enabled when the environment variable is not provided:
$ sfn list
It can also be disabled/enabled via configuration setting:
Configuration.new do
aws_assume_role.status 'enabled'
end
Support for MFA within AWS can be provided using the AWS MFA callback. It will prompt for an MFA token code which is then used to generate the new session.
To enable the callback:
Configuration.new do
callbacks do
default ['aws_mfa']
end
end
The default virtual MFA device ARN will be used when creating the new session. If a non-default virutal MFA device or a hardware device is being used, set the device serial number with the configuration:
Configuration.new do
credentials do
provider :aws
aws_sts_mfa_serial_number 'DEVICE_IDENTIFIER'
end
end
After a session has been successfully created, the callback will store the session
token and credentials within a file in the working directory named .sfn-aws
. This
path can be configured via configuration:
Configuration.new do
aws_mfa do
cache_file '/custom/path/to/file'
end
end
Use of MFA may be conditional based on actions performed. For easier toggling of MFA usage, a configuration value can be used to enable or disable MFA:
Configuration.new do
aws_mfa do
cache_file ENV.fetch('SFN_MFA', 'enabled')
end
end
With this configuration, MFA usage can be easily disabled:
$ SFN_MFA=disabled sfn list
The Stack Policy Callback utilizes the policy feature built into the SparkleFormation library.
To enable the callback:
Configuration.new do
callbacks do
default ['stack_policy']
end
end
By default a stack policy is not disabled when an update command is run. This may require multiple update commands to be run first disabling the existing policy, then running the actual update. Stack policies can be automatically removed prior to update allowing the stack to be properly updated with the newly generated policy applied on completion. To disable the stack policy on update, add this to your configuration:
Configuration.new do
stack_policy.update 'defenseless'
end
To create a custom callback define a new class within the callback namespace and subclass the abstract class:
module Sfn
class Callback
class MyCallback < Callback
end
end
end
Providing a method that matches the callback name requested will enable its functionality. For example, running an action after every command:
module Sfn
class Callback
class MyCallback < Callback
def after(args)
# do things
end
end
end
end
or after the create
command:
module Sfn
class Callback
class MyCallback < Callback
def after_create(args)
# do things
end
end
end
end
The args
referenced above will be a Hash
composed of some or all of
the following:
:api_stack
- The Miasma::Models::Orchestration::Stack
instance of the remote stack:stack_name
- Name of the stack:sparkle_stack
- The SparkleFormation
instance of the template:hash_stack
- The Hash
instance of the templateEnabling the custom callback is the same as above:
Configuration.new do
callbacks.after ['custom_callback']
end
The sfn command will output a notification to the user before a callback is
run, and after it has completed. This may be too verbose for some callbacks.
A callback may disable this output using the quiet
method:
module Sfn
class Callback
class MyCallback < Callback
def quiet
true
end
end
end
end
Addon callbacks must be installed to the local bundle, or the system depending on usage type.
For bundle usage, add the callback to the Gemfile:
gem 'sfn-callback-name'
For system usage, install the gem:
$ gem install sfn-callback-name
Manage stack parameters via files within the project repository.
Define Serverspec rules directly on resources within templates and automatically run after success stack creation or update.