AWS Lambda上的权限问题,无法产生subprocess

所以我创造了这个漂亮的小lambda,在当地运行很好,但是在野外实际上没有那么多。

lambda需要事件,在事件源中使用html,将该html转换为PDF(使用html-pdf节点模块),将该pdf传递给s3存储桶,然后将签名的URL返回,过期时间为60秒。

或者至less这是应该发生的(再次,在本地工作)。 在Lambda上进行testing时,出现以下错误:

{ "errorMessage": "spawn EACCES", "errorType": "Error", "stackTrace": [ "exports._errnoException (util.js:870:11)", "ChildProcess.spawn (internal/child_process.js:298:11)", "Object.exports.spawn (child_process.js:362:9)", "PDF.PdfExec [as exec] (/var/task/node_modules/html-pdf/lib/pdf.js:87:28)", "PDF.PdfToFile [as toFile] (/var/task/node_modules/html-pdf/lib/pdf.js:83:8)", "/var/task/index.js:72:43", "Promise._execute (/var/task/node_modules/bluebird/js/release/debuggability.js:272:9)", "Promise._resolveFromExecutor (/var/task/node_modules/bluebird/js/release/promise.js:473:18)", "new Promise (/var/task/node_modules/bluebird/js/release/promise.js:77:14)", "createPDF (/var/task/index.js:71:19)", "main (/var/task/index.js:50:5)" ] } 

这里是代码本身(不编译,有一个方便的一口气任务)

 if(typeof regeneratorRuntime === 'undefined') { require("babel/polyfill") } import fs from 'fs' import pdf from 'html-pdf' import md5 from 'md5' import AWS from 'aws-sdk' import Promise from 'bluebird' import moment from 'moment' const tempDir = '/tmp' const config = require('./config') const s3 = new AWS.S3() export const main = (event, context) => { console.log("Got event: ", event) AWS.config.update({ accessKeyId: config.awsKey, secretAccessKey: config.awsSecret, region: 'us-east-1' }) const filename = md5(event.html) + ".pdf" createPDF(event.html, filename).then(function(result) { uploadToS3(filename, result.filename).then(function(result) { getOneTimeUrl(filename).then(function(result) { return context.succeed(result) }, function(err) { console.log(err) return context.fail(err) }) }, function(err) { console.log(err) return context.fail(err) }) }, function(err) { console.log(err) return context.fail(err) }) } const createPDF = (html, filename) => { console.log("Creating PDF") var promise = new Promise(function(resolve, reject) { pdf.create(html).toFile(filename, function(err, res) { if (err) { reject(err) } else { resolve(res) } }) }) return promise } const uploadToS3 = (filename, filePath) => { console.log("Pushing to S3") var promise = new Promise(function(resolve, reject) { var fileToUpload = fs.createReadStream(filePath) var expiryDate = moment().add(1, 'm').toDate() var uploadParams = { Bucket: config.pdfBucket, Key: filename, Body: fileToUpload } s3.upload(uploadParams, function(err, data) { if(err) { reject(err) } else { resolve(data) } }) }) return promise } const getOneTimeUrl = (filename) => { var promise = new Promise(function(resolve, reject) { var params = { Bucket: config.pdfBucket, Key: filename, Expires: 60 } s3.getSignedUrl('getObject', params, function(err, url) { if (err) { reject(err) } else { resolve(url) } }) }) return promise } 

看起来像在html-pdf中的问题。 我认为这可能是PhantomJS(html-pdf取决于)的一个问题,因为我在这里做了一些阅读: https : //engineering.fundingcircle.com/blog/2015/04/09/aws-lambda-for-great – 胜利/ ,但是,因为Lambda已经撞到了最大的zip大小为50MB,我没有上传二进制文件的问题。

有什么想法吗?

html-pdf使用引擎盖下的phantomjs ,安装时需要编译一些二进制文件。 我想你的问题是你正在部署这些本地编译的二进制文件,但是Lambda需要在Amazon Linux上编译的二进制文件。

您可以通过在运行Amazon Linux的EC2实例上构build部署包来解决这个问题,然后像在本教程中解释的那样直接从那里直接部署它。

也检查出类似的问题这个答案 。