module Stackdeploy

Constants

VERSION

Public Class Methods

run() click to toggle source
# File lib/stackdeploy.rb, line 8
def self.run
  region = ARGV[0]
  stack_name = ARGV[1]
  param_name = ARGV[2]
  param_value = ARGV[3]
  sentry_org = ARGV[4]
  sentry_app = ARGV[5]
  git_sha = ARGV[6]

  if !region || !stack_name || !param_name || !param_value
    puts "Usage: stackdeploy region stack param value"
    exit(1)
  end

  puts "Updating stack #{stack_name} in #{region} with parameter #{param_name}=\"#{param_value}\""

  cloudformation = Aws::CloudFormation::Client.new(region: region)
  stacks = cloudformation.describe_stacks(stack_name: stack_name)
  stack = stacks.stacks[0]

  if !stack
    puts "Stack #{stack} not found."
    exit(1)
  end

  options = {
    stack_name: stack_name,
    use_previous_template: true,
    parameters: [],
    capabilities: ["CAPABILITY_IAM"],
    notification_arns: stack.notification_arns
  }

  stack.parameters.each do |param|
    options_param = {
      parameter_key: param.parameter_key
    }

    if param.parameter_key == param_name
      options_param[:parameter_value] = param_value
      options_param[:use_previous_value] = false
      param.use_previous_value = false
    else
      options_param[:parameter_value] = nil
      options_param[:use_previous_value] = true
    end

    options[:parameters] << options_param
  end

  begin
    response = cloudformation.update_stack(options)
  rescue Aws::CloudFormation::Errors::ValidationError => e
    puts "Update failed: #{e}"
    exit(1)
  end

  if response.successful?
    puts "Update requested successfully."
  else
    puts "Update request failed."
    exit(1)
  end

  # Notify sentry of the release
  if sentry_org && sentry_app && git_sha
    if !ENV['SENTRY_API_TOKEN']
      puts "Set SENTRY_API_TOKEN to update Sentry."
      exit(1)
    end

    uri = URI("https://app.getsentry.com/api/0/projects/#{sentry_org}/#{sentry_app}/releases/")
    Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
      request = Net::HTTP::Post.new(uri)
      request.form_data = {
        version: param_value,
        ref: git_sha
      }
      request["Authorization"] = "Bearer #{ENV["SENTRY_API_TOKEN"]}"

      response = http.request(request)

      if response.is_a?(Net::HTTPSuccess)
        puts "Tagged release #{param_value} for revision #{git_sha}"
      else
        puts "Tagging release failed: #{response.body}"
      end
    end
  end
end