Class: Dev::Aws::Cloudformation

Inherits:
Object
  • Object
show all
Defined in:
lib/firespring_dev_commands/aws/cloudformation.rb,
lib/firespring_dev_commands/aws/cloudformation/parameters.rb

Overview

Class for performing cloudformation functions

Defined Under Namespace

Classes: Parameters

Constant Summary collapse

NOT_STARTED =

Not Started status

:not_started
STARTED =

Started status

:started
NO_CHANGES =

No Changes status

:no_changes
FAILED =

Failed status

:failed
FINISHED =

Finished status

:finished

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, template_filename, parameters: Dev::Aws::Cloudformation::Parameters.new, capabilities: [], failure_behavior: 'ROLLBACK', preserve_parameters_on_update: false) ⇒ Cloudformation

Returns a new instance of Cloudformation.



26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/firespring_dev_commands/aws/cloudformation.rb', line 26

def initialize(name, template_filename, parameters: Dev::Aws::Cloudformation::Parameters.new, capabilities: [], failure_behavior: 'ROLLBACK',
               preserve_parameters_on_update: false)
  raise 'parameters must be an intsance of parameters' unless parameters.is_a?(Dev::Aws::Cloudformation::Parameters)

  @client = nil
  @name = name
  @template_filename = template_filename
  @parameters = parameters
  @capabilities = capabilities
  @failure_behavior = failure_behavior
  @preserve_parameters_on_update = preserve_parameters_on_update
  @state = NOT_STARTED
end

Instance Attribute Details

#capabilitiesObject

Returns the value of attribute capabilities.



24
25
26
# File 'lib/firespring_dev_commands/aws/cloudformation.rb', line 24

def capabilities
  @capabilities
end

#clientObject

Create/set a new client if none is present Return the client



42
43
44
# File 'lib/firespring_dev_commands/aws/cloudformation.rb', line 42

def client
  @client
end

#failure_behaviorObject

Returns the value of attribute failure_behavior.



24
25
26
# File 'lib/firespring_dev_commands/aws/cloudformation.rb', line 24

def failure_behavior
  @failure_behavior
end

#nameObject

Returns the value of attribute name.



24
25
26
# File 'lib/firespring_dev_commands/aws/cloudformation.rb', line 24

def name
  @name
end

#parametersObject

Returns the value of attribute parameters.



24
25
26
# File 'lib/firespring_dev_commands/aws/cloudformation.rb', line 24

def parameters
  @parameters
end

#preserve_parameters_on_updateObject

Returns the value of attribute preserve_parameters_on_update.



24
25
26
# File 'lib/firespring_dev_commands/aws/cloudformation.rb', line 24

def preserve_parameters_on_update
  @preserve_parameters_on_update
end

#stateObject

Returns the value of attribute state.



24
25
26
# File 'lib/firespring_dev_commands/aws/cloudformation.rb', line 24

def state
  @state
end

#template_filenameObject

Returns the value of attribute template_filename.



24
25
26
# File 'lib/firespring_dev_commands/aws/cloudformation.rb', line 24

def template_filename
  @template_filename
end

Instance Method Details

#create(should_wait: true) ⇒ Object

Create the cloudformation stack



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/firespring_dev_commands/aws/cloudformation.rb', line 47

def create(should_wait: true)
  # Call upload function to get the s3 url
  template_url = upload(template_filename)

  # Create the cloudformation stack
  client.create_stack(
    stack_name: name,
    template_url:,
    parameters: parameters.default,
    capabilities:,
    on_failure: failure_behavior
  )
  @state = STARTED
  LOG.info "#{name} stack create started at #{Time.now.to_s.light_yellow}"

  # return if we aren't waiting here
  return unless should_wait

  # Wait if we are supposed to wait
  create_wait
  @state = FINISHED
  LOG.info "#{name} stack create finished at #{Time.now.to_s.light_yellow}"
rescue => e
  LOG.error "Error creating stack: #{e.message}"
  @state = FAILED
end

#create_waitObject

Wait for create complete



139
140
141
# File 'lib/firespring_dev_commands/aws/cloudformation.rb', line 139

def create_wait
  wait(name, :create_complete)
end

#delete(should_wait: true) ⇒ Object

Delete the cloudformation stack



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/firespring_dev_commands/aws/cloudformation.rb', line 120

def delete(should_wait: true)
  # Delete the cloudformation stack
  client.delete_stack(stack_name: name)
  @state = STARTED
  LOG.info "#{name} stack delete started at #{Time.now.to_s.light_yellow}"

  # Return if we aren't waiting here
  return unless should_wait

  # Wait if we are supposed to wait
  delete_wait
  @state = FINISHED
  LOG.info "#{name} stack delete finished at #{Time.now.to_s.light_yellow}"
rescue => e
  LOG.error "Error deleting stack: #{e.message}"
  @state = FAILED
end

#delete_waitObject

Wait for delete complete



149
150
151
# File 'lib/firespring_dev_commands/aws/cloudformation.rb', line 149

def delete_wait
  wait(name, :delete_complete)
end

#exist?Boolean

Get the cloudformation stack

Returns:

  • (Boolean)


75
76
77
78
79
# File 'lib/firespring_dev_commands/aws/cloudformation.rb', line 75

def exist?
  !client.describe_stacks(stack_name: name).stacks.empty?
rescue ::Aws::CloudFormation::Errors::ValidationError
  false
end

#failed?Boolean

State matches the failed state

Returns:

  • (Boolean)


184
185
186
# File 'lib/firespring_dev_commands/aws/cloudformation.rb', line 184

def failed?
  state == FAILED
end

#finished?Boolean

State matches the finished state

Returns:

  • (Boolean)


189
190
191
# File 'lib/firespring_dev_commands/aws/cloudformation.rb', line 189

def finished?
  state == FINISHED
end

#no_changes?Boolean

State matches the no_changes state

Returns:

  • (Boolean)


179
180
181
# File 'lib/firespring_dev_commands/aws/cloudformation.rb', line 179

def no_changes?
  state == NO_CHANGES
end

#not_started?Boolean

State matches the not started state

Returns:

  • (Boolean)


169
170
171
# File 'lib/firespring_dev_commands/aws/cloudformation.rb', line 169

def not_started?
  state == NOT_STARTED
end

#started?Boolean

State matches the started state

Returns:

  • (Boolean)


174
175
176
# File 'lib/firespring_dev_commands/aws/cloudformation.rb', line 174

def started?
  state == STARTED
end

#update(should_wait: true) ⇒ Object

Update the cloudformation stack



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
# File 'lib/firespring_dev_commands/aws/cloudformation.rb', line 82

def update(should_wait: true)
  # Call upload function to get the s3 url
  template_url = upload(template_filename)

  update_parameters = if preserve_parameters_on_update
                        parameters.preserve
                      else
                        parameters.default
                      end
  # Update the cloudformation stack
  client.update_stack(
    stack_name: name,
    template_url:,
    parameters: update_parameters,
    capabilities:
  )
  @state = STARTED
  LOG.info "#{name} stack update started at #{Time.now.to_s.light_yellow}"

  # return if we aren't waiting here
  return unless should_wait

  # Wait if we are supposed to wait
  update_wait
  @state = FINISHED
  LOG.info "#{name} stack update finished at #{Time.now.to_s.light_yellow}"
rescue => e
  if /no updates/i.match?(e.message)
    LOG.info "No updates to needed on #{name}".light_yellow
    @state = NO_CHANGES
  else

    LOG.error "Error updating stack: #{e.message}"
    @state = FAILED
  end
end

#update_waitObject

Wait for update complete



144
145
146
# File 'lib/firespring_dev_commands/aws/cloudformation.rb', line 144

def update_wait
  wait(name, :update_complete)
end

#wait(stack_name, type = 'exists', max_attempts: 360, delay: 5) ⇒ Object

Wait for the stack name to complete the specified type of action Defaults to exists



155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/firespring_dev_commands/aws/cloudformation.rb', line 155

def wait(stack_name, type = 'exists', max_attempts: 360, delay: 5)
  # Don't wait if there's nothing to wait for
  return if no_changes? || finished?

  client.wait_until(
    :"stack_#{type}",
    {stack_name:},
    {max_attempts:, delay:}
  )
rescue ::Aws::Waiters::Errors::WaiterFailed => e
  raise "Action failed to complete: #{e.message}"
end