Class: LambdaWrap::LambdaManager

Inherits:
Object
  • Object
show all
Defined in:
lib/lambda_wrap/lambda_manager.rb

Overview

The LambdaManager simplifies creating a package, publishing to S3, deploying a new version, & setting permissions.

Note: The concept of an environment of the LambdaWrap gem matches an alias of AWS Lambda.

Instance Method Summary collapse

Constructor Details

#initializeLambdaManager

The constructor does some basic setup

  • Validating basic AWS configuration

  • Creating the underlying client to interace with the AWS SDK



13
14
15
16
# File 'lib/lambda_wrap/lambda_manager.rb', line 13

def initialize
  # AWS lambda client
  @client = Aws::Lambda::Client.new
end

Instance Method Details

#create_alias(function_name, func_version, alias_name) ⇒ Object

Creates an alias for a given lambda function version.

Arguments

function_name

The lambda function name for which the alias should be created.

func_version

The lambda function versino to which the alias should point.

alias_name

The name of the alias, matching the LambdaWrap environment concept.



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

def create_alias(function_name, func_version, alias_name)
  # create or update alias
  func_alias = @client.list_aliases(function_name: function_name).aliases.select { |a| a.name == alias_name }.first
  if !func_alias
    a = @client.create_alias(
      function_name: function_name, name: alias_name, function_version: func_version,
      description: 'created by an automated script'
    ).data
  else
    a = @client.update_alias(
      function_name: function_name, name: alias_name, function_version: func_version,
      description: 'updated by an automated script'
    ).data
  end
  puts a

  add_api_gateway_permissions(function_name, alias_name)
end

#deploy_lambda(bucket, key, version_id, function_name, handler, lambda_role, lambda_description = 'Deployed with LambdaWrap', vpc_subnet_ids = [], vpc_security_group_ids = []) ⇒ Object

Deploys a package that has been uploaded to S3.

Arguments

bucket

The S3 bucket where the package can be retrieved from.

key

The S3 path (key) where the package can be retrieved from.

version_id

The version of the file on S3 to retrieve.

function_name

The name of the lambda function.

handler

The handler that should be executed for this lambda function.

lambda_role

The arn of the IAM role that should be used when executing the lambda function.

lambda_description

The description of the lambda function.

vpc_subnet_ids

A list of subnet ids for the lambda’s VPC configuration. All subnets must be on the same VPC.

vpc_security_group_ids

A list of security group ids for the lambda’s VPC configuration. All of the security_group_ids must be on the same VPC.



78
79
80
81
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
# File 'lib/lambda_wrap/lambda_manager.rb', line 78

def deploy_lambda(
  bucket, key, version_id, function_name, handler, lambda_role,
  lambda_description = 'Deployed with LambdaWrap', vpc_subnet_ids = [], vpc_security_group_ids = []
)
  # create or update function

  begin
    @client.get_function(function_name: function_name)
    func_config = @client.update_function_code(function_name: function_name, s3_bucket: bucket, s3_key: key,
                                               s3_object_version: version_id, publish: true).data
    puts func_config
    func_version = func_config.version
    raise 'Error while publishing existing lambda function ' + function_name unless func_version
  rescue Aws::Lambda::Errors::ResourceNotFoundException
    # check if vpc_subnet_ids and vpc_security_group_ids are empty or not and set the vpc_config accordingly.
    vpc_Configuration = nil
    vpc_Configuration = { subnet_ids: vpc_subnet_ids, security_group_ids: vpc_security_group_ids } unless (vpc_subnet_ids.empty? && vpc_security_group_ids.empty?)

    # if we cannot find it, we have to create it instead of updating it
    func_config = @client.create_function(
      function_name: function_name, runtime: 'nodejs4.3', role: lambda_role,
      handler: handler, code: { s3_bucket: bucket, s3_key: key }, timeout: 5, memory_size: 128, publish: true,
      description: lambda_description,
      vpc_config: vpc_Configuration
    ).data
    puts func_config
    func_version = func_config.version
    raise "Error while publishing new lambda function #{function_name}" unless func_version
  end

  add_api_gateway_permissions(function_name, nil)

  func_version
end

#package(directory, zipfile, input_filenames, node_modules) ⇒ Object

Packages a set of files and node modules into a deployable package.

Arguments

directory

A temporary directory to copy all related files before they are packages into a single zip file.

zipfile

A path where the deployable package, a zip file, should be stored.

input_filenames

A list of file names that contain the source code.

node_modules

A list of node modules that need to be included in the package.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/lambda_wrap/lambda_manager.rb', line 26

def package(directory, zipfile, input_filenames, node_modules)
  FileUtils.mkdir_p directory
  FileUtils.mkdir_p File.join(directory, 'node_modules')

  input_filenames.each do |filename|
    FileUtils.copy_file(File.join(filename), File.join(directory, File.basename(filename)))
  end

  node_modules.each do |dir|
    FileUtils.cp_r(File.join('node_modules', dir), File.join(directory, 'node_modules'))
  end

  ZipFileGenerator.new(directory, zipfile).write
end

#publish_lambda_to_s3(local_lambda_file, bucket, key) ⇒ Object

Publishes a package to S3 so it can be deployed as a lambda function.

Arguments

local_lambda_file

The location of the package that needs to be deployed.

bucket

The s3 bucket where the file needs to be uploaded to.

key

The S3 path (key) where the package should be stored.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/lambda_wrap/lambda_manager.rb', line 48

def publish_lambda_to_s3(local_lambda_file, bucket, key)
  # get s3 object
  s3 = Aws::S3::Resource.new
  obj = s3.bucket(bucket).object(key)

  # upload
  version_id = nil
  File.open(local_lambda_file, 'rb') do |file|
    version_id = obj.put(body: file).version_id
  end
  raise 'Upload to S3 failed' unless version_id

  puts 'Uploaded object to S3 with version ' + version_id
  version_id
end

#remove_alias(function_name, alias_name) ⇒ Object

Removes an alias for a function.

Arguments

function_name

The lambda function name for which the alias should be removed.

alias_name

The alias to remove.



145
146
147
# File 'lib/lambda_wrap/lambda_manager.rb', line 145

def remove_alias(function_name, alias_name)
  @client.delete_alias(function_name: function_name, name: alias_name)
end