class Stacker::Stack

Constants

CLIENT_METHODS
SAFE_UPDATE_POLICY

Attributes

name[R]
options[R]
region[R]

Public Class Methods

new(region, name, options = {}) click to toggle source
# File lib/stacker/stack.rb, line 46
def initialize region, name, options = {}
  @region, @name, @options = region, name, options
end

Public Instance Methods

capabilities() click to toggle source
# File lib/stacker/stack.rb, line 69
def capabilities
  @capabilities ||= Capabilities.new self
end
client() click to toggle source
# File lib/stacker/stack.rb, line 50
def client
  @client ||= region.client.stacks[name]
end
create(blocking = true) click to toggle source
# File lib/stacker/stack.rb, line 80
def create blocking = true
  if exists?
    Stacker.logger.warn 'Stack already exists'
    return
  end

  if parameters.missing.any?
    raise MissingParameters.new(
      "Required parameters missing: #{parameters.missing.join ', '}"
    )
  end

  Stacker.logger.info 'Creating stack'

  region.client.stacks.create(
    name,
    template.local,
    parameters: parameters.resolved,
    capabilities: capabilities.local
  )

  wait_while_status 'CREATE_IN_PROGRESS' if blocking
rescue AWS::CloudFormation::Errors::ValidationError => err
  raise Error.new err.message
end
outputs() click to toggle source
# File lib/stacker/stack.rb, line 73
def outputs
  @outputs ||= begin
    return {} unless complete?
    Hash[client.outputs.map { |output| [ output.key, output.value ] }]
  end
end
parameters() click to toggle source
# File lib/stacker/stack.rb, line 65
def parameters
  @parameters ||= Parameters.new self
end
template() click to toggle source
# File lib/stacker/stack.rb, line 61
def template
  @template ||= Template.new self
end
update(options = {}) click to toggle source
# File lib/stacker/stack.rb, line 106
def update options = {}
  options.assert_valid_keys(:blocking, :allow_destructive)

  blocking = options.fetch(:blocking, true)
  allow_destructive = options.fetch(:allow_destructive, false)

  if parameters.missing.any?
    raise MissingParameters.new(
      "Required parameters missing: #{parameters.missing.join ', '}"
    )
  end

  Stacker.logger.info 'Updating stack'

  update_params = {
    template: template.local,
    parameters: parameters.resolved,
    capabilities: capabilities.local
  }

  unless allow_destructive
    update_params[:stack_policy_during_update_body] = SAFE_UPDATE_POLICY
  end

  client.update(update_params)

  wait_while_status 'UPDATE_IN_PROGRESS' if blocking
rescue AWS::CloudFormation::Errors::ValidationError => err
  case err.message
  when /does not exist/
    raise DoesNotExistError.new err.message
  when /No updates/
    raise UpToDateError.new err.message
  else
    raise Error.new err.message
  end
end

Private Instance Methods

report_status() click to toggle source
# File lib/stacker/stack.rb, line 146
def report_status
  case status
  when /_COMPLETE$/
    Stacker.logger.info "#{name} Status => #{status}"
  when /_ROLLBACK_IN_PROGRESS$/
    failure_event = client.events.enum(limit: 30).find do |event|
      event.resource_status =~ /_FAILED$/
    end
    failure_reason = failure_event.resource_status_reason
    if failure_reason =~ /stack policy/
      raise StackPolicyError.new failure_reason
    else
      Stacker.logger.fatal "#{name} Status => #{status}"
      raise Error.new "Failure Reason: #{failure_reason}"
    end
  else
    Stacker.logger.debug "#{name} Status => #{status}"
  end
end
wait_while_status(wait_status) click to toggle source
# File lib/stacker/stack.rb, line 166
def wait_while_status wait_status
  while flush_cache('status') && status == wait_status
    report_status
    sleep 5
  end
  report_status
end