結局は…

  • ドキュメントよく読めってことだった

経緯

環境

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.11.6
BuildVersion:   15G1217

$ bundle exec ruby -v
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin15]

$ bundle exec gem list | grep aws
aws-sdk (2.7.11)
aws-sdk-core (2.7.11)
aws-sdk-resources (2.7.11)
aws-sigv4 (1.0.0)

やりたいこと

ローカルの zip ファイルをアップロードしたい。

  • /path/to/zipfile.zip

ドキュメントには

update_function_code のサンプルには以下のように書かれている。

resp = client.update_function_code({
  function_name: "myFunction", 
  publish: true, 
  s3_bucket: "myBucket", 
  s3_key: "myKey", 
  s3_object_version: "1", 
  zip_file: "fileb://file-path/file.zip", 
})

オプションの zip_file: の説明は以下のように書かれていたりしたので…(IO, String と書かれている時点で気付くべきだった…)

:zip_file (IO, String) — .zip file containing your packaged source code.

なるほど、ファイルのパスを渡せばいいのね。

ところが…

Aws::Lambda::Errors::InvalidParameterValueException: Could not unzip uploaded file. Please check your file, then try to upload again.

なんでだろう。

解決

一つの issue

以下の issue がヒントをくれた。

https://github.com/aws/aws-sdk-ruby/issues/942

この issue 自体はドキュメントの誤り(zip ファイルって Base64 エンコードする必要あるの?、ないの?)を指摘するものだが、コメントを付けていた pchaganti 氏曰く、

ボクらは IO.read(path_to_zip) を使っているよ

ほう。そうなんや。

ということで

以下のように書くことで無事に zip ファイルをアップロードすることが出来ましたとさ。

def update_function_code(function_name, zip_file_path)
  client = Aws::Lambda::Client.new(region: 'ap-northeast-1', profile: ENV['_AWS_PROFILE'])
  zip_file = IO.read(zip_file_path)
  res = client.update_function_code({
    function_name: function_name,
    zip_file: zip_file
  })
end

以上

 

メモ

でした。

参考

元記事はこちら

AWS SDK for Ruby から Lambda の update_function_code を叩く時にハマったこと