IAM Cannot Access Launch Template - amazon-ec2

I am using the AWS Node SDK to try and use a launch template to launch an EC2 instance. In the web console for the same user I have access to the Launch Template ID, but in the Node API it tells me the Launch Template with ID does not exist:
version: aws-sdk#2.606.0
Screenshot in AWS Console
Screenshot in my config file
(I've blocked the last few characters for security but they are the same)
This is the Node
AWS = require('aws-sdk');
AWS.config.update({region: global.settings.aws.region});
let instanceParams = {
LaunchTemplate: {
LaunchTemplateId: global.settings.aws.ltId
},
InstanceType: 't2.micro',
MinCount: 1,
MaxCount: 1
};
let instancePromise = new AWS.EC2().runInstances(instanceParams).promise();
instancePromise.then(
function(data) {
console.log(data);
}).catch(
function(err) {
console.error(err, err.stack);
});
This is the error the API returns:
InvalidLaunchTemplateId.NotFound: The specified launch template, with template ID lt-03969d13638b5XXXX, does not exist.
at Request.extractError (/ApplicationPath/node_modules/aws-sdk/lib/services/ec2.js:50:35)
at Request.callListeners (/ApplicationPath/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (/ApplicationPath/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/ApplicationPath/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/ApplicationPath/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/ApplicationPath/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /ApplicationPath/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request. (/ApplicationPath/node_modules/aws-sdk/lib/request.js:38:9)
at Request. (/ApplicationPath/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/ApplicationPath/node_modules/aws-sdk/lib/sequential_executor.js:116:18)
at Request.emit (/ApplicationPath/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/ApplicationPath/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/ApplicationPath/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/ApplicationPath/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /ApplicationPath/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request. (/ApplicationPath/node_modules/aws-sdk/lib/request.js:38:9)
at Request. (/ApplicationPath/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/ApplicationPath/node_modules/aws-sdk/lib/sequential_executor.js:116:18)
at callNextListener (/ApplicationPath/node_modules/aws-sdk/lib/sequential_executor.js:96:12)
at IncomingMessage.onEnd (/ApplicationPath/node_modules/aws-sdk/lib/event_listeners.js:307:13)
at IncomingMessage.emit (events.js:214:15)
at IncomingMessage.EventEmitter.emit (domain.js:476:20) {
message: 'The specified launch template, with template ID lt-03969d13638b5XXXX, does not exist.',
code: 'InvalidLaunchTemplateId.NotFound',
time: 2020-01-22T15:29:18.641Z,
requestId: '16082702-49c0-4451-a3b7-570b930b5238',
statusCode: 400,
retryable: false,
retryDelay: 47.92654090836894
}
The IAM access includes both:
AmazonEC2FullAccess
AmazonEC2FullAccess
(The JSON are super long but I am happy to post those in here if needed)
My thought is that there is some permissioning error for the IAM but I can't determine what that might be. Thank you for the help and please let me know if there is any other clarity I can provide.

When you can see that a given AWS resource exists in the AWS console, but it is not returned by the awscli or SDK calls, (or vice-versa) then one of the following is likely the cause:
you have queried the wrong region
you have queried the wrong AWS account (your effective credentials are for a 2nd, different account)
you have mis-typed the resource name/id
your browser has cached results that no longer exist (refresh your browser)

Related

How to run nextjs in AWS lambda with `experimental-edge` runtime

I'm trying to find a way to run Next.js (v13.0.6) with OG image generation logic (using #vercel/og) in AWS Lambda
Everything works fine locally (in dev and prod mode) but when I try execute lambda handler getting "statusCode": 500,
It only fails for apis that involve ImageResponse (and runtime: 'experimental-edge' as a requirement for #vercel/og)
I'm pretty sure the problem is caused by Edge Runtime is not being configured correctly
There is my handler code
next build with next.config.js output: 'standalone' creates folder .next/standalone
insde standalone handler.js
const { parse } = require('url');
const NextServer = require('next/dist/server/next-server').default
const serverless = require('serverless-http');
const path = require('path');
process.env.NODE_ENV = 'production'
process.chdir(__dirname)
const currentPort = parseInt(process.env.PORT, 10) || 3000
const nextServer = new NextServer({
hostname: 'localhost',
port: currentPort,
dir: path.join(__dirname),
dev: false,
customServer: false,
conf: {...} // copied from `server.js` in there same folder
});
const requestHandler = nextServer.getRequestHandler();
// this is a AWS lambda handler that converts lambda event
// to http request that next server can process
const handler = serverless(async (req, res) => {
// const parsedUrl = parse(req.url, true);
try {
await requestHandler(req, res);
}catch(err){
console.error(err);
res.statusCode = 500
res.end('internal server error')
}
});
module.exports = {
handler
}
testing it locally with local-lambda, but getting similar results when test against AWS deployed lambda
what is confusing is that server.js (in .next/standalone) has a similar setup, it only involves http server on top of of it
update:
aws lambda logs show
ERROR [Error [CompileError]: WebAssembly.compile(): Compiling function #64 failed: invalid value type 'Simd128', enable with --experimental-wasm-simd #+3457 ]
update 2:
the first error was fixed by selecting Node 16 for AWS lambda, now getting this error
{
"errorType": "Error",
"errorMessage": "write after end",
"trace": [
"Error [ERR_STREAM_WRITE_AFTER_END]: write after end",
" at new NodeError (node:internal/errors:372:5)",
" at ServerlessResponse.end (node:_http_outgoing:846:15)",
" at ServerlessResponse.end (/var/task/node_modules/next/dist/compiled/compression/index.js:22:783)",
" at NodeNextResponse.send (/var/task/node_modules/next/dist/server/base-http/node.js:93:19)",
" at NextNodeServer.handleRequest (/var/task/node_modules/next/dist/server/base-server.js:332:47)",
" at processTicksAndRejections (node:internal/process/task_queues:96:5)",
" at async /var/task/index.js:34:5"
]
}
At the moment of writing Vercel's runtime: 'experimental-edge' seems to be unstable (run into multiple issues with it)
I ended up recreating #vercel/og lib without wasm and next.js dependencies, can be found here
and simply use it in AWS lambda. It depends on #resvg/resvg-js instead of wasm version, which uses binaries, so there should not be much perf loss comparing to wasm

CDK/CloudFormation Batch Setup NotStabilized Error

I'm trying to set up a simple Batch Compute Environment using a LaunchTemplate, so that I can specify a larger-than-default volume size:
const templateName = 'my-template'
const jobLaunchTemplate = new ec2.LaunchTemplate(stack, 'Template', {
launchTemplateName: templateName,
blockDevices: [ ..vol config .. ]
})
const computeEnv = new batch.CfnComputeEnvironment(stack, 'CompEnvironment', {
type: 'managed',
computeResources: {
instanceRole: jobRole.roleName,
instanceTypes: [
InstanceType.of(InstanceClass.C4, InstanceSize.LARGE).toString()
],
maxvCpus: 64,
minvCpus: 0,
desiredvCpus: 0,
subnets: vpc.publicSubnets.map(sn => sn.subnetId),
securityGroupIds: [vpc.vpcDefaultSecurityGroup],
type: 'EC2',
launchTemplate: {
launchTemplateName: templateName,
}
},
})
They both initialize fine when not linked, however as soon as the launchTemplate block is added to the compute environment, I get the following error:
Error: Resource handler returned message: "Resource of type 'AWS::Batch::ComputeEnvironment' with identifier 'compute-env-arn' did not stabilize." (RequestToken: token, HandlerErrorCode: NotStabilized)
Any suggestions are greatly appreciated, thanks in advance!
For anyone running into this - check the resource that is being created in the AWS Console - i.e go to aws.amazon.com and refresh the page over and over until you see it created by CF. This gave me a different error message regarding the instance profile not existing (A bit more helpful than the terminal error...)
A simple CfnInstanceProfile did the trick:
new iam.CfnInstanceProfile(stack, "batchInstanceProfile", {
instanceProfileName: jobRole.roleName,
roles: [jobRole.roleName],
});
I faced similar error.
But in my case cdk had created subnetGroups list in cdk.context.json and was trying to use the same in the CfnComputeEnvironment definition.
The problem was; I was using the default vpc and had manually modified few subnets. and cdk.context.json was not updated.
Solved by deleting the cdk.context.json
This file was recreated with correct values in next synth.
Tip for others facing similar problem:
Don't just rely on the error message; watch closely the Cloud-formation Script that's generated from CDK for the resource.

google-api-nodejs-client - Service Account credentials authentication issues

I am trying to use the google-api-nodejs library to manage some resources in the google Campaign Manager API.
I have confirmed that we currently have a project configured, and that this project has the google Campaign Manager API enabled (see screenshot at the bottom).
I have tried several ways of authenticating myself (particularly API keys, OAuth2, and Service account credentials). This question will focus on using a Service Account for authentication purposes.
Now, I have generated a new service account keyfile (see screenshot at the bottom)), and I configured my code as follows, following the service-account-credentials section of the library's repo. I've also extended the auth scope to include the necessary scope according to this endpoint API docs
import { assert } from "chai";
import { google } from "googleapis";
it("can query userProfiles using service account keyfile", async () => {
try {
const auth = new google.auth.GoogleAuth({
keyFile:
"/full-path-to/credentials-service-account.json",
scopes: [
"https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/dfatrafficking",
"https://www.googleapis.com/auth/ddmconversions",
"https://www.googleapis.com/auth/dfareporting",
],
});
const authClient = await auth.getClient();
// set auth as a global default
google.options({
auth: authClient,
});
const df = google.dfareporting("v3.5");
const res = await df.userProfiles.list({});
console.log("res: ", res);
assert(true);
} catch (e) {
console.error("error: ", e);
assert(false);
}
});
This results in the following error:
{
"code": 403,
"errors": [
{
"message": "Version v3.5 is no longer supported. Please upgrade to the latest version of the API.",
"domain": "global",
"reason": "forbidden"
}
]
}
This is an interesting error, because v3.5 is the latest version of that API (as of 14 April 2022) (This page shows the deprecation schedule: https://developers.google.com/doubleclick-advertisers/deprecation. Notice that v3.3 and v3.4 are deprecated, while v3.5 is not.)
In any case, using a different version of the dfareporting API still result in error:
// error thrown: "Version v3.5 is no longer supported. Please upgrade to the latest version of the API."
const df = google.dfareporting("v3.5");
// error thrown: "Version v3.4 is no longer supported. Please upgrade to the latest version of the API."
const df = google.dfareporting("v3.4");
// error thrown: 404 "The requested URL <code>/dfareporting/v3.3/userprofiles</code> was not found on this server"
const df = google.dfareporting("v3.3");
// Note 1: There are no other versions available
// Note 2: It is not possible to leave the version blank
const df = google.dfareporting();
// results in typescript error: "An argument for 'version' was not provided."
I also tried to query the floodlightActivities API, which failed with an authentication error.
// const res = await df.userProfiles.list({});
const res = await df.floodlightActivities.list({
profileId: "7474579",
});
This, in it's turn, results in the following error:
{
"code": 401,
"errors": [
{
"message": "1075 : Failed to authenticate. Google account can not access the user profile/account requested.",
"domain": "global",
"reason": "authError",
"location": "Authorization",
"locationType": "header"
}
]
}
Now, my question is:
am I doing something wrong while trying to authenticate using the service account credentials?
Or, is it possible that these endpoints do not support service-account-credentials?
Or, is something else going wrong here?

"Unsupported Media Type" using serverless offline

I'm working on a small serverless offline assignment and I got error Unsupported Media Type when tried to invoke one lambda function in another.
I found a solution but when I tried to applied to my project was not working:
here in the link all the details. cloud anyone help me with that
https://github.com/dherault/serverless-offline/issues/1005#issue-632401297
there are three possible solutions.
Make sure that the lambda_A have the same port and host where the lambda_B is running.
Lambda_A:
const { Lambda } = require('aws-sdk');
const lambda = new Lambda({
region: 'us-east-1',
endpoint: 'http://localhost:3000',
});
module.exports.main = async (event, context) => {
// invoke
}
Lambda_B: Is running on http://localhost:3000
You have configured out serverless-offline in twice functions.
https://www.serverless.com/plugins/serverless-offline#usage-with-invoke
Lambda_A or Lambda_B have correctly stage?. Remember to use sls offline --stage local in both functions.

serverless .yml environment variable issues

I am on this page of a serverless with Lambdas and Dynamo DB exercise.
I am on the " Add a Create Note API" section and am having trouble with testing the API
the command:
serverless invoke local --function create --path mocks/create-event.json
produces this error
Serverless: DOTENV: Loading environment variables from .env:
Serverless: - tableName
Serverless: Bundling with Webpack...
error is : ResourceNotFoundException: Requested resource not found
at Request.extractError (/Users/dannybyrne/notes-app-api/node_modules/aws-sdk/lib/protocol/json.js:51:27)
at Request.callListeners (/Users/dannybyrne/notes-app-api/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (/Users/dannybyrne/notes-app-api/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/Users/dannybyrne/notes-app-api/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/Users/dannybyrne/notes-app-api/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/Users/dannybyrne/notes-app-api/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /Users/dannybyrne/notes-app-api/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/Users/dannybyrne/notes-app-api/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/Users/dannybyrne/notes-app-api/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/Users/dannybyrne/notes-app-api/node_modules/aws-sdk/lib/sequential_executor.js:116:18)
at Request.emit (/Users/dannybyrne/notes-app-api/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/Users/dannybyrne/notes-app-api/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/Users/dannybyrne/notes-app-api/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/Users/dannybyrne/notes-app-api/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /Users/dannybyrne/notes-app-api/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/Users/dannybyrne/notes-app-api/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/Users/dannybyrne/notes-app-api/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/Users/dannybyrne/notes-app-api/node_modules/aws-sdk/lib/sequential_executor.js:116:18)
at callNextListener (/Users/dannybyrne/notes-app-api/node_modules/aws-sdk/lib/sequential_executor.js:96:12)
at IncomingMessage.onEnd (/Users/dannybyrne/notes-app-api/node_modules/aws-sdk/lib/event_listeners.js:307:13)
at IncomingMessage.emit (events.js:215:7)
at IncomingMessage.EventEmitter.emit (domain.js:476:20)
at endReadableNT (_stream_readable.js:1183:12)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
message: 'Requested resource not found',
code: 'ResourceNotFoundException',
time: 2019-12-10T18:33:00.494Z,
requestId: '4D2O3VOI437AE9MTH1M4UPGDUVVV4KQNSO5AEMVJF66Q9ASUAAJG',
statusCode: 400,
retryable: false,
retryDelay: 28.999931507407407
}
{
"statusCode": 500,
"headers": {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Credentials": true
},
"body": "{\"status\":false}"
}
I have edited the .env file to have
tableName='notes'
though in the .yml file is says
# These environment variables are made available to our functions
# under process.env.
environment:
tableName: notes
I'm assuming this means that in the create.js file, under the params object
TableName: process.env.tableName,
In the instructions it says
" We read the name of our DynamoDB table from the environment variable using  process.env.tableName . We’ll be setting this in our  serverless.yml  below. We do this so we won’t have to hardcode it in every function."
Does this mean that I don't have to set it in the .env file that is included? when I rename this file to not be included in the build it also throws an error asking for it. When I define tableName in .env and set it to 'notes', as is defined in the .yml file and is the name of the dynamoDB table, it throws the above error.
I'm basically trying to figure out hoew .yml pull from .env (or not)
Yes if you define the variable under the provider it'll be available to all the functions.

Resources