class Awful::CloudFormation

add as a subcommand of `cf`

Constants

COLORS
STATUSES

stack statuses that are not DELETE_COMPLETE

Public Instance Methods

color(string) click to toggle source
# File lib/awful/cloudformation.rb, line 37
def color(string)
  set_color(string, COLORS.fetch(string.downcase.to_sym, :blue))
end
cost(name) click to toggle source
# File lib/awful/cloudformation.rb, line 265
def cost(name)
  template = cf.get_template(stack_name: name).template_body
  parameters = cf.describe_stacks(stack_name: name).stacks.first.parameters.map do |p|
    {
      parameter_key:      p.parameter_key,
      parameter_value:    p.parameter_value,
      use_previous_value: true, # use param values from actual stack
    }
  end
  puts cf.estimate_template_cost(template_body: template, parameters: parameters).url
end
create(name, file = nil) click to toggle source
# File lib/awful/cloudformation.rb, line 138
def create(name, file = nil)
  cf.create_stack(stack_name: name, template_body: file_or_stdin(file)).output do |response|
    puts response.stack_id
  end
end
delete(name) click to toggle source
# File lib/awful/cloudformation.rb, line 173
def delete(name)
  if yes? "Really delete stack #{name}?", :yellow
    cf.delete_stack(stack_name: name)
  end
end
dump(name) click to toggle source
# File lib/awful/cloudformation.rb, line 82
def dump(name)
  cf.describe_stacks(stack_name: name).stacks.output do |stacks|
    stacks.each do |stack|
      puts YAML.dump(stringify_keys(stack.to_hash))
    end
  end
end
events(name) click to toggle source
# File lib/awful/cloudformation.rb, line 181
def events(name)
  events = cf.describe_stack_events(stack_name: name).stack_events
  events = events.first(options[:number]) if options[:number]
  events.reverse.output do |events|
    print_table events.map { |e|
      [e.timestamp, color(e.resource_status), e.resource_type, e.logical_resource_id, e.resource_status_reason]
    }
  end
end
exists(name) click to toggle source
# File lib/awful/cloudformation.rb, line 72
def exists(name)
  begin
    cf.describe_stacks(stack_name: name)
    true
  rescue Aws::CloudFormation::Errors::ValidationError
    false
  end.output(&method(:puts))
end
id(name, resource) click to toggle source
# File lib/awful/cloudformation.rb, line 232
def id(name, resource)
  detail = cf.describe_stack_resource(stack_name: name, logical_resource_id: resource).stack_resource_detail
  if options[:all]
    detail.output do |d|
      puts YAML.dump(stringify_keys(d.to_hash))
    end
  else
    detail.physical_resource_id.output do |id|
      puts id
    end
  end
end
limits() click to toggle source
# File lib/awful/cloudformation.rb, line 257
def limits
  cf.describe_account_limits.account_limits.output do |limits|
    print_table limits.map { |l| [l.name, l.value] }
  end
end
ls(name = nil) click to toggle source
# File lib/awful/cloudformation.rb, line 55
def ls(name = nil)
  paginate(:stack_summaries) do |next_token|
    cf.list_stacks(stack_status_filter: STATUSES, next_token: next_token)
  end.tap do |stacks|
    stacks.select! { |s| s.stack_name.match(name) } if name
  end.output do |list|
    if options[:long]
      print_table list.map { |s|
        [s.stack_name, s.creation_time, color(s.stack_status), s.template_description]
      }.sort
    else
      puts list.map(&:stack_name).sort
    end
  end
end
outputs(name, key = nil) click to toggle source
# File lib/awful/cloudformation.rb, line 100
def outputs(name, key = nil)
  output_hash = cf.describe_stacks(stack_name: name).stacks.first.outputs.each_with_object({}) do |o, hash|
    hash[o.output_key] = o.output_value
  end

  if key
    output_hash[key.to_s].output(&method(:puts))
  else
    output_hash.output do |hash|
      print_table hash.sort
    end
  end
end
parameters(name) click to toggle source
# File lib/awful/cloudformation.rb, line 91
def parameters(name)
  cf.describe_stacks(stack_name: name).stacks.first.parameters.each_with_object({}) do |p, h|
    h[p.parameter_key] = p.parameter_value
  end.output do |hash|
    print_table hash.sort
  end
end
policy(name, file = nil) click to toggle source
# File lib/awful/cloudformation.rb, line 247
def policy(name, file = nil)
  policy = options[:json].nil? ? file_or_stdin(file) : options[:json]
  if policy
    cf.set_stack_policy(stack_name: name, stack_policy_body: policy)
  else
    cf.get_stack_policy(stack_name: name).stack_policy_body.output(&method(:puts))
  end
end
resources(name) click to toggle source
# File lib/awful/cloudformation.rb, line 196
def resources(name)
  resources = cf.list_stack_resources(stack_name: name).stack_resource_summaries

  if options[:type]
    resources.select! do |resource|
      options[:type].include?(resource.resource_type)
    end
  end

  if options[:match]
    resources.select! do |resource|
      Regexp.new(options[:match], Regexp::IGNORECASE).match(resource.resource_type)
    end
  end

  resources.output do |resources|
    if options[:long]
      print_table(
        resources.map { |r|
          [
            r.logical_resource_id,
            r.resource_type,
            color(r.resource_status),
            r.physical_resource_id,
          ]
        },
        truncate: options[:truncate]
      )
    else
      puts resources.map(&:logical_resource_id)
    end
  end
end
stack_summaries(next_token = nil) click to toggle source

get list of stacks

# File lib/awful/cloudformation.rb, line 42
def stack_summaries(next_token = nil)
  response = cf.list_stacks(next_token: next_token)
  summaries = response.stack_summaries
  if response.next_token # recurse to get more data
    summaries += stack_summaries(response.next_token)
  else
    summaries
  end
end
status(name) click to toggle source
# File lib/awful/cloudformation.rb, line 115
def status(name)
  cf.describe_stacks(stack_name: name).stacks.first.stack_status.output(&method(:puts))
end
tag(name, *tags) click to toggle source
# File lib/awful/cloudformation.rb, line 157
def tag(name, *tags)
  params = {
    stack_name:            name,
    use_previous_template: true,
    capabilities:          ['CAPABILITY_IAM'],
    tags: tags.map do |t|
      key, value = t.split(/[:=]/)
      {key: key, value: value}
    end
  }
  cf.update_stack(params).output do |response|
    puts response.stack_id
  end
end
template(name) click to toggle source
# File lib/awful/cloudformation.rb, line 120
def template(name)
  cf.get_template(stack_name: name).template_body.output do |template|
    puts template
  end
end
update(name, file = nil) click to toggle source
# File lib/awful/cloudformation.rb, line 145
def update(name, file = nil)
  begin
    cf.update_stack(stack_name: name, template_body: file_or_stdin(file)).output do |response|
      puts response.stack_id
    end
  rescue Aws::CloudFormation::Errors::ValidationError => e
    e.output { |err| puts err.message }
  end
end
validate(file = nil) click to toggle source
# File lib/awful/cloudformation.rb, line 127
def validate(file = nil)
  begin
    cf.validate_template(template_body: file_or_stdin(file)).output do |response|
      puts YAML.dump(stringify_keys(response.to_hash))
    end
  rescue Aws::CloudFormation::Errors::ValidationError => e
    e.output { |err| puts err.message }
  end
end