Class: RubyLambda::Deploy

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_lambda/deploy.rb

Instance Method Summary collapse

Constructor Details

#initialize(current_directory, options = {'native_extensions' => false, 'config' => 'config.yml'}) ⇒ Deploy

Returns a new instance of Deploy.



3
4
5
6
7
# 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

Instance Method Details

#clean_upObject



76
77
78
79
80
# 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_roleObject



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# 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) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# 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_arnObject



115
116
117
118
119
120
121
122
123
124
125
# 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_zipObject



68
69
70
71
72
73
74
# 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_fileObject



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# 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) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 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) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
# 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