I have a single Lambda function which is very small and has few npm dependencies and yet when I try and deploy I get the following:
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (85.9 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - representative-truth-services-dev
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleStateMachineExecution
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - StateInfoLogGroup
CloudFormation - UPDATE_IN_PROGRESS - AWS::S3::Bucket - ServerlessDeploymentBucket
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleStateMachineExecution
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - StateInfoLogGroup
CloudFormation - CREATE_COMPLETE - AWS::Logs::LogGroup - StateInfoLogGroup
CloudFormation - CREATE_COMPLETE - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - CREATE_COMPLETE - AWS::IAM::Role - IamRoleStateMachineExecution
CloudFormation - UPDATE_COMPLETE - AWS::S3::Bucket - ServerlessDeploymentBucket
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - StateInfoLambdaFunction
CloudFormation - CREATE_FAILED - AWS::Lambda::Function - StateInfoLambdaFunction
CloudFormation - UPDATE_ROLLBACK_IN_PROGRESS - AWS::CloudFormation::Stack - representative-truth-services-dev
CloudFormation - UPDATE_IN_PROGRESS - AWS::S3::Bucket - ServerlessDeploymentBucket
CloudFormation - UPDATE_COMPLETE - AWS::S3::Bucket - ServerlessDeploymentBucket
CloudFormation - UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - representative-truth-services-dev
CloudFormation - DELETE_COMPLETE - AWS::Lambda::Function - StateInfoLambdaFunction
CloudFormation - DELETE_IN_PROGRESS - AWS::IAM::Role - IamRoleStateMachineExecution
CloudFormation - DELETE_COMPLETE - AWS::IAM::Role - IamRoleStateMachineExecution
CloudFormation - DELETE_IN_PROGRESS - AWS::Logs::LogGroup - StateInfoLogGroup
CloudFormation - DELETE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - DELETE_COMPLETE - AWS::Logs::LogGroup - StateInfoLogGroup
CloudFormation - DELETE_COMPLETE - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - UPDATE_ROLLBACK_COMPLETE - AWS::CloudFormation::Stack - representative-truth-services-dev
Serverless: Operation failed!
The serverless error from this is:
An error occurred: StateInfoLambdaFunction - Unzipped size must be smaller than 262144000 bytes.
How can this be? For reference the function I’m uploading is:
import {
IDictionary,
AWSGatewayCallback,
IAWSGatewayRequest,
IAWSGatewayResponse
} from "common-types";
import GetStateInfo from "./vote-smart/get-state-info";
import { Lambda } from "aws-sdk";
import { STATES } from "./models/shared";
import DB from "abstracted-admin";
import { StateInfo } from "./models/StateInfo";
import { IApiResponse } from "./shared/ApiRetriever";
let _db: DB;
export const db = (setter?: DB) => {
if (setter) {
_db = setter;
} else {
if (!_db) {
_db = new DB();
}
return _db;
}
};
/**
* Cycles through all states, asynchronously firing off a lambda function for
* each. These worker functions will in turn update the Firebase DB for the given
* state they are responsible for.
*
* @param event Event parameters passed down from AWS Gateway
* @param context AWS params giving context to the execution
* @param cb A callback function to call on exit or error
*/
export const handler = (
event: IDictionary,
context: IAWSGatewayRequest,
cb: AWSGatewayCallback
) => {
const lambda = new Lambda({ region: "us-east" });
const states: string[] = event.states || [];
if (states.length === 0) {
cb(403, { statusCode: 403, error: "no states found in event" });
return;
}
(async () => {
const promises: Array<Promise<any>> = [];
const errors: any[] = [];
states.forEach((state: keyof typeof STATES) => {
promises.push(processState(state, errors));
});
const result = await Promise.all(promises);
cb(null, {
statusCode: 200,
body: JSON.stringify({
messsage: `State Info retrieved for ${
states.length
} states: ${states.join(", ")}`,
processed: states.length - errors.length,
failed: errors.length,
errors
})
});
})();
};
async function processState(state: keyof typeof STATES, errors: any[]) {
const api = new GetStateInfo().setState(state);
const result: any = await api
.getMapped()
.catch(err => errors.push({ state, err }));
return typeof result === "object"
? db().set<StateInfo>(`/reference/states/${state}`, result)
: Promise.resolve();
}
it would be impractical for me include all the little files this refers to be please believe me it is rather minor. That said, I have not yet switched to a per function dependency configuration (I know you can do this but couldn’t find it yet in the docs). As a result there are a few more npm deps that are being brought in as you can see in the package.json
:
{
"name": "representative-truth-services",
"version": "0.0.0",
"description": "representative-truth-services",
"license": "private",
"repository": "",
"author": "",
"keywords": [
"serverless",
"typescript"
],
"files": [
"lib"
],
"main": "lib/index.js",
"typings": "lib/index.d.ts",
"scripts": {
"clean": "rimraf lib",
"lint": "tslint --force --format verbose \"src/**/*.ts\"",
"build": "ts-node ./scripts/build.ts",
"run": "ts-node ./scripts/run.ts | ts-node ",
"test": "ts-node ./scripts/test.ts ",
"coverage": "nyc --reporter=text --reporter=html mocha --compilers ts:ts-node/register",
"watch": "ts-node ./scripts/watch.ts",
"deploy": "ts-node ./scripts/deploy.ts",
"watch:test": "ts-node ./scripts/watch.ts test",
"watch:all": "ts-node ./scripts/watch.ts all",
"cli": "ts-node cli/index.ts --"
},
"dependencies": {
"abstracted-admin": "^0.2.10",
"aws-sdk": "^2.162.0",
"axios": "^0.17.1",
"cheerio": "^1.0.0-rc.2",
"common-types": "~1.3.10",
"entities": "^1.1.1",
"firemodel": "^0.1.5",
"html2plaintext": "^1.1.1",
"moment": "^2.0.0",
"natural": "^0.5.4",
"sentiment": "^4.1.0",
"xml2js": "^0.4.19"
},
"devDependencies": {
"@types/chai": "^3.0.0",
"@types/chance": "^0.7.33",
"@types/cheerio": "^0.22.6",
"@types/entities": "^1.1.0",
"@types/faker": "^4.1.0",
"@types/js-yaml": "^3.9.0",
"@types/lodash": "^4.0.0",
"@types/mocha": "^2.2.41",
"@types/natural": "^0.2.33",
"@types/node": "^6.0.0",
"@types/rimraf": "^0.0.28",
"@types/shelljs": "^0.7.1",
"@types/stack-trace": "^0.0.28",
"@types/xml2js": "^0.4.2",
"chai": "^4.0.0",
"chalk": "^2.3.0",
"chance": "^1.0.0",
"coveralls": "^2.0.0",
"faker": "^4.1.0",
"js-yaml": "^3.0.0",
"lodash": "^4.17.4",
"mocha": "^3.4.0",
"nyc": "^11.0.0",
"prettier": "^1.5.2",
"rimraf": "^2.0.0",
"serverless": "^1.24.1",
"serverless-step-functions": "^1.3.0",
"shelljs": "^0.7.0",
"test-console": "^1.0.0",
"ts-node": "^3.3.0",
"tslint": "^5.0.0",
"tslint-config-prettier": "^1.1.0",
"typescript": "^2.7.0-dev.20171203"
},
"engines": {
"node": ">=6.0.0"
}
}