Class: Stackit::ManagedStack

Inherits:
Stack
  • Object
show all
Includes:
Wait
Defined in:
lib/stackit/stack/managed_stack.rb

Defined Under Namespace

Classes: DRY_RUN_RESPONSE

Instance Attribute Summary collapse

Attributes inherited from Stack

#change_set_name, #cloudformation, #creation_time, #description, #disable_rollback, #last_updated_time, #notification_arns, #on_failure, #parameters, #retain_resources, #stack_id, #stack_name, #stack_policy_body, #stack_policy_during_update_body, #stack_policy_during_update_url, #stack_policy_url, #stack_status, #stack_status_reason, #tags, #timeout_in_minutes, #use_previous_template

Instance Method Summary collapse

Methods included from Wait

#wait_for_stack, #wait_for_stack_to_delete, #wait_until_stack_has_key

Methods inherited from Stack

#[], #change_set_request_params, #create_stack_request_params, #delete_stack_request_params, #hydrate!, #outputs, #resources, #update_stack_request_params

Constructor Details

#initialize(options = {}) ⇒ ManagedStack

Returns a new instance of ManagedStack.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/stackit/stack/managed_stack.rb', line 18

def initialize(options={})
  super(options)
  self.template_path = options[:template]
  self.user_defined_parameters = symbolized_user_defined_parameters(options[:user_defined_parameters])
  self.parameter_map = symbolized_parameter_map(options[:parameter_map])
  self.stack_name = options[:stack_name] || default_stack_name
  self.depends = options[:depends] || []
  self.disable_rollback = self.debug ? true : !!options[:disable_rollback]
  self.debug = !!options[:debug] || Stackit.debug
  self.force = options[:force]
  self.wait = options[:wait]
  self.dry_run = options[:dry_run]
  self.notifier = options[:notifier] || Stackit::ThorNotifier.new
  parse_file_parameters(options[:parameters_file]) if options[:parameters_file]
  create_stack_policy(options[:stack_policy])
  create_stack_policy_during_update(options[:stack_policy_during_update])
end

Instance Attribute Details

#debugObject

Returns the value of attribute debug.



13
14
15
# File 'lib/stackit/stack/managed_stack.rb', line 13

def debug
  @debug
end

#dependsObject

Returns the value of attribute depends.



12
13
14
# File 'lib/stackit/stack/managed_stack.rb', line 12

def depends
  @depends
end

#dry_runObject

Returns the value of attribute dry_run.



11
12
13
# File 'lib/stackit/stack/managed_stack.rb', line 11

def dry_run
  @dry_run
end

#file_parametersObject

Returns the value of attribute file_parameters.



8
9
10
# File 'lib/stackit/stack/managed_stack.rb', line 8

def file_parameters
  @file_parameters
end

#forceObject

Returns the value of attribute force.



14
15
16
# File 'lib/stackit/stack/managed_stack.rb', line 14

def force
  @force
end

#notifierObject

Returns the value of attribute notifier.



16
17
18
# File 'lib/stackit/stack/managed_stack.rb', line 16

def notifier
  @notifier
end

#parameter_mapObject

Returns the value of attribute parameter_map.



10
11
12
# File 'lib/stackit/stack/managed_stack.rb', line 10

def parameter_map
  @parameter_map
end

#templateObject

Returns the value of attribute template.



6
7
8
# File 'lib/stackit/stack/managed_stack.rb', line 6

def template
  @template
end

#template_pathObject

Returns the value of attribute template_path.



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

def template_path
  @template_path
end

#user_defined_parametersObject

Returns the value of attribute user_defined_parameters.



9
10
11
# File 'lib/stackit/stack/managed_stack.rb', line 9

def user_defined_parameters
  @user_defined_parameters
end

#waitObject

Returns the value of attribute wait.



15
16
17
# File 'lib/stackit/stack/managed_stack.rb', line 15

def wait
  @wait
end

Instance Method Details

#change_set!Object



130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/stackit/stack/managed_stack.rb', line 130

def change_set!
  begin
    response = cloudformation_request(:create_change_set)
    notifier.response(response)
  rescue ::Aws::CloudFormation::Errors::AlreadyExistsException => e
    notifier.backtrace(e) if Stackit.debug
    notifier.error(e.message)
  rescue ::Aws::CloudFormation::Errors::ValidationError => e
    notifier.backtrace(e) if Stackit.debug
    notifier.error(e.message)
  end
  response
end

#create!Object



36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/stackit/stack/managed_stack.rb', line 36

def create!
  begin
    response = cloudformation_request(:create_stack)
    notifier.response(response)
  rescue ::Aws::CloudFormation::Errors::AlreadyExistsException => e
    notifier.backtrace(e) if Stackit.debug
    notifier.error(e.message)
  rescue ::Aws::CloudFormation::Errors::ValidationError => e
    notifier.backtrace(e) if Stackit.debug
    notifier.error(e.message)
  end
  response
end

#delete!Object



68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/stackit/stack/managed_stack.rb', line 68

def delete!
  begin
    response = cloudformation_request(:delete_stack)
    notifier.response(response)
  rescue ::Aws::CloudFormation::Errors::AlreadyExistsException => e
    notifier.backtrace(e) if Stackit.debug
    notifier.error(e.message)
  rescue ::Aws::CloudFormation::Errors::ValidationError => e
    notifier.backtrace(e) if Stackit.debug
    notifier.error(e.message)
  end
  response
end

#deploy!Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/stackit/stack/managed_stack.rb', line 82

def deploy!
  if !File.exist?(template)
    delete!
    wait_for_stack_to_delete
    notifier.success('Delete successful')
  elsif exist?
    begin
      update!
      wait_for_stack
      notifier.success('Update successful')
    rescue ::Aws::CloudFormation::Errors::ValidationError => e 
      if e.message.include? "No updates are to be performed"
        Stackit.logger.info "No updates are to be performed"
      elsif e.message.include? "_FAILED state and can not be updated"
        Stackit.logger.info 'Stack is in a failed state and can\'t be updated. Deleting/creating a new stack.'
        delete!
        wait_for_stack_to_delete
        create!
        wait_for_stack
        notifier.success('Stack deleted and re-created')
      else
        raise e
      end
    end
  else
    begin
      create!
      wait_for_stack
      notifier.success('Created successfully')
    rescue ::Aws::CloudFormation::Errors::ValidationError => e 
      if e.message.include? "_FAILED state and can not be updated"
        Stackit.logger.info 'Stack already exists, is in a failed state, and can\'t be updated. Deleting and creating a new stack.'
        delete!
        wait_for_stack_to_delete
        create!
        wait_for_stack
        notifier.success('Stack deleted and re-created')
      else
        raise e
      end
    end
  end
end

#describeObject



144
145
146
147
148
149
150
151
152
153
# File 'lib/stackit/stack/managed_stack.rb', line 144

def describe
  response = cloudformation_request(:describe_stacks)
  if response && response[:stacks]
    response[:stacks].first
  else
    nil
  end
rescue ::Aws::CloudFormation::Errors::ValidationError
  nil
end

#exist?Boolean

Returns:

  • (Boolean)


126
127
128
# File 'lib/stackit/stack/managed_stack.rb', line 126

def exist?
  describe != nil
end

#update!Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/stackit/stack/managed_stack.rb', line 50

def update!
  begin
    response = cloudformation_request(:update_stack)
    notifier.response(response)
  rescue ::Aws::CloudFormation::Errors::AlreadyExistsException => e
    notifier.backtrace(e) if Stackit.debug
    notifier.error(e.message)
  rescue ::Aws::CloudFormation::Errors::ValidationError => e
    if e.message =~ /No updates are to be performed./
      notifier.success(e.message)
    else
      notifier.backtrace(e) if Stackit.debug
      notifier.error(e.message)
    end
  end
  response
end