S3 & node.js / Define new agent for aws.sdk - amazon-web-services

I use node.js and aws-sdk.
I want to define a new agent from a require aws-sdk.
var agent = new http.Agent()
agent.maxSockets = 20;
var s3 = new AWS.S3({accessKeyId: "acc",
secretAccessKey: "sec", region:"us-east-1", httpOptions: {agent: agent}});
For some reason, it gives me an Networking error when I use var download = s3t.getObject(s3Params);
What can be the reason? How I define new agent?
Edit : This is the error:
{ [NetworkingError: read ECONNRESET]
message: 'read ECONNRESET',
code: 'NetworkingError',
errno: 'ECONNRESET',

Below is how you define a new https agent in your AWS S3 client:
var s3 = new AWS.S3({
httpOptions: {
agent: new https.Agent(...)
}})
Or you can globally update the AWS client config:
AWS.config.update({
httpOptions: {
agent: new http.Agent(...)
}
})

Related

S3 Bucket Access Denied for my HTTP client

I am working on an app that is deployed to AWS EC2 (Both client and server as a separate instance). My app uploads users' images to the s3 bucket.
I just added domains to both instances for https certification to both client and rest API
and since then I am getting this error while trying to save files to my S3 Bucket:
code: "AccessDenied"
extendedRequestId: "*****"
message: "Access Denied"
region: null
requestId: "****"
retryDelay: 67.72439862213535
retryable: false
statusCode: 403
time: "2020-09-12T13:42:29.739Z"
message: "Access Denied"
I have made this bucket public, even then it's not working.
here is my code
require('dotenv').config();
let multer = require('multer');
let AWS = require('aws-sdk');
let { uuid } = require('uuidv4');
let s3 = new AWS.S3({
accessKeyId: process.env.AWS_ID,
secretAccessKey: process.env.AWS_SECRET,
});
let storage = multer.memoryStorage({
destination: function (req, file, callback) {
callback(null, '');
},
});
let multiUpload = multer({ storage }).fields([
{ name: 'profile', maxCount: 1 },
{ name: 'gallery' },
]);
router.post('/', auth.required, multiUpload, async function (req, res, next) {
var profile = new Profile();
profile.userId = req.payload.id;
if (typeof req.files.profile !== 'undefined') {
let myImage = req.files.profile[0].originalname.split('.');
let fileType = myImage[myImage.length - 1];
let params = {
Bucket: process.env.AWS_BUCKET_NAME,
Key: `${uuid()}.${fileType}`,
Body: req.files.profile[0].buffer,
ContentType: 'image/jpeg',
ACL: 'public-read',
};
let data = await s3.upload(params).promise();
if (!data.Location) res.sendStatus(500);
profile.profileImage.url = data.Location;
profile.profileImage.imageId = data.key;
}
if (typeof req.files.gallery !== 'undefined') {
let galleryImageList = [];
for (let i = 0; i < req.files.gallery.length; i++) {
let myImage = req.files.gallery[i].originalname.split('.');
let fileType = myImage[myImage.length - 1];
let params = {
Bucket: process.env.AWS_BUCKET_NAME,
Key: `${uuid()}.${fileType}`,
Body: req.files.gallery[i].buffer,
ContentType: 'image/jpeg',
ACL: 'public-read',
};
let data = await s3.upload(params).promise();
if (!data.Location) res.sendStatus(500);
let galleryItem = {
url: data.Location,
imageId: data.key,
};
galleryImageList.push(galleryItem);
}
profile.gallery = galleryImageList;
}
profile
.save()
.then(function () {
return res.json({ profile: profile.toProfileJSONFor() });
})
.catch(next);
});
I apparently don't have enough reputation to make a comment, but you likely should include whether you're getting Access Denied from reading from the bucket or writing to the bucket or both, and you should include your code snippets that read/write from the bucket. Also, you should include what you mean by "Added domains to both instances for https certification" because I wouldn't think that should be necessary
Editing my response since you included your code:
It looks like you are using Keys to upload your files:
let s3 = new AWS.S3({
accessKeyId: process.env.AWS_ID,
secretAccessKey: process.env.AWS_SECRET,
});
let data = await s3.upload(params).promise();
So, if you are getting Access Denied on your writes, you should look at your keys permissions.

Uploading file to s3 bucket without using AWS console using nodeJs

I am new to AWS technology, i need to do above assignment so i want to know procedure do complete above task. What are prerequisites software and tools should i required.
Please suggest me in simple way. TIN Happy Coding
you have to configure your AWS credential before suing Aws with aws-sdk npm package using below method
import AWS from "aws-sdk";
const s3 = new AWS.S3({
accessKeyId: YOUR_ACCESS_KEY_ID_OF_AMAZON,
secretAccessKey: YOUR_AMAZON_SECRET_ACCESS_KEY,
signatureVersion: "v4",
region: YOUR_AMAZON_REGION // country
});
export { s3 };
then call s3 and do upload request using below code
const uploadReq: any = {
Bucket: "YOUR_BUCKET"
Key: "FILE_NAME",
Body: "FILE_STREAM",
ACL: "public-read", //ACCESSIBLE TO REMOTE LOCATION
};
await new Promise((resolve, reject) => {
s3.upload(uploadReq).send(async (err: any, data: any) => {
if (err) {
console.log("err", err);
reject(err);
} else {
//database call
resolve("STATUS");
}
});
});

AWS Elastic search service - IAM Role (Refresh session token - Node.js)

I'm using AWS Elastic search service and written a Node.js wrapper (runs within a ECS dockerized container) . IAM roles are used to create a singleton connection with Elastic search.
I'm trying to refresh my session token by checking AWS.config.credentials.needsRefresh() before every request - however it always returns true even after the session has expired. Obviously AWS is complaining with a 403 error. Any ideas will be greatly appreciated .
var AWS = require('aws-sdk');
var config = require('config');
var connectionClass = require('http-aws-es');
var elasticsearch = require('elasticsearch');
AWS.config.getCredentials(function() {
AWS.config.update({
credentials: new AWS.Credentials(AWS.config.credentials.accessKeyId,AWS.config.credentials.secretAccessKey,AWS.config.credentials.sessionToken),
region: 'us-east-1'
});
}
)
var client = new elasticsearch.Client({
host: `${config.get('elasticSearch.host')}`,
log: 'debug',
connectionClass: connectionClass,
amazonES: {
credentials: new AWS.EnvironmentCredentials('AWS')
}
});
module.exports = client;

Authenticating and Running an EC2 Instance: AWS

I am attempting to create an EC2 instance and then add it to my Auto Scaling group. I am having a lot of issues trying to authenticate. I am looking for a simple way to authenticate a request using my access key to simply start an instance. What I have tried so far:
//Authenticate AWS:
var myCredentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId:'us-west-2:IdentityPoolID'
});
var myConfig = new AWS.Config({
credentials: myCredentials, region: 'us-west-2'
});
AWS.config = myConfig
var minInst = 1;
var maxInst = 3;
var ec2 = new AWS.EC2();
//Set up parameters for EC2 Instances:
var params = {
ImageId: 'ami-6e1a0117',
MaxCount: minInst,
MinCount: maxInst,
InstanceInitiatedShutdownBehavior: 'terminate',
InstanceType: 't2.micro',
Monitoring: {
Enabled: false
},
NetworkInterfaces: [{
AssociatePublicIpAddress: true,
DeleteOnTermination: true,
}],
Placement: {
AvailabilityZone: 'us-west-2',
},
SecurityGroupIds: [
'sg-b0307ccd',
],
SecurityGroups: [
'CAB432Assignment2SG',
],
};
ec2.runInstances(params, function(err, data) {
if (err){
console.log(err, err.stack); //An error occurred
}
else{
console.log(data); //Successful Response
}
});
I know this code is wrong. I just don't know to fix it. The error I get is:
CredentialsError: Missing credentials in config
Any help would be greatly appreciated.
Delete this section of code entirely:
//Authenticate AWS:
var myCredentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId:'us-west-2:IdentityPoolID'
});
var myConfig = new AWS.Config({
credentials: myCredentials, region: 'us-west-2'
});
AWS.config = myConfig
Change this:
var ec2 = new AWS.EC2();
To this:
var ec2 = new AWS.EC2({region: 'us-west-2'});
Then go read this page in the Setting Credentials in Node.js documentation. In particular, you need to do one of the following:
Add an IAM role to your EC2 instance, if this is running on EC2.
Add an IAM execution role to your Lambda function if this is running on Lambda.
Create either a ~/.aws/credentials file with your keys. This can be done with the aws configure command if you have the AWS CLI installed.
Set the keys as environment variables.

AWS DynamoDB: "Error: Missing region in config" - even with 'config.region' returning 'eu-west-1'

While following the AWS docs for setting up DynamoDB in my front end project, with settings taken from the docs the API throws:
Error: Missing region in config
at constructor.<anonymous> (aws-sdk-2.129.0.min.js:42)
at constructor.callListeners (aws-sdk-2.129.0.min.js:44)
at i (aws-sdk-2.129.0.min.js:44)
at aws-sdk-2.129.0.min.js:42
at t (aws-sdk-2.129.0.min.js:41)
at constructor.getCredentials (aws-sdk-2.129.0.min.js:41)
at constructor.<anonymous> (aws-sdk-2.129.0.min.js:42)
at constructor.callListeners (aws-sdk-2.129.0.min.js:44)
at constructor.emit (aws-sdk-2.129.0.min.js:44)
at constructor.emitEvent (aws-sdk-2.129.0.min.js:43)
My settings:
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.129.0.min.js"></script>
<script>
var myCredentials = new AWS.CognitoIdentityCredentials({IdentityPoolId:'eu-west-1_XXXXXX'});
var myConfig = new AWS.Config({
credentials: myCredentials, region: 'eu-west-1',
});
console.log(myConfig.region); //logs 'eu-west-1'
var dynamodb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
dynamodb.listTables({Limit: 10}, function(err, data) {
if (err) {
console.log(err);
} else {
console.log("Table names are ", data.TableNames);
}
});
</script>
What am I missing?
Looks like you’re newing up AWS.config.
Change the line
var myConfig = new AWS.Config({
credentials: myCredentials, region: 'eu-west-1',
});
to
AWS.config.update({
credentials: myCredentials, region: 'eu-west-1',
}});
Reference:
http://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-region.html
Hope it helps.
For others hitting the same issue, where the docs mention:
If you have not yet created one, create an identity pool...
and you got forwarded to the Amazon Cognito service, choose the Manage Federal Identities not the Manage User Pools option.