I am using serverless to deploy an Appsync API using 'PIPELINE', for use as an API lambda-functions. This plugin https://github.com/sid88in/serverless-appsync-plugin is used to deploy Appsync with the ability to use 'pipeline'. I used the description from the documentation however when I try to do deploy it in myself I have an error:
Error: The CloudFormation template is invalid: Template error: instance of Fn::GetAtt references undefined resource GraphQlDsmeInfo
functions:
graphlql:
handler: handler.meInfo
name: meInfo
custom:
accountId: testId
appSync:
name: test-AppSync
authenticationType: API_KEY
mappingTemplates:
- type: Query
field: meInfo
request: 'meInfo-request-mapping-template.vtl'
response: 'meInfo-response-mapping-template.vtl'
kind: PIPELINE
functions:
- meInfo
functionConfigurations:
- dataSource: meInfo
name: 'meInfo'
request: 'meInfo-request-mapping-template.vtl'
response: 'meInfo-response-mapping-template.vtl'
Could somebody help me to configure 'serverless-appsync-plugin ' with pipeline kind?
You need to specify the data source used in your function.
It seems you've deployed the handler as Lambda function. If not, first you should have a separate serverless.yml config for your Lambda and deploy it. Then you need to attach this Lambda as AppSync data source, so your AppSync config would look like this:
custom:
accountId: testId
appSync:
name: test-AppSync
authenticationType: API_KEY
dataSources:
- type: AWS_LAMBDA
name: Lambda_Name
description: 'Lambda Description'
config:
lambdaFunctionArn: 'arn:aws:lambda:xxxx'
serviceRoleArn: 'arn:aws:iam::xxxx'
mappingTemplates:
- type: Query
field: meInfo
request: 'meInfo-request-mapping-template.vtl'
response: 'meInfo-response-mapping-template.vtl'
kind: PIPELINE
functions:
- meInfo
functionConfigurations:
- dataSource: Lambda_Name
name: 'meInfo'
request: 'meInfo-request-mapping-template.vtl'
response: 'meInfo-response-mapping-template.vtl'
There is an article which describes the process in details that might be useful: https://medium.com/hackernoon/running-a-scalable-reliable-graphql-endpoint-with-serverless-24c3bb5acb43
Related
I have the following in my serverless yml file :
lambdaQueueFirstInvokePermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: ServiceLambdaFunctionQualifiedArn
Action: ‘lambda:InvokeFunction’
Principal: sqs.amazonaws.com
and I have the following in the Outputs section :
Outputs:
ServiceLambdaFunctionQualifiedArn:
Value:
‘Fn::GetAtt’: [ lambdaQueueFirst, Arn ]
this comes back with a message:
Template error: instance of Fn::GetAtt references undefined resource lambdaQueueFirst
Am I missing something and if so, what? since it is very little in terms of help or examples…
Also, is there a better of getting the lambda arn into the permissions code? if so, what is it?
You can use the environment variables to construct the ARN value. In your case, you can define a variable in your provider section like below. You might need to modify a little bit according to your application.
service: serverless App2
provider:
name: aws
runtime: python3.6
region: ap-southeast-2
stage: dev
environment:
AWS_ACCOUNT: 1234567890 # use your own AWS ACCOUNT number here
# define the ARN of the function that you want to invoke
FUNCTION_ARN: "arn:aws:lambda:${self:provider.region}:${self:provider.environment.AWS_ACCOUNT}:function:${self:service}-${self:provider.stage}-lambdaQueueFirst"
Outputs:
ServiceLambdaFunctionQualifiedArn:
Value: "${self:provider.environment.FUNCTION_ARN}"
See this and serverless variables for aws for example.
you can do this:
resources:
Resources:
LoggingLambdaPermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: { "Fn::GetAtt": ["LoghandlerLambdaFunction", "Arn" ] }
Action: lambda:InvokeFunction
Principal: { "Fn::Join" : ["", ["logs.", { "Ref" : "AWS::Region"}, ".amazonaws.com" ] ] }
reference:
https://github.com/andymac4182/serverless_example
I am trying to create an AWS CloudFormation template using YAML. I add a UserPool resource as follows. The user pool name & id should be obtained via a parameter value i.e., if the value of parameter paramUserPoolName is 'Sample', then:
UserPoolName = Sample
UserPool Resource Name = SampleUserPool i.e., concatenated value of 'paramUserPoolName + UserPool'
Parameters:
paramUserPoolName:
Type: String
Resources:
<I need 'paramUserPoolName + UserPool' here >:
Type: 'AWS::Cognito::UserPool'
Properties: {
"UserPoolName": paramUserPoolName
}
How can I dynamically create a resource id in CloudFormation template?
PS:
The following worked:
Resources:
SampleUserPool:
Type: 'AWS::Cognito::UserPool'
Properties:
UserPoolName: !Sub ${paramUserPoolName}UserPool
Use !Sub for that. You can also use !Join, but !Sub is easier.
Parameters:
paramUserPoolName:
Type: String
Resources:
Type: 'AWS::Cognito::UserPool'
Properties:
UserPoolName: !Sub ${paramUserPoolName}UserPool
I am having issues deploying a lambda with a handler in a nested directory using sam.
I perform the following steps:
package:
sam package --template template.yaml --output-template-file packaged.yaml --s3-bucket
Creates a packaged.yaml that I use in the next step.
deploy:
aws cloudformation deploy --template-file /Users/localuser/Do/learn-sam/dynamo-stream-lambda/packaged.yaml --stack-name barkingstack
ERROR
Failed to create the changeset: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state Status: FAILED. Reason: Transform AWS::Serverless-2016-10-31 failed with: Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [PublishNewBark] is invalid. Missing required property 'Handler'.
Cloudformation/SAM Template
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Globals:
Function:
Runtime: nodejs8.10
Timeout: 300
Resources:
PublishNewBark:
Type: AWS::Serverless::Function
FunctionName: publishNewBark
CodeUri: .
Handler: src/index.handler
Role: "<ROLE_ARN>"
Description: Reads from the DynamoDB Stream and publishes to an SNS topic
Events:
- ReceiveBark:
Type: DynamoDB
Stream: !GetAtt BarkTable.StreamArn
StartingPosition: TRIM_HORIZON
BatchSize: 1
BarkTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: BarkTable
KeySchema:
- KeyType: HASH
AttributeName: id
AttributeDefinitions:
- AttributeName: id
AttributeType: S
StreamSpecification:
StreamViewType: NEW_AND_OLD_IMAGES
ProvisionedThroughput:
WriteCapacityUnits: 5
ReadCapacityUnits: 5
WooferTopic:
Type: AWS::SNS::Topic
Properties:
DisplayName: wooferTopic
TopicName: wooferTopic
Subscription:
- Endpoint: <my_email>
Protocol: email
DIRECTORY STRUCTURE
root_directory/
events/ (for sample events)
policies/ (for IAM Role to be created for the lambda using CLI)
src/index.js
package.json
node_modules
template.yaml
HANDLER CODE
async function handler (event, context) {
console.log(JSON.stringify(event, null, 2))
return {}
}
module.exports = {handler}
I believe you have to put everything except the resource type under "Properties".
Your function declaration should be:
PublishNewBark:
Type: AWS::Serverless::Function
Properties:
FunctionName: publishNewBark
CodeUri: .
Handler: src/index.handler
Role: "<ROLE_ARN>"
Description: Reads from the DynamoDB Stream and publishes to an SNS topic
Events:
- ReceiveBark:
Type: DynamoDB
Stream: !GetAtt BarkTable.StreamArn
StartingPosition: TRIM_HORIZON
BatchSize: 1
I have a little doubt about "Mappings section" of the aws cloudformation syntax:
Example:
...
Mappings:
accounts:
56565d644801:true
986958470041:true
090960219037:true
05166767667:false
functions:
MyFunction:
handler: src/MyFunction/func.lambda_handler
role: MyRole
events:
- schedule:
rate: rate(12 hours)
enabled: Fn::FindInMap
- accounts
- Ref "AWS::AccountId"
...
Could the Mappings section be included in a serverless.yml file ?
I meant, eventhough it is a valid cloudformation syntax, would it possible include it in the serverless.yml, so that later we can implement it (serverless | sls deploy ...)?
thanks,
You might be able to use:
functions:
# ...
resources:
Mappings:
accounts:
56565d644801:true
986958470041:true
090960219037:true
05166767667:false
Just another way to work with mapping is through stage params.
https://www.serverless.com/framework/docs/guides/parameters
params:
stage1:
schedule:true
stage2:
schedule:false
functions:
MyFunction:
handler: src/MyFunction/func.lambda_handler
role: MyRole
events:
- schedule:
rate: rate(12 hours)
enabled: ${param:schedule}
Then call adding the stage arg (default is dev)
serverless deploy --stage stage1
I'm attempting to export a DynamoDb StreamArn from a stack created in CloudFormation, then reference the export using !ImportValue in the serverless.yml.
But I'm getting this error message:
unknown tag !<!ImportValue> in "/codebuild/output/src/serverless.yml"
The cloudformation and serverless.yml are defined as below. Any help appreciated.
StackA.yml
AWSTemplateFormatVersion: 2010-09-09
Description: Resources for the registration site
Resources:
ClientTable:
Type: AWS::DynamoDB::Table
DeletionPolicy: Retain
Properties:
TableName: client
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 2
WriteCapacityUnits: 2
StreamSpecification:
StreamViewType: NEW_AND_OLD_IMAGES
Outputs:
ClientTableStreamArn:
Description: The ARN for My ClientTable Stream
Value: !GetAtt ClientTable.StreamArn
Export:
Name: my-client-table-stream-arn
serverless.yml
service: my-service
frameworkVersion: ">=1.1.0 <2.0.0"
provider:
name: aws
runtime: nodejs6.10
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:DescribeStream
- dynamodb:GetRecords
- dynamodb:GetShardIterator
- dynamodb:ListStreams
- dynamodb:GetItem
- dynamodb:PutItem
Resource: arn:aws:dynamodb:*:*:table/client
functions:
foo:
handler: foo.main
events:
- stream:
type: dynamodb
arn: !ImportValue my-client-table-stream-arn
batchSize: 1
Solved by using ${cf:stackName.outputKey}
I struggled with this as well, and what did trick for me was:
functions:
foo:
handler: foo.main
events:
- stream:
type: dynamodb
arn:
!ImportValue my-client-table-stream-arn
batchSize: 1
Note, that intrinsic functions ImportValue is on a new line and indented, otherwise the whole event is ignored when cloudformation-template-update-stack.json is generated.
It appears that you're using the !ImportValue shorthand for CloudFormation YAML. My understanding is that when CloudFormation parses the YAML, and !ImportValue actually aliases Fn::ImportValue. According to the Serverless Function documentation, it appears that they should support the Fn::ImportValue form of imports.
Based on the documentation for Fn::ImportValue, you should be able to reference the your export like
- stream:
type: dynamodb
arn: {"Fn::ImportValue": "my-client-table-stream-arn"}
batchSize: 1
Hope that helps solve your issue.
I couldn't find it clearly documented anywhere but what seemed to resolve the issue for me is:
For the Variables which need to be exposed/exported in outputs, they must have an "Export" property with a "Name" sub-property:
In serverless.ts
resources: {
Resources: resources["Resources"],
Outputs: {
// For eventbus
EventBusName: {
Export: {
Name: "${self:service}-${self:provider.stage}-UNIQUE_EVENTBUS_NAME",
},
Value: {
Ref: "UNIQUE_EVENTBUS_NAME",
},
},
// For something like sqs, or anything else, would be the same
IDVerifyQueueARN: {
Export: {
Name: "${self:service}-${self:provider.stage}-UNIQUE_SQS_NAME",
},
Value: { "Fn::GetAtt": ["UNIQUE_SQS_NAME", "Arn"] },
}
},
}
Once this is deployed you can check if the exports are present by running in the terminal (using your associated aws credentials):
aws cloudformation list-exports
Then there should be a Name property in a list:
{
"ExportingStackId": "***",
"Name": "${self:service}-${self:provider.stage}-UNIQUE_EVENTBUS_NAME", <-- same as given above (but will be populated with your service and stage)
"Value": "***"
}
And then if the above is successful, you can reference it with "Fn::ImportValue" like so, e.g.:
"Resource": {
"Fn::ImportValue": "${self:service}-${self:provider.stage}-UNIQUE_EVENTBUS_NAME", <-- same as given above (but will be populated with your service and stage)
}