class Formatron::AWS::CloudFormationStack

utilities for monitoring CloudFormation stack activities rubocop:disable Metrics/ClassLength

Constants

CAPABILITIES
CREATE_COMPLETE_STATUS
CREATE_FINAL_STATUSES
DELETE_COMPLETE_STATUS
DELETE_FINAL_STATUSES
UPDATE_COMPLETE_STATUS
UPDATE_FINAL_STATUSES

Public Class Methods

new(stack_name:, client:) click to toggle source
# File lib/formatron/aws/cloud_formation_stack.rb, line 31
def initialize(stack_name:, client:)
  @stack_name = stack_name
  @client = client
  @stack = Aws::CloudFormation::Stack.new(
    stack_name,
    client: @client
  )
end

Public Instance Methods

create(template_url:, parameters:) click to toggle source
# File lib/formatron/aws/cloud_formation_stack.rb, line 44
def create(template_url:, parameters:)
  @client.create_stack(
    stack_name: @stack_name,
    template_url: template_url,
    capabilities: CAPABILITIES,
    on_failure: 'DO_NOTHING',
    parameters: parameters
  )
  @stack.wait_until_exists
  status = _wait_for_status statuses: CREATE_FINAL_STATUSES
  fail status unless status.eql? CREATE_COMPLETE_STATUS
end
delete() click to toggle source

rubocop:enable Metrics/MethodLength

# File lib/formatron/aws/cloud_formation_stack.rb, line 89
def delete
  last_event_id = _last_event_id
  @stack.delete
  status = _wait_for_status(
    statuses: DELETE_FINAL_STATUSES,
    last_event_id: last_event_id
  )
  fail status unless status.eql? DELETE_COMPLETE_STATUS
end
exists?() click to toggle source
# File lib/formatron/aws/cloud_formation_stack.rb, line 40
def exists?
  @stack.exists?
end
update(template_url:, parameters:) click to toggle source
# File lib/formatron/aws/cloud_formation_stack.rb, line 57
def update(template_url:, parameters:)
  last_event_id = _last_event_id
  return unless _update_unless_no_changes(
    template_url: template_url,
    parameters: parameters
  )
  status = _wait_for_status(
    statuses: UPDATE_FINAL_STATUSES,
    last_event_id: last_event_id
  )
  fail status unless status.eql? UPDATE_COMPLETE_STATUS
end

Private Instance Methods

_last_event_id() click to toggle source
# File lib/formatron/aws/cloud_formation_stack.rb, line 99
def _last_event_id
  @stack.events.each do |event|
    return event.event_id
  end
end
_update_unless_no_changes(template_url:, parameters:) click to toggle source

rubocop:disable Metrics/MethodLength

# File lib/formatron/aws/cloud_formation_stack.rb, line 71
def _update_unless_no_changes(template_url:, parameters:)
  @stack.update(
    template_url: template_url,
    parameters: parameters,
    capabilities: CAPABILITIES
  )
  true
rescue Aws::CloudFormation::Errors::ValidationError => error
  raise error unless error.message.eql?(
    'No updates are to be performed.'
  )
  Formatron::LOG.info do
    'No updates are to be performed for CloudFormation stack'
  end
  false
end
_wait_for_status(statuses:, last_event_id: nil) click to toggle source

rubocop:disable Metrics/MethodLength rubocop:disable Metrics/AbcSize

# File lib/formatron/aws/cloud_formation_stack.rb, line 107
def _wait_for_status(statuses:, last_event_id: nil)
  loop do
    events = []
    @stack.events.each do |event|
      break if event.event_id.eql? last_event_id
      events.push event
    end
    events.reverse!
    events.each do |event|
      status = event.resource_status
      timestamp = event.timestamp
      type = event.resource_type
      logical_id = event.logical_resource_id
      reason = event.resource_status_reason
      Formatron::LOG.info do
        "#{timestamp} - #{status} - #{type} - #{logical_id} - #{reason}"
      end
      return status if
        statuses.include?(status) &&
        logical_id.eql?(@stack_name) &&
        type.eql?('AWS::CloudFormation::Stack')
      last_event_id = event.event_id
    end
    sleep 1
  end
end