NextJs Application is working perfectly fine locally but after pushing the fronted to AWS I'm getting the run time error, No Credentials in callback.js api
No Build time error, so I assume aws-exports.js file is built correctly during the build but I don't know if it is built with the required details like API key on AWS.
I'm using API key authentication by default. I'm not using amplify add auth because I've a requirement to use custom auth. I know amplify auth is the recommend way but I still need to use my custom method.
I have already tried multiple suggestions like disable Analytics: true as suggested in couple of other discussions but none of them worked for me. Build my project multiple times from scratch by re-installing all the dependencies but no luck.
callback.js API
import { API, graphqlOperation } from 'aws-amplify';
import {getAuth} from "../../../../src/graphql/queries"
import {createAuth} from "../../../../src/graphql/mutations"
export default async function callback(req, res) {
const record = await API.graphql(graphqlOperation(getAuth, {emailId: "abc#gmail.com"}))
res.status(200).json({ record });
}
aws-exports.js
/* eslint-disable */
// WARNING: DO NOT EDIT. This file is automatically generated by AWS Amplify. It will be overwritten.
const awsmobile = {
"aws_project_region": "us-east-1",
"aws_appsync_graphqlEndpoint": "https://dummyUrl.appsync-api.us-east-1.amazonaws.com/graphql",
"aws_appsync_region": "us-east-1",
"aws_appsync_authenticationType": "API_KEY",
"aws_appsync_apiKey": "da2-************"
};
export default awsmobile;
_app.js
import {Amplify} from 'aws-amplify';
import config from "../aws-exports"
Amplify.configure(config)
function MyApp({ Component, pageProps: { session, ...pageProps } }) {
// App logic
})
GraphQL Schema
type Auth #model #auth(rules: [{ allow: public }]) {
emailId: ID! #primaryKey
name: String
screen_name: String
profile_img: String
userSession: String
tokenType: String
accessToken: String
accessSecret: String
refreshToken: String
accessScope: String
}
Package.json
"dependencies": {
"#emoji-mart/data": "^1.0.6",
"#emoji-mart/react": "^1.0.1",
"aes256": "^1.1.0",
"aws-amplify": "^4.3.37",
"emoji-mart": "^5.2.2",
"formidable": "^2.0.1",
"js-cookie": "^3.0.1",
"next": "12.3.1",
"react": "18.2.0",
"react-datepicker": "^4.8.0",
"react-dom": "18.2.0",
},
Amplify.yml
version: 1
backend:
phases:
build:
commands:
- '# Execute Amplify CLI with the helper script'
- amplifyPush --simple
frontend:
phases:
preBuild:
commands:
- yarn install
build:
commands:
- yarn run build
artifacts:
baseDirectory: .next
files:
- '**/*'
cache:
paths:
- node_modules/**/*
Edited
I've found how the server side process work with amplify and graphql. Please refer to this. On the server side, you need to pass the API KEY explicitly into the graphql request as that page writes.
==========
I'm using appsync, but appsync pure directives. So just let me provide the reference below. Please confirm the rule follows this way.
{ allow: public, provider: apiKey }
I'm trying to use CDK and CodePipeline to build and deploy a React application to S3. After the CodePipeline phase, in my own stack, I defined the S3 bucket like this:
const bucket = new Bucket(this, "Bucket", {
websiteIndexDocument: "index.html",
websiteErrorDocument: "error.html",
})
which worked. And then I defined the deployment of my built React app like this:
new BucketDeployment(this, "WebsiteDeployment", {
sources: [Source.asset("./")],
destinationBucket: bucket
})
which doesn't seem to work. Is that use of BucketDeployment correct?
Something odd that happens when I add the BucketDeployment lines is that cdk synth or cdk deploy, they never finish and they seem to generate an infinite recursive tree in cdk.out, so something definitely seems wrong there.
And if I change to Source.asset("./build") I get the error:
> cdk synth
C:\Users\pupeno\Code\ww3fe\node_modules\aws-cdk-lib\core\lib\asset-staging.ts:109
throw new Error(`Cannot find asset at ${this.sourcePath}`);
^
Error: Cannot find asset at C:\Users\pupeno\Code\ww3fe\build
at new AssetStaging (C:\Users\pupeno\Code\ww3fe\node_modules\aws-cdk-lib\core\lib\asset-staging.ts:109:13)
at new Asset (C:\Users\pupeno\Code\ww3fe\node_modules\aws-cdk-lib\aws-s3-assets\lib\asset.ts:72:21)
at Object.bind (C:\Users\pupeno\Code\ww3fe\node_modules\aws-cdk-lib\aws-s3-deployment\lib\source.ts:55:23)
at C:\Users\pupeno\Code\ww3fe\node_modules\aws-cdk-lib\aws-s3-deployment\lib\bucket-deployment.ts:170:83
at Array.map (<anonymous>)
at new BucketDeployment (C:\Users\pupeno\Code\ww3fe\node_modules\aws-cdk-lib\aws-s3-deployment\lib\bucket-deployment.ts:170:51)
at new MainStack (C:\Users\pupeno\Code\ww3fe\infra\pipeline-stack.ts:16:9)
at new DeployStage (C:\Users\pupeno\Code\ww3fe\infra\pipeline-stack.ts:28:26)
at new PipelineStack (C:\Users\pupeno\Code\ww3fe\infra\pipeline-stack.ts:56:24)
at Object.<anonymous> (C:\Users\pupeno\Code\ww3fe\infra\pipeline.ts:6:1)
Subprocess exited with error 1
which would indicate this is very wrong. Why is it searching for the build directory on my machine? It's supposed to search for it in CodePipeline, after building.
My whole pipeline is:
import {Construct} from "constructs"
import {CodeBuildStep, CodePipeline, CodePipelineSource} from "aws-cdk-lib/pipelines"
import {Stage, CfnOutput, StageProps, Stack, StackProps} from "aws-cdk-lib"
import {Bucket} from "aws-cdk-lib/aws-s3"
import {BucketDeployment, Source} from "aws-cdk-lib/aws-s3-deployment"
export class MainStack extends Stack {
constructor(scope: Construct, id: string, props?: StageProps) {
super(scope, id, props)
const bucket = new Bucket(this, "Bucket", {
websiteIndexDocument: "index.html",
websiteErrorDocument: "error.html",
})
new BucketDeployment(this, "WebsiteDeployment", {
sources: [Source.asset("./")],
destinationBucket: bucket
})
new CfnOutput(this, "BucketOutput", {value: bucket.bucketArn})
}
}
export class DeployStage extends Stage {
public readonly mainStack: MainStack
constructor(scope: Construct, id: string, props?: StageProps) {
super(scope, id, props)
this.mainStack = new MainStack(this, "example")
}
}
export class PipelineStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props)
const pipeline = new CodePipeline(this, id, {
pipelineName: id,
synth: new CodeBuildStep("Synth", {
input: CodePipelineSource.connection("user/example", "main", {
connectionArn: "arn:aws:codestar-connections:....",
}),
installCommands: [
"npm install -g aws-cdk"
],
commands: [
"npm ci",
"npm run build",
"npx cdk synth"
]
}
),
})
const deploy = new DeployStage(this, "Staging")
const deployStage = pipeline.addStage(deploy)
}
}
The actual error I'm experiencing in AWS is this:
[Container] 2022/01/25 20:28:27 Phase complete: BUILD State: SUCCEEDED
[Container] 2022/01/25 20:28:27 Phase context status code: Message:
[Container] 2022/01/25 20:28:27 Entering phase POST_BUILD
[Container] 2022/01/25 20:28:27 Phase complete: POST_BUILD State: SUCCEEDED
[Container] 2022/01/25 20:28:27 Phase context status code: Message:
[Container] 2022/01/25 20:28:27 Expanding base directory path: cdk.out
[Container] 2022/01/25 20:28:27 Assembling file list
[Container] 2022/01/25 20:28:27 Expanding cdk.out
[Container] 2022/01/25 20:28:27 Skipping invalid file path cdk.out
[Container] 2022/01/25 20:28:27 Phase complete: UPLOAD_ARTIFACTS State: FAILED
[Container] 2022/01/25 20:28:27 Phase context status code: CLIENT_ERROR Message: no matching base directory path found for cdk.out
In case it matters, by cdk.json, in the root of my repo, contains:
{
"app": "npx ts-node --project infra/tsconfig.json --prefer-ts-exts infra/pipeline.ts",
"watch": {
"include": [
"**"
],
"exclude": [
"README.md",
"cdk*.json",
"**/*.d.ts",
"**/*.js",
"tsconfig.json",
"package*.json",
"yarn.lock",
"node_modules",
"test"
]
},
"context": {
"#aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true,
"#aws-cdk/core:stackRelativeExports": true,
"#aws-cdk/aws-rds:lowercaseDbIdentifier": true,
"#aws-cdk/aws-lambda:recognizeVersionProps": true,
"#aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true
}
}
TL;DR With two changes, the pipeline successfully deploys the React app: (1) Source.asset needs the full path to the build directory and (2) the React build commands need to be added to the synth step.
Give Source.asset the full path to the React build dir:
new BucketDeployment(this, "WebsiteDeployment", {
sources: [Source.asset(path.join(__dirname, './build'))], // relative to the Stack dir
destinationBucket: bucket
})
React build artifacts are typically .gitignored, so CodePipeline needs to build the React app. My version has a separate package.json for the React app, so the build step 1 needs a few more commands:
synth: new pipelines.CodeBuildStep('Synth', {
commands: [
// build react (new)
'cd react-app', // path from project root to React app package.json
'npm ci',
'npm run build',
'cd ..',
// synth cdk (as in OP)
"npm ci",
"npm run build",
"npx cdk synth" // synth must run AFTER the React build step
],
The React app deploys to a S3 URL:
// MainStack
new cdk.CfnOutput(this, 'WebsiteUrl', {
value: `http://${this.websiteBucket.bucketName}.s3-website-${this.region}.amazonaws.com`,
});
(1) pipelines.CodePipeline is an opinionated construct for deploying Stacks. The lower-level codepipeline.Pipeline construct has features many apps will need, such as separating build steps and the passing build-time env vars between steps (e.g. injecting the API URL into the client bundle using a REACT_APP_API_URL env var).
For the first question:
And if I change to Source.asset("./build") I get the error: ... Why is it searching for the build directory on my machine?
This is happening when you run cdk synth locally. Remember, cdk synth will always reference the file system where this command is run. Locally it will be your machine, in the pipeline it will be in the container or environment that is being used by AWS CodePipeline.
Dig a little deeper into BucketDeployment
But also, there is some interesting things that happen here that could be helpful. BucketDeployment doesn't just pull from the source you reference in BucketDeployment.sources and upload it to the bucket you specify in BucketDeployment.destinationBucket. According to the BucketDeployment docs the assets are uploaded to an intermediary bucket and then later merged to your bucket. This matters because it will explain your error received Error: Cannot find asset at C:\Users\pupeno\Code\ww3fe\build because when you run cdk synth it will expect the dir ./build as stated in Source.asset("./build") to exist.
This gets really interesting when trying to use a CodePipeline to build and deploy a single page app like React in your case. By default, CodePipeline will execute a Source step, followed a Synth step, then any of the waves or stages you add after. Adding a wave that builds your react app won't work right away because we now see that the output directory of building you react app is needed during the Synth step because of how BucketDeployment works. We need to be able to have the order be Source -> Build -> Synth -> Deploy. As found in this question, we can control the order of the steps by using inputs and outputs. CodePipeline will order the steps to ensure input/output dependencies are met. So we need the have our Synth step use the Build's output as its input.
Concerns with the currently defined pipeline
I believe that your current pipeline is missing a CodeBuildStep that would bundle your react app and output it to the directory that you specified in BucketDeployment.sources. We also need to set the inputs to order these actions correctly. Below are some updates to the pipeline definition, though some changes may need to be made to have the correct file paths. Also, set BucketDeployment.sources to the dir where your app bundle is written to.
export class PipelineStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props)
const sourceAction = CodePipelineSource.connection("user/example", "main", {
connectionArn: "arn:aws:codestar-connections:....",
});
const buildAction = new CodeBuildStep("Build", {
input: sourceAction, // This places Source first
installCommands: [ "npm ci" ],
commands: [ "npm run build" ], // Change this to your build command for your react app
// We need to output the entire contents of our file structure
// this is both the CDK code needed for synth and the bundled app
primaryOutputDirectory: "./",
});
const synthAction = new ShellStep("Synth", {
input: buildAction, // This places Synth after Build
installCommands: [
"npm install -g aws-cdk"
],
commands: [
"npm ci",
"npm run build",
"npx cdk synth"
],
// Synth step must output to cdk.out
// if your CDK code is nested, this will have to match that structure
primaryOutputDirectory: "./cdk.out",
});
const pipeline = new CodePipeline(this, id, {
pipelineName: id,
synth: synthAction,
});
const deploy = new DeployStage(this, "Staging");
const deployStage = pipeline.addStage(deploy);
}
}
Take a look in your gitignore file if some files like json or html files are not commited to be pushed into Repo.
I have just started to study Webpack and trying to setup development environment based on Webpack4.
I put one script for executing dev server in package.json like below.
# package.json
"scripts": {
"dev": "webpack-dev-server --mode development",
}
However, there was an error message like below when I execute'npm run dev' on my terminal.
ERROR in ./node_modules/destroy/index.js
Module not found: Error: Can't resolve 'fs' in 'D:\webpack-setup\node_modules\destroy'
# ./node_modules/destroy/index.js 14:17-30
So, I installed 'webpack-node-externals' and put configuration in 'webpack.config.js' like below.
# install webpack-node-externals module
# npm install --save-dev webpack-node-externals
# webpack.config.js
const nodeExternals = require('webpack-node-externals');
module.exports = {
target: 'web',
externals: [nodeExternals()],
devServer: {
host: 'localhost',
port: 3000,
open: true
}
};
When a browser was opened, there was an error on a browser like below.
Uncaught ReferenceError: require is not defined
at eval (external_"url":1)
at Object.url (main.js:289)
at __webpack_require__ (main.js:20)
at Object.eval (webpack:///(:3000/webpack)-dev-server/client?:6:11)
at eval (webpack:///(:3000/webpack)-dev-server/client?:249:30)
at Object../node_modules/webpack-dev-server/client/index.js?http://localhost:3000 (main.js:97)
at __webpack_require__ (main.js:20)
at eval (webpack:///multi_(:3000/webpack)-dev-server/client?:1:1)
at Object.0 (main.js:190)
at __webpack_require__ (main.js:20)
I'm not sure this error is related to 'webpack-node-externals' module or not,
but could I get some guide for solving this situation?
I think you have a problem in your config file. I ran a sample with this and it worked:
const nodeExternals = require('webpack-node-externals')
module.exports = {
target: 'web',
externals: [nodeExternals()],
devServer: {
host: 'localhost',
port: 3000,
open: true,
},
}
After searching for hours I can't figure out how to properly run claudia create in my project.
Following this turoial, I created a group and a user the AWS console, then I added the keys to my .aws/credentials file.
Then I ran this command that correctly produced the lambda.js file :
claudia --source dist generate-serverless-express-proxy --express-module app
My lambda.js
'use strict'
const awsServerlessExpress = require('aws-serverless-express')
const app = require('./app')
const binaryMimeTypes = [
'application/octet-stream',
'font/eot',
'font/opentype',
'font/otf',
'image/jpeg',
'image/png',
'image/svg+xml'
]
const server = awsServerlessExpress.createServer(app, null, binaryMimeTypes);
exports.handler = (event, context) => awsServerlessExpress.proxy(server, event, context)
Then I tried to deploy the lambda function on AWS :
claudia create --source dist --profile myprofile --handler lambda.handler --deploy-proxy-api --region eu-west-1
But I got this error :
validating package TypeError: "listener" argument must be a function
at _addListener (events.js:239:11)
at Server.addListener (events.js:297:10)
at new Server (_http_server.js:269:10)
at Object.createServer (http.js:34:10)
at Object.createServer (/tmp/IiRPif/my-project-1.0.0-1Yh6Wb/package/node_modules/aws-serverless-express/index.js:155:25)
at Object. (/tmp/IiRPif/my-project-1.0.0-1Yh6Wb/package/lambda.js:13:37)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Module.require (module.js:596:17)
at require (internal/module.js:11:18)
at validatePackage (/usr/local/lib/node_modules/claudia/src/tasks/validate-package.js:16:15)
at initEnvVarsFromOptions.then.then.then.then.then.then.then.dir (/usr/local/lib/node_modules/claudia/src/commands/create.js:342:10)
at cannot require ./lambda after clean installation. Check your dependencies.
What am I doing wrong here ?
My package.json
{
"name": "...",
"version": "1.0.0",
"scripts": {
"build": "tsc -p tsconfig.json & cp \"package.json\" \"dist/package.json\"
},
"repository": {
"type": "git",
"url": "..."
},
"homepage": "...",
"dependencies": {
"body-parser": "^1.18.3",
"express": "^4.16.3",
"mongoose": "^5.2.7",
"nodemon": "^1.18.3"
},
"devDependencies": {
"typescript": "^3.0.1"
}
}
My app.ts
import * as express from "express";
import * as bodyParser from "body-parser";
import * as mongoose from "mongoose";
import { Routes } from "./routes/routes";
class App {
public app: express.Application;
public routes: Routes = new Routes();
constructor() {
this.app = express();
// Parser setup
this.app.use(bodyParser.json());
this.app.use(bodyParser.urlencoded({ extended: true }));
this.routes.routes(this.app);
}
}
exports.default = new App().app;
After a discussion on Claudia's github, this appears to be a compatibility issue between es6 and claudia/lambda.
All I needed to do was to change this line in my app.js file from :
exports.default = new App().app;
To :
module.exports = new App().app;
Here is the mup.js:
module.exports = {
servers: {
one: {
host: '52.41.186.122',
username: 'ubuntu',
pem: 'aws-key/xanthelabs.pem'
// password:
// or leave blank for authenticate from ssh-agent
}
},
meteor: {
name: 'deep-app',
path: '/home/cortana/Desktop/deep-app',
servers: {
one: {}
},
buildOptions: {
serverOnly: true,
},
env: {
ROOT_URL: 'http://52.41.186.122:8888',
MONGO_URL: 'mongodb://localhost/meteor'
},
//dockerImage: 'kadirahq/meteord'
deployCheckWaitTime: 60
},
mongo: {
oplog: true,
port: 27017,
servers: {
one: {},
},
},
};
The error is:
Started TaskList: Start Meteor
[52.41.186.122] - Start Meteor
[52.41.186.122] - Start Meteor: SUCCESS
[52.41.186.122] - Verifying Deployment
[52.41.186.122] x Verifying Deployment: FAILED
-----------------------------------STDERR-----------------------------------
npm WARN deprecated semver behavior.
npm WARN package.json meteor-dev-bundle#0.0.0 No description
npm WARN package.json meteor-dev-bundle#0.0.0 No repository field.
npm WARN package.json meteor-dev-bundle#0.0.0 No README data
npm WARN cannot run in wd meteor-dev-bundle#0.0.0 node npm-rebuild.js (wd=/bundle/bundle/programs/server)
=> Starting meteor app on port:80
assert.js:93
throw new assert.AssertionError({
^
AssertionError: "undefined" === "function"
at wrapPathFunction (/bundle/bundle/programs/server/mini-files.js:77:10)
at Object.<anonymous> (/bundle/bundle/programs/server/mini-files.js:108:24)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object.<anonymous> (/bundle/bundle/programs/server/boot.js:9:13)
at Module._compile (module.js:456:26)
-----------------------------------STDOUT-----------------------------------
To see more logs type 'mup logs --tail=50'
----------------------------------------------------------------------------
(node:8968) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error:
-----------------------------------STDERR-----------------------------------
npm WARN deprecated semver behavior.
npm WARN package.json meteor-dev-bundle#0.0.0 No description
npm WARN package.json meteor-dev-bundle#0.0.0 No repository field.
npm WARN package.json meteor-dev-bundle#0.0.0 No README data
npm WARN cannot run in wd meteor-dev-bundle#0.0.0 node npm-rebuild.js (wd=/bundle/bundle/programs/server)
=> Starting meteor app on port:80
assert.js:93
throw new assert.AssertionError({
^
AssertionError: "undefined" === "function"
at wrapPathFunction (/bundle/bundle/programs/server/mini-files.js:77:10)
at Object.<anonymous> (/bundle/bundle/programs/server/mini-files.js:108:24)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object.<anonymous> (/bundle/bundle/programs/server/boot.js:9:13)
at Module._compile (module.js:456:26)
-----------------------------------STDOUT-----------------------------------
To see more logs type 'mup logs --tail=50'
----------------------------------------------------------------------------
Everything has been successfully setup. I dont understand what is throwing the error. Please explain the error and its reasons along with the solution. Thanks
About the system:
OS: ubuntu 16.04
deployment OS: Ubuntu 14.04 (on aws)
meteor : v1.4.1.2
Edit:
On using meteor-up fork suggested, I am getting this error:
[52.41.186.122] - Installing Node.js
[52.41.186.122] - Installing Node.js: SUCCESS
[52.41.186.122] - Installing PhantomJS
[52.41.186.122] - Installing PhantomJS: SUCCESS
[52.41.186.122] - Setting up Environment
[52.41.186.122] - Setting up Environment: SUCCESS
[52.41.186.122] - Copying MongoDB configuration
[52.41.186.122] x Copying MongoDB configuration: FAILED
Received exit code 0 while establishing SFTP session
The mup.js file I have is:
{
// Server authentication info
"servers": [
{
"host": "52.41.186.122",
"username": "ubuntu",
// "password": "ubuntu"
// or pem file (ssh based authentication)
"pem": "aws-key/xanthelabs.pem"
}
],
// Install MongoDB in the server, does not destroy local MongoDB on future setup
"setupMongo": true,
// WARNING: Node.js is required! Only skip if you already have Node.js installed on server.
"setupNode": true,
// WARNING: If nodeVersion omitted will setup 0.10.43 by default. Do not use v, only version number.
"nodeVersion": "4.4.7",
// Install PhantomJS in the server
"setupPhantom": true,
// Show a progress bar during the upload of the bundle to the server.
// Might cause an error in some rare cases if set to true, for instance in Shippable CI
"enableUploadProgressBar": true,
// Application name (No spaces)
"appName": "deep-app",
// Location of app (local directory)
"app": "/home/cortana/Desktop/deep-app",
// Configure environment
"env": {
"PORT": 8888,
"ROOT_URL": "http://52.41.186.122",
"MONGO_URL": "mongodb://localhost/meteor"
},
// Meteor Up checks if the app comes online just after the deployment
// before mup checks that, it will wait for no. of seconds configured below
"deployCheckWaitTime": 15
}
what is wrong here?
i had the same issues. add dockerImage: "abernix/meteord:base", to you meteor part of MUP.json.
If it's still not working. replace Flow Router with React Router