I try to deploy simple Nuxt 3 application to AWS Lambda for SSR. So far I have:
in nitro.config.ts
import { defineNitroConfig } from 'nitropack';
export default defineNitroConfig({
preset: 'aws-lambda',
serveStatic: true
});
in Lambda handler
import { handler } from './output/server/index.mjs';
export const runner = (event, context) => {
const { statusCode, headers, body } = handler({ rawPath: '/' });
return {
statusCode,
body,
headers
}
}
in serverless.yaml
functions:
ssr:
handler: handler.runner
timeout: 15
package:
individually: true
include:
- output/**
events:
- httpApi:
path: '*'
method: '*'
I run yarn build, change .output folder name to output to be able to include it with package, but I still have errors like "errorMessage": "SyntaxError: Cannot use import statement outside a module".
Is someone has idea how it could be done?
Its easier than that bro, nuxt already exports the handler nothing for us to do:
serverles.yml:
service: nuxt-app-lamba
provider:
name: aws
runtime: nodejs14.x
stage: dev
region: us-east-1
functions:
nuxt:
handler: .output/server/index.handler
events:
- httpApi: '*'
nuxt.config.ts:
// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
nitro: {
preset: 'aws-lambda',
serveStatic: true
}
})
package.json:
{
"private": true,
"scripts": {
"build": "nuxt build",
"build:lamba": "NITRO_PRESET=aws-lambda nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare",
"deploy": "sls deploy"
},
"devDependencies": {
"nuxt": "3.0.0-rc.11"
}
}
This example is not working anymore (2022.12.09):
Working example: https://8cyysz2g5f.execute-api.us-east-1.amazonaws.com/
Related
I'm building a CDK Pipeline that with update another CDK template.
This CDK template is a static frontend react app.
The backend uses an AWS Lambda, API Gateway, and CloudFront Distribution to host the site.
I want to put the api's in the config.json file as I normally would if I were building it manually one service at a time.
The problem seems to be in the cdk pipeline-stack, which builds the static-frontend-stack.
When you initialize a new pipeline, it wants you to add shell steps first, (npm i, cd into correct folder, npm run build, etc) which creates the distribution folder I need.
As well as turning the whole thing into a CF template.
Then you can drop that into different stages you want, e.g., test and prod.
However, I won't receive CfnOutputs until the stages are built. And the CfnOutputs hold the api's and other info I need to put into the config.json file (which was already built first, and created empty values).
There is even a envFromCfnOutputs param to add to the initial codebuild pipeline, but since they are initialized/created later, typescript yells at me for putting it in there before. I understand why that errors, but I can't figure a clever way to fix this issue.
import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import * as pipelines from "aws-cdk-lib/pipelines";
import * as codecommit from "aws-cdk-lib/aws-codecommit";
import { Stages } from "./stages";
import { Stack, Stage } from "aws-cdk-lib";
interface PipelineStackProps extends cdk.StackProps {
env: {
account: string;
region: string;
stage: string;
};
}
export class PipelineStack extends cdk.Stack {
constructor(scope: Construct, id: string, props: PipelineStackProps) {
super(scope, id, props);
/************ Grab Repo ************/
const source = codecommit.Repository.fromRepositoryName(
this,
"PreCallbackSMSSolution",
"PreCallbackSMSSolution"
);
/************ Define Pipeline & Build ShellStep (for Frontend) ************/
const Pipeline = new pipelines.CodePipeline(this, "Pipeline", {
pipelineName: `CodePipeline`,
selfMutation: true,
crossAccountKeys: true,
synthCodeBuildDefaults: {
rolePolicy: [
// #desc Policy to allow CodeBuild to use CodeArtifact
// #external https://docs.aws.amazon.com/codeartifact/latest/ug/using-npm-packages-in-codebuild.html
new cdk.aws_iam.PolicyStatement({
actions: [
"codeartifact:GetAuthorizationToken",
"codeartifact:GetRepositoryEndpoint",
"codeartifact:ReadFromRepository",
],
resources: ["*"],
}),
new cdk.aws_iam.PolicyStatement({
actions: ["sts:GetServiceBearerToken"],
resources: ["*"],
conditions: {
StringEquals: {
"sts:AWSServiceName": "codeartifact.amazonaws.com",
},
},
}),
],
},
synth: new pipelines.ShellStep("Synth", {
input: pipelines.CodePipelineSource.codeCommit(source, "master"),
installCommands: [
"cd $CODEBUILD_SRC_DIR/deployment",
"npm install -g typescript",
"npm run co:login",
"npm i",
],
env: {
stage: props.env.stage,
},
envFromCfnOutputs: {
// TODO: cfn outputs need to go here!
// CcpUrlOutput: TestStage.CcpUrlOutput,
// loginUrlOutput: TestStage.LoginUrlOutput,
// regionOutput: TestStage.RegionOutput,
// apiOutput: TestStage.ApiOutput
},
commands: [
"cd $CODEBUILD_SRC_DIR/frontend",
"pwd",
"apt-get install jq -y",
"chmod +x ./generate-config.sh",
"npm i",
"npm run build-prod",
"pwd",
"cat ./src/config-prod.json",
"cd ../deployment",
"npx cdk synth",
],
primaryOutputDirectory: "$CODEBUILD_SRC_DIR/deployment/cdk.out", // $CODEBUILD_SRC_DIR = starts root path
}),
});
/************ Initialize Test Stack & Add Stage************/
const TestStage = new Stages(this, "TestStage", {
env: { account: "***********", region: "us-east-1", stage: "test" },
}); // Aspen Sandbox
Pipeline.addStage(TestStage);
/************ Initialize Prod Stack & Add Stage ************/
const ProdStage = new Stages(this, "ProdStage", {
env: { account: "***********", region: "us-east-1", stage: "prod" },
}); // Aspen Sandbox
Pipeline.addStage(ProdStage);
/************ Build Pipeline ************/
Pipeline.buildPipeline();
/************ Manual Approve Stage ************/
const ApproveStage = Pipeline.pipeline.addStage({
stageName: "PromoteToProd",
placement: {
justAfter: Pipeline.pipeline.stage("TestStage"),
},
});
ApproveStage.addAction(
new cdk.aws_codepipeline_actions.ManualApprovalAction({
actionName: "Approve",
additionalInformation: "Approve this deployment for production.",
})
);
}
/****/
}
I am deploying on amazon using CI/CD pipeline using Github action.Deployed on Amazon successfully but when I run the graphql query on appsync it show that the #aws-sdk/client-dynamodb not found.
You can see the error on this image
succesfully deployed on github
I add dynamodb package on package.json
`{
"name": "Serverless-apix",
"type": "module",
"version": "1.0.0",
"description": "",
"scripts": {
"start": "sls offline start --stage local",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"#aws-sdk/client-dynamodb": "^3.215.0",
"ramda": "^0.28.0",
"serverless": "^3.24.1",
"serverless-appsync-plugin": "^1.14.0",
"serverless-iam-roles-per-function": "^3.2.0"
},
"devDependencies": {}
}`
Controller Where I call the Dynamodb
`import { PutItemCommand } from "#aws-sdk/client-dynamodb";
import { ddbClient } from "../../dynamodb/db.js";`
Db file
`import { DynamoDBClient } from "#aws-sdk/client-dynamodb";
const REGION = "us-east-1"; //e.g. "us-east-1"
// const client = new DynamoDBClient({
// // region: "us-east-1",
// // accessKeyId: "AKIA272VV64HPNKION2R",
// // secretAccessKeyId: "7IARIpa5q8ZEf0NQKKsUPTDP+oszFaw+Dd5v4s7N",
// // endpoint: "http://localhost:8000"
// region: 'localhost',
// endpoint: 'http://localhost:8000'
// });
const ddbClient = new DynamoDBClient({ region: REGION });
export { ddbClient };å`
Serverless file
`service: image-base-serverless-api
provider:
name: aws
runtime: nodejs14.x
stage: ${opt:stage, 'dev'}
region: us-east-1
environment:
# DYNAMODB_TABLE_NAME: ${self:custom.usersTableName}
STAGE: ${self:provider.stage}
REGION: ${self:provider.region}
APPSYNC_NAME: "${self:custom.defaultPrefix}-appsync"
SERVICE_NAME: ${self:service}-${self:provider.stage}
DYNAMODB: ${self:service}-${self:provider.stage}
TABLE_NAME:
Ref: usersTable
iam:
role:
statements: # permissions for all of your functions can be set here
- Effect: Allow
Action: # Gives permission to DynamoDB tables in a specific region
- dynamodb:*
- lambda:*
- s3:*
Resource:
- arn:aws:dynamodb:${self:provider.region}:*:*
- arn:aws:lambda:${self:provider.region}:*:*
- "Fn::GetAtt": [usersTable, Arn]
plugins: ${file(plugins/plugins-${self:provider.stage}.yml)}
package:
exclude:
- node_modules/**
- venv/**
custom:
usersTableName: users-table-${self:provider.stage}
dynamodb:
stages:
- local
start:
port: 8000
inMemory: false
dbPath: "dynamodb_local_data"
migrate: true
appSync:
name: image-base-serverless-backened-api-${self:provider.stage}
schema: schema.graphql
authenticationType: API_KEY
serviceRole: "AppSyncServiceRole"
mappingTemplates: ${file(appsync/mappingtemplate.yml)}
dataSources: ${file(appsync/datasource.yml)}
appsync-offline: # appsync-offline configuration
port: 62222
dynamodb:
client:
endpoint: "http://localhost:8000"
region: localhost
defaultPrefix: ${self:service}-${self:provider.stage}
functions:
- ${file(src/adminusers/admin-user-route.yml)}
resources:
# Roles
- ${file(resources/roles.yml)}
# DynamoDB tables
- ${file(resources/dynamodb-tables.yml)}
# - ${file(resources/dynamodb.yml)}
# - ${file(resources/iam.yml)}
`
I Shall be very thankfull if you help me to solve this error
I downgrade the node version and also try deploy the amazon directly and also deploy the code using CI/CD pipeline but its show the same error on each tried.I have
i am trying to use aws ecr for my serverless application but i am failing to do so,
my main problem is the 50mb upload limit lambda has, and this is the config in my serverless (i am not sure if it is correct since there is not lots of documentation about it online)
(i am using aws-nodejs-typescript template)
addFriend is the function that i am trying to build with docker.
this is my Dockerfile
FROM public.ecr.aws/lambda/nodejs:14 as builder
WORKDIR /usr/app
COPY package.json handler.ts ./
RUN npm install
RUN npm run build
FROM public.ecr.aws/lambda/nodejs:14
WORKDIR ${LAMBDA_TASK_ROOT}
COPY --from=builder /usr/app/dist/* ./
CMD ["handler.main"]
and my serverless.ts
const serverlessConfiguration: AWS = {
...
custom: {
esbuild: {
bundle: true,
minify: false,
sourcemap: true,
exclude: ['aws-sdk'],
target: 'node14',
define: { 'require.resolve': undefined },
platform: 'node',
},
...
},
plugins: ['serverless-esbuild'],
provider: {
name: 'aws',
runtime: 'nodejs14.x',
profile: <PROFILE>,
region: 'us-east-1',
stage: 'dev',
apiGateway: {
minimumCompressionSize: 1024,
shouldStartNameWithService: true,
},
iamRoleStatements: [
{
Effect: 'Allow',
Action: ['s3:*', 'sns:*'],
Resource: '*',
},
],
ecr: {
images: {
addfriendfunction: {
path: './src/functions/addFriend',
},
},
},
lambdaHashingVersion: '20201221',
},
functions: {
...
addPushToken,
addFriend: {
image: {
name: 'addfriendfunction',
},
events: [
{
http: {
method: 'get',
path: 'api/v1/add-friend',
},
},
],
},
the error in the console is:
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type
string. Received undefined
i am stuck with this issue unable to continue working, is there any solution for this with serverless framework?
Follow this guide for nodejs.
Can you try copy js code. For example something like: .esbuild/.build/src/functions/addFriend/handler.js instead of this step:
COPY package.json handler.ts ./
I have my serverless.yml like below
service: omy-api
provider:
name: aws
runtime: nodejs14.x
region: ${opt:region, 'us-east-1'}
stage: ${opt:stage, 'devint'}
memorySize: 128
timeout: 15
custom:
jest:
collectCoverage: true
functions:
- ${file(config/Customer/delete.yml)}
plugins:
- serverless-jest-plugin
in my package.json I have
{
"name": "omy-api",
"version": "1.0.0",
"scripts": {
"deploy": "sls deploy",
"test": "jest"
},
"jest": {
"collectCoverage": true,
"coverageReporters": ["text-summary"],
"coverageThreshold": {
"global": {
"branches": 90,
"functions": 90,
"lines": 90,
"statements": -10
}
}
},
"author": "",
"license": "ISC",
"devDependencies": {
"serverless": "^1.83.3",
"serverless-jest-plugin": "^0.3.0",
},
"dependencies": {
"jest": "^27.0.6"
}
}
am following the https://github.com/nordcloud/serverless-jest-plugin documentation.
when i run sls invoke test, I get the error
Serverless Error ----------------------------------------
Serverless command "invoke test" not found. Run "serverless help" for a list of all available commands.
I tried sls invoke test --help, but I get the same error.
If you want to run it by entering a command like below, you must first install serverless and the serverless plugins you use globally, for example
npm install -g serverless
npm install -g serverless-jest-plugin
and run
sls invoke test
I have some strange errors and I can not find out the reason, can you help me?
...
Serverless: Warning: Unable to find plugin named: TypeScriptPlugin
Serverless: Configuration error at root: unrecognized property 'stepFunctions'
...
serverless.yml
service:
name: service-name
plugins:
- serverless-localstack
- serverless-step-functions
- serverless-pseudo-parameters
- serverless-webpack
custom:
webpackIncludeModules: true
localstack:
stages:
- local
host: http://localhost
edgePort: 4566
autostart: true
lambda:
mountCode: false
debug: true
docker:
sudo: true
provider:
configValidationMode: off
deploymentBucket:
name: local
name: aws
runtime: nodejs12.x
stage: ${opt:stage, "dev"}
region: ${env:AWS_REGION, "us-east-1"}
logRetentionInDays: 30
functions:
...
stepFunctions:
...
package.json
{
"name": "service-name",
"version": "0.119.0",
"description": "Service decription.",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"devDependencies": {
"#babel/plugin-transform-runtime": "^7.2.0",
"babel-core": "^6.26.0",
"babel-loader": "^8.0.5",
"babel-plugin-source-map-support": "^2.0.1",
"babel-preset-env": "^1.6.1",
"serverless": "^1.40.0",
"serverless-localstack": "^0.4.27",
"serverless-pseudo-parameters": "^1.4.2",
"serverless-step-functions": "^1.11.0",
"serverless-webpack": "^4.4.0",
"webpack": "^3.11.0",
"webpack-node-externals": "^1.6.0"
},
"dependencies": {
"babel-runtime": "^6.26.0",
"source-map-support": "^0.5.9"
}
}
This is just a bug with the package serverless-step-functions
This can be resolved by updating the library :)
"serverless-step-functions": "^2.23.x",