I've debugged my application, and identified a problem. I have 2 REST API Gateway, and it seems like since they both bind on the same endpoint, the first one will recieve the call that the second one should handle.
Here's my template.yaml
Resources:
mysampleapi1:
Type: 'AWS::Serverless::Function'
Properties:
Handler: packages/mysampleapi1/dist/index.handler
Runtime: nodejs14.x
CodeUri: .
Description: ''
MemorySize: 1024
Timeout: 30
Role: >-
arn:aws:iam:: [PRIVATE]
Events:
Api1:
Type: Api
Properties:
Path: /users
Method: ANY
Environment:
Variables:
NODE_ENV: local
Tags:
STAGE: local
mysampleapi2:
Type: 'AWS::Serverless::Function'
Properties:
Handler: packages/mysampleapi2/dist/index.handler
Runtime: nodejs14.x
CodeUri: .
Description: ''
MemorySize: 1024
Timeout: 30
Role: >-
arn:aws:iam:: [PRIVATE]
Events:
Api1:
Type: Api
Properties:
Path: /wallet
Method: ANY
Environment:
Variables:
NODE_ENV: local
Tags:
STAGE: local
When I send a HTTP request for mysampleapi2
Here's what's happening in the logs using the startup command
sam local start-api --port 3001 --log-file /tmp/server-output.log --profile personal --debug
2022-04-27 18:2:34,953 | Mounting /home/mathieu_auclair/Documents/Project/repositories/server as /var/task:ro,delegated inside runtime container
2022-04-27 18:20:35,481 | Starting a timer for 30 seconds for function 'mysampleapi1'
2022-04-27 18:21:05,484 | Function 'mysampleapi1' timed out after 30 seconds
2022-04-27 18:21:46,732 | Container was not created. Skipping deletion
2022-04-27 18:21:46,732 | Cleaning all decompressed code dirs
2022-04-27 18:21:46,733 | No response from invoke container for mysampleapi1
2022-04-27 18:21:46,733 | Invalid lambda response received: Lambda response must be valid json
Why is my mysampleapi2 not picking the HTTP call? If I run them in separate template files using different ports, then it works... why is that?
After launching my lambda in separate processes, I discovered that there's an issue in my configuration for the second service.
The issue still occured after this launcher
echo "" > /tmp/server-output-1.log
sam local start-api --port 3001 --log-file /tmp/server-output-1.log --template .template.1.yaml --debug &
tail -f /tmp/server-output-1.log &
echo "" > /tmp/server-output-2.log
sam local start-api --port 3002 --log-file /tmp/server-output-2.log --template .template.2.yaml --debug &
tail -f /tmp/server-output-2.log &
I noticed when I exported my configuration, for one of the services, there's the following in the template.yaml
Path: '/{proxy+}'
without the proxy line, the lambda handler just never gets called for some reason
Related
I am writing a cloud-formation template where I am running two powershell scripts. Now I want to fetch the output of both the scripts and want to send that to an email which is already mentioned in cloud-formation parameter.
here is the code:-
AWSTemplateFormatVersion: '2010-09-09'
Description: Test Document
Resources:
Type: AWS::SSM::Document
Properties:
DocumentType: Command
Name: "Test Upgrade"
Content:
schemaVersion: '2.2'
description: "Test Upgrade"
parameters:
Emails:
type: String
description: |-
enter the email address to send the overall output
mainSteps:
- action: "aws:runPowerShellScript"
name: "DriverUpgrade"
precondition:
StringEquals: ["platformType", "Windows"]
inputs:
runCommand:
[]
timeoutSeconds: 3600
onFailure: Continue
maxAttempts: 1
isCritical: False
nextStep: Second Driver
- action: "aws:runPowerShellScript"
name: "SecondDriverUpgrade"
precondition:
StringEquals: ["platformType", "Windows"]
inputs:
runCommand:
[]
timeoutSeconds: 3600
onFailure: Continue
isCritical: False
Could you use AWS CLI command 'ses send-email' inside the Powershell script or as a part of Run Command parameters?
Certainly you have to configure the SES service beforehand in cfn template or console.
You could retrieve the email address from parameter store by using AWS CLI command ssm get-parameters.
To store the output of the scripts you could use a local file, parameter store, or, for example, dynamodb table etc.
https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ses/send-email.html
https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ssm/get-parameters.html
Given
root#kun4:/home/ubuntu/Igloo_Backend# sam --version
SAM CLI, version 1.62.0
root#kun4:/home/ubuntu/Igloo_Backend# nohup sam local start-api --log-file logfile.txt --host 0.0.0.0 --warm-containers EAGER >>output.log 2>&1 &
[1] 196068
The time execution is still long (13s, bot local request and remote request).
Here is template:
AWSTemplateFormatVersion: 2010-09-09
Description: BACKEND
Transform: AWS::Serverless-2016-10-31
Resources:
postingFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src.posting
Runtime: nodejs16.x
Environment:
Variables:
NODE_ENV: lc
# Architectures:
# - x86_64
# MemorySize: 128
Timeout: 100
Events:
Api:
Type: Api
Properties:
Path: /credentials
Method: POST
Log:
START RequestId: 62315c0e-f4f9-47c7-bb72-2302f15ac6c4 Version: $LATEST
2022-11-11T08:36:42.012Z 62315c0e-f4f9-47c7-bb72-2302f15ac6c4 INFO ENTER
2022-11-11T08:36:42.053Z 62315c0e-f4f9-47c7-bb72-2302f15ac6c4 INFO Executing (default): SELECT "id", "username", "password", "encrypted", "createdAt", "updatedAt" FROM "users" AS "User" WHERE "User"."username" = 'a' LIMIT 1;2022-11-11T08:36:42.056Z 62315c0e-f4f9-47c7-bb72-2302f15ac6c4 INFO ERROR
2022-11-11T08:36:42.057Z 62315c0e-f4f9-47c7-bb72-2302f15ac6c4 INFO UserExistedError: a - a already existed^M at Object.module.exports.persistCredentials (/var/task/src/service/user.service.js:29:15)^M at processTicksA>END RequestId: 62315c0e-f4f9-47c7-bb72-2302f15ac6c4
REPORT RequestId: 62315c0e-f4f9-47c7-bb72-2302f15ac6c4 Init Duration: 0.12 ms Duration: 10362.78 ms Billed Duration: 10363 ms Memory Size: 128 MB Max Memory Used: 128 MB
Please suggest your idea, thank you
I'm trying to dynamically pass in options to resolve when deploying my functions with serverless but they're always null or hit the fallback.
custom:
send_grid_api: ${opt:sendgridapi, 'missing'}
SubscribedUsersTable:
name: !Ref UsersSubscriptionTable
arn: !GetAtt UsersSubscriptionTable.Arn
bundle:
linting: false
provider:
name: aws
lambdaHashingVersion: 20201221
runtime: nodejs12.x
memorySize: 256
stage: ${opt:stage, 'dev'}
region: us-west-2
environment:
STAGE: ${self:provider.stage}
SEND_GRID_API_KEY: ${self:custom.send_grid_api}
I've also tried:
environment:
STAGE: ${self:provider.stage}
SEND_GRID_API_KEY: ${opt:sendgridapi, 'missing'}
both yield 'missing', but why?
sls deploy --stage=prod --sendgridapi=xxx
also fails if I try with space instead of =.
Edit: Working Solution
In my github action template, I defined the following:
- name: create env file
run: |
touch .env
echo SEND_GRID_API_KEY=${{ secrets.SEND_GRID_KEY }} >> .env
ls -la
pwd
In addition, I explicitly set the working directory for this stage like so:
working-directory: /home/runner/work/myDir/myDir/
In my serverless.yml I added the following:
environment:
SEND_GRID_API_KEY: ${env:SEND_GRID_API_KEY}
sls will read the contents from the file and load them properly
opt is for serverless' CLI options. These are part of serverless, not your own code.
You can instead use...
provider:
...
environment:
...
SEND_GRID_API_KEY: ${env:SEND_GRID_API_KEY}
And pass the value as an environment variable in your deploy step.
- name: Deploy
run: sls deploy --stage=prod
env:
SEND_GRID_API_KEY: "insert api key here"
I'm trying to execute aws sam local invoke command in order to test my function locally. The problem occurs when I run this command passing profile parameter. The execution container sets account id as a dummy account like 123456789012
Does anybody knows If there is any thing cached here? When I deploy my project using sam deploy --guided everything runs perfect and code is uploaded to AWS
my ~/.aws/config and ~/.aws/credentials files are filled
credentials
[adm]
aws_access_key_id=XXXXXXXXXXXXXx
aws_secret_access_key=XXXXXXXXXXXXXXXXXX
config
[adm]
region = eu-west-1
output = json
➜ POC sam local invoke "ScheduleBusinessRuleFunction" --profile adm
Invoking scheduleBusinessRule (go1.x)
Skip pulling image and use local one: amazon/aws-sam-cli-emulation-image-go1.x:rapid-1.18.1.
Mounting /run/media/urkob/projects/Projects/POC/.aws-sam/build/ScheduleBusinessRuleFunction as /var/task:ro,delegated inside runtime container
START RequestId: bc99de19-290b-46fa-908a-744d54547cbe Version: $LATEST
operation error CloudWatch Events: PutTargets, https response error StatusCode: 400, RequestID: 8e335486-de38-49bb-a06e-8090e26e9628, api error AccessDeniedException: Access to the resource arn:aws:lambda:us-east-1:123456789012:function:POC-executeBusinessRule is denied. Reason: Adding cross-account target is not permitted.: OperationError
null
END RequestId: bc99de19-290b-46fa-908a-744d54547cbe
REPORT RequestId: bc99de19-290b-46fa-908a-744d54547cbe Init Duration: 0.14 ms Duration: 1415.60 ms Billed Duration: 1500 ms Memory Size: 128 MB Max Memory Used: 128 MB
{"errorMessage":"operation error CloudWatch Events: PutTargets, https response error StatusCode: 400, RequestID: 8e335486-de38-49bb-a06e-8090e26e9628, api error AccessDeniedException: Access to the resource arn:aws:lambda:us-east-1:123456789012:function:POC-executeBusinessRule is denied. Reason: Adding cross-account target is not permitted.","errorType":"OperationError"}%
➜ POC
UPDATED: 21/02/16
I've been searching what could be the problem. I'm using aws-sdk-go-v2 the example they exposed in ther official github documentation to get an instance of configuration:
I tryied two ways of getting config instance as you can see in this piece of code, the line commented and the line that comes after that is not commented.
import (
"context"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/cloudwatchevents"
)
//NewCloudWatchService scheduler service
func NewCloudWatchService() CWEPutEventsAPI {
cfg, err := config.LoadDefaultConfig(context.TODO())
//Happens the same in local with this line
// cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithSharedConfigFiles(config.DefaultSharedCredentialsFiles))
if err != nil {
panic("configuration error, " + err.Error())
}
return cloudwatchevents.NewFromConfig(cfg)
}
This is my template.yaml file. I'm developing usin AWS SAM yaml templates. As you can see I reference ExecuteLambda in ScheduleLambda using GettAtt method but when the code runs in local the region and accountId are always the same: default values.
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Globals:
Function:
Timeout: 5
Resources:
ScheduleBusinessRuleFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: POC-scheduleBusinessRule
CodeUri: functions/scheduleBusinessRule/
Handler: scheduleBusinessRule
Runtime: go1.x
MemorySize: 128
Timeout: 10
Tracing: Active
Role: !GetAtt SchedulerRole.Arn
Environment:
Variables:
LAMBDA_ARN: !GetAtt ExecuteBusinessRuleFunction.Arn
EVENT_BUS: "default"
ExecuteBusinessRuleFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: POC-executeBusinessRule
CodeUri: functions/executeBusinessRule/
Handler: executeBusinessRule
Runtime: go1.x
MemorySize: 128
Tracing: Active
I use the serverless framework.
I use AWS API GateWay.
I would like to create an API to enter this command at the terminal and receive the parameter "name" and the parameter "type".
$ mkdir test-serverless
$ cd test-serverless
$ sls create --template aws-nodejs --name test
$ vi serverless.yml
$cat serverless.yml
service:test
provider:
name: aws
runtime: nodejs6.10
region: ap-northeast-1
functions:
testfunc:
handler: handler.func
events:
- http:
path: testpath
method: get
request:
querystrings:
name: true
type: true
headers:
Accept: application/json
$ sls deploy -v
With this command, the API was created successfully.
However, none of the parameters were set.
As a result, I set the parameters manually in the AWS console.
But wait for correct knowledge.
As a result, is not it possible to eliminate manual input with the serverless framework?
Reflecting the setting of parameters in API GateWay If anyone knows how to write yml, please let me know.
I want to easily hit the API with curl.
$ curl http://url.com/para?name=test&type=test
You need to add the correct identation:
functions:
testfunc:
handler: handler.func
events:
- http:
path: testpath
method: get
request:
querystrings:
name: true
type: true
headers:
Accept: application/json