class RubyLambda::Deploy

Public Class Methods

new(current_directory, options = {'native_extensions' => false, 'config' => 'config.yml'}) click to toggle source
# File lib/ruby_lambda/deploy.rb, line 3
def initialize(current_directory, options = {'native_extensions' => false, 'config' => 'config.yml'})
  @current_directory  = current_directory
  @shell = Thor::Base.shell.new
  @options = options
end

Public Instance Methods

clean_up() click to toggle source
# File lib/ruby_lambda/deploy.rb, line 76
def clean_up
  return if @options['zip_file'] != ''

  FileUtils.rm "#{@current_directory}/#{@zip_file_name}"
end
create_role() click to toggle source
# File lib/ruby_lambda/deploy.rb, line 127
def create_role
  policy_doc = {
    Version:'2012-10-17',
    Statement:[
      {
        Effect:'Allow',
        Action:'sts:AssumeRole',
        Principal:{
          Service:'lambda.amazonaws.com'
        }
      }]
  }

  role = @iam.create_role({
    role_name: 'ruby_lambda_gem_basic_execution_role',
    description: 'Role created to deploy lambda functions from ruby lambda gem',
    assume_role_policy_document: policy_doc.to_json
  })

  role.attach_policy({
    policy_arn: 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
  })

  sleep 5 # This will give the policy enough time to be attached to the role https://stackoverflow.com/a/37438525/7157278
  role
end
deploy_function(deploy_options) click to toggle source
# File lib/ruby_lambda/deploy.rb, line 82
def deploy_function(deploy_options)
  begin
    if @options['update']
      update_function(deploy_options)
    else
      @client.create_function(deploy_options)
    end
  rescue Aws::Lambda::Errors::ResourceConflictException
    if @options['update']
      update_function(deploy_options)
    else
      @shell.say('Function already exists use the --update flag to update the current function', :red)
      clean_up
      exit 1
    end
  end
end
get_role_arn() click to toggle source
# File lib/ruby_lambda/deploy.rb, line 115
def get_role_arn
  begin
    new_role = @iam_client.get_role({
      role_name: 'ruby_lambda_gem_basic_execution_role',
    })

    new_role.role.arn
  rescue Aws::IAM::Errors::NoSuchEntity
    create_role.data.arn
  end
end
get_temp_build_zip() click to toggle source
# File lib/ruby_lambda/deploy.rb, line 68
def get_temp_build_zip
  @zip_file_name = "#{Time.now.strftime('%Y-%m-%d_%H-%M-%S')}_deploy_build.zip"

  RubyLambda::Build.new(@current_directory, {'file_name' => @zip_file_name, 'native_extensions' => @options['native_extensions']}).run(mute: @mute)

  @zip_file_name
end
load_data_from_config_file() click to toggle source
# File lib/ruby_lambda/deploy.rb, line 48
def load_data_from_config_file
  begin
    config_data = YAML.load(ERB.new(File.read("#{@current_directory}/#{@options['config']}")).result)

    raise RubyLambda::ExecuteError.new('Invalid config file') unless config_data.is_a?(Hash)

    config_data
  rescue Errno::ENOENT
    no_config_file_message = 'Config file missing, create a config.yml file or use the -c / --config flag to pass a different config file.'

    @shell.say(no_config_file_message, :red)

    exit 1
  rescue RubyLambda::ExecuteError
    @shell.say('Invalid config file', :red)

    exit 1
  end
end
run(mute: false) click to toggle source
# File lib/ruby_lambda/deploy.rb, line 9
def run(mute: false)
  @mute = mute

  @config_data  = load_data_from_config_file

  Aws.config.update({
    credentials: Aws::Credentials.new(@config_data['aws_access_key'], @config_data['aws_secret_access_key'])
  })

  @iam_client = Aws::IAM::Client.new(region: @config_data['region'])

  @iam = Aws::IAM::Resource.new(client: @iam_client)

  @client = Aws::Lambda::Client.new(region: @config_data['region'])

  deploy_options = {}

  deploy_options[:role] = get_role_arn
  deploy_options[:function_name] = @config_data['function_name']
  deploy_options[:handler] = @config_data['handler']
  deploy_options[:runtime] = @config_data['runtime']
  deploy_options[:publish] = @options['publish']

  if @options['zip_file']
    zip_file = @options['zip_file']
  else
    zip_file = get_temp_build_zip
  end

  deploy_options[:code] = { zip_file: File.open(zip_file, 'rb').read }

  function = deploy_function(deploy_options)

  clean_up

  ap function
  @shell.say('Function deployed', :green) unless @mute
end
update_function(deploy_options) click to toggle source
# File lib/ruby_lambda/deploy.rb, line 100
def update_function(deploy_options)
  begin
    update_options = {}
    update_options[:function_name] = deploy_options[:function_name]
    update_options[:publish] = deploy_options[:publish]
    update_options[:zip_file] = deploy_options[:code][:zip_file]

    @client.update_function_code(update_options)
  rescue Aws::Lambda::Errors::ResourceNotFoundException
    @shell.say('Function was not found, remove the --update flag to create it', :red)
    clean_up
    exit 1
  end
end