Class: Stack

Inherits:
Object
  • Object
show all
Defined in:
lib/cloudformer/stack.rb

Overview

Class to simplify AWS CloudFormation stack creation

Constant Summary collapse

SUCESS_STATES =
%w[CREATE_COMPLETE UPDATE_COMPLETE].freeze
FAILURE_STATES =
%w[
  CREATE_FAILED DELETE_FAILED UPDATE_ROLLBACK_FAILED
  ROLLBACK_FAILED ROLLBACK_COMPLETE ROLLBACK_FAILED
  UPDATE_ROLLBACK_COMPLETE UPDATE_ROLLBACK_FAILED
].freeze
END_STATES =
SUCESS_STATES + FAILURE_STATES

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(stack_name) ⇒ Stack

WAITING_STATES = [“CREATE_IN_PROGRESS”,“DELETE_IN_PROGRESS”,“ROLLBACK_IN_PROGRESS”,“UPDATE_COMPLETE_CLEANUP_IN_PROGRESS”,“UPDATE_IN_PROGRESS”,“UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS”,“UPDATE_ROLLBACK_IN_PROGRESS”]



18
19
20
21
22
23
# File 'lib/cloudformer/stack.rb', line 18

def initialize(stack_name)
  @name = stack_name
  @cf = AWS::CloudFormation.new
  @stack = @cf.stacks[name]
  @ec2 = AWS::EC2.new
end

Instance Attribute Details

#deployedObject

Returns the value of attribute deployed.



7
8
9
# File 'lib/cloudformer/stack.rb', line 7

def deployed
  @deployed
end

#nameObject

Returns the value of attribute name.



7
8
9
# File 'lib/cloudformer/stack.rb', line 7

def name
  @name
end

#stackObject

Returns the value of attribute stack.



7
8
9
# File 'lib/cloudformer/stack.rb', line 7

def stack
  @stack
end

Instance Method Details

#apply(template_file, parameters, disable_rollback = false, capabilities = [], notify = [], tags = []) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/cloudformer/stack.rb', line 29

def apply(template_file, parameters, disable_rollback = false,
          capabilities = [], notify = [], tags = [])
  if template_file =~ %r{^https:\/\/s3\S+\.amazonaws\.com\/(.*)}
    template = template_file
  elsif template_file =~ %r{^http.*(.json)$/}
    begin
      response = HTTParty.get(template_file)
      template = response.body
    rescue => e
      puts "Unable to retieve json file for template from #{template_file} - #{e.class}, #{e}"
      return :Failed
    end
  else
    template = File.read(template_file)
  end
  validation = validate(template)
  unless validation["valid"]
    puts "Unable to update - #{validation['response'][:code]} - #{validation['response'][:message]}"
    return :Failed
  end
  pending_operations = false
  begin
    if deployed
      pending_operations = update(template, parameters, capabilities)
    else
      pending_operations = create(template, parameters, disable_rollback, capabilities, notify, tags)
    end
  rescue ::AWS::CloudFormation::Errors::ValidationError => e
    puts e.message
    return e.message == "No updates are to be performed." ? :NoUpdates : :Failed
  end
  wait_until_end if pending_operations
  deploy_succeeded? ? :Succeeded : :Failed
end

#deleteObject



78
79
80
81
82
83
84
85
# File 'lib/cloudformer/stack.rb', line 78

def delete
  with_highlight do
    puts "Attempting to delete stack - #{name}"
    stack.delete
    wait_until_end
    return deploy_succeeded?
  end
end

#deploy_succeeded?Boolean

Returns:

  • (Boolean)


64
65
66
67
68
# File 'lib/cloudformer/stack.rb', line 64

def deploy_succeeded?
  return true unless FAILURE_STATES.include?(stack.status)
  puts "Unable to deploy template. Check log for more information."
  false
end

#events(options = {}) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
# File 'lib/cloudformer/stack.rb', line 97

def events(options = {})
  with_highlight do
    if !deployed
      puts "Stack not up."
      return
    end
    stack.events.sort_by { |a| a.timestamp }.each do |event|
      puts "#{event.timestamp} - #{event.physical_resource_id.to_s} - #{event.logical_resource_id} - #{event.resource_type} - #{event.resource_status} - #{event.resource_status_reason.to_s}"
    end
  end
end

#outputsObject



109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/cloudformer/stack.rb', line 109

def outputs
  with_highlight do
    if !deployed
      puts "Stack not up."
      return 1
    end
    stack.outputs.each do |output|
      puts "#{output.key} - #{output.description} - #{output.value}"
    end
  end
  return 0
end

#start_instancesObject



74
75
76
# File 'lib/cloudformer/stack.rb', line 74

def start_instances
  update_instances("start")
end

#statusObject



87
88
89
90
91
92
93
94
95
# File 'lib/cloudformer/stack.rb', line 87

def status
  with_highlight do
    if deployed
      puts "#{stack.name} - #{stack.status} - #{stack.status_reason}"
    else
      puts "#{name} - Not Deployed"
    end
  end
end

#stop_instancesObject



70
71
72
# File 'lib/cloudformer/stack.rb', line 70

def stop_instances
  update_instances("stop")
end

#validate(template) ⇒ Object



122
123
124
125
126
127
128
# File 'lib/cloudformer/stack.rb', line 122

def validate(template)
  response = @cf.validate_template(template)
  return {
    "valid" => response[:code].nil?,
    "response" => response
  }
end