I have this for example in my template:
ApiGatewayRestApi:
Type: AWS::ApiGateway::RestApi
Properties:
Name: MyApi
Description: My AWS API Gateway config
Body:
# INSERT swagger.yml content here
Is there some cloudformation function I can use to read swagger.yml in or attach it under "Body:"? So I can keep it in another file and my template doesn't become huge.
There's a Fn::Transform function that allows you to call different Cloudformation macros to process your templates. One of those macros is AWS::Include
Heres an example:
Resources:
APIGateway:
Fn::Transform:
Name: AWS::Include
Parameters:
Location:
Fn::Sub: s3://partials-bucket/${PartialsEnv}/resources/api-gateway.yaml
Here api-gateway.yaml will have the full definition of your resource.
You can use this function in the same way as other intrinsic functions. The only caveat is AWS::Include will only work with files hosted in S3 so you'll need to upload your partials separatedly.
You can try the BodyS3Location .
The Amazon Simple Storage Service (Amazon S3) location that points to
an OpenAPI file, which defines a set of RESTful APIs in JSON or YAML
format.
For Example
"BodyS3Location": {
"Bucket": "you_bucket_name",
"Key": "filename.yaml"
}
For more see BodyS3Location
Related
I'm trying to deploy an AWS API Gateway and a Lambda function using Gitlab CICD pipeline using sam template. Since I want individual stacks for each environment, the Path property under Events of the Lambda function needs to change with each environment. Below is my code for implementing this:
Mappings:
StackEnv:
stack-dev:
envm: "dev"
stack-qa:
envm: "qa"
Resources:
MyFunction:
Type: AWS::Serverless::Function
Properties:
Events:
MyAPI:
Type: Api
Properties:
Path:
Fn::Sub:
- "/${path}"
- path: !FindInMap [StackEnv, !Ref AWS::StackName, envm]
However, while running the pipeline, an error is returned:
[InvalidResourceException('MyFunction', "Event with id [MyAPI] is invalid. Api Event must have a String specified for 'Path'.")]
Is this behaviour expected while passing in values using !FindInMap? Is there any other way of dynamically passing in the value for Path?
I've created AWS Lambda in C# using Visual Studio that returns some JSON from the API endpoint. Now I want to run that lambda locally. All the examples use AWS SAM, but they create a new function using the SAM template.
When I run the command sam local start-lambda I get an error saying that the template isn't found. So what is certain is that I need template.yaml, but I'm not sure is there a way to generate this template for existing Lambda?
Any help is appreciated!
Check out the Template Anatomy resource on the AWS documentation.
You might find this example helpful (it's greatly simplified). I use NodeJS for development, but the differences between programming languages when you're creating a SAM Template are trivial. The example is an outline for a simple Lambda function someFunction being invoked by an API Gateway (HTTP) event.
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: My Serverless Application
Parameters:
# Manually define this in AWS IAM for just the services needed.
lambdaExecutionRole:
Description: 'Required. The role used for lambda execution.'
Type: 'String'
Default: 'arn:aws:iam::nnnnnnnnnnnn:role/LambdaExecutionRole'
Globals:
Function:
Runtime: nodejs10.x
# Environment:
# Variables:
# NODE_ENV: test
# DEBUG: myapp:foo
Resources:
performSomeFunction:
Type: 'AWS::Serverless::Function'
Properties:
FunctionName: performSomeFunction
Handler: lambda.someFunction
CodeUri: ./
Description: description of the function being performed
MemorySize: 256
Timeout: 60
Role:
Ref: lambdaExecutionRole
Events:
# API Gateway proxy endpoint.
ProxyApiRoot:
Type: Api
Properties:
Path: '/'
Method: ANY
ProxyApiGreedy:
Type: Api
Properties:
Path: '/{proxy+}'
Method: ANY
As you're getting started with AWS Lambda, one of the big concepts to keep in mind is how your function will be triggered. Functions are triggered by different kinds of events, and there can be many many different types of events. I tend to use API Gateway, Simple Queue Service and CloudWatch Events to trigger mine, but it entirely depends on your use case.
It turned out that you can export Lambda function, and get the generated .yaml template, which was exactly what I needed.
I have a cloudformation template that I would like to embed in the resources section but the existing cloudformation template contains parameters. Is it possible to handle this?
resources: Resources: ${file(cloudformation-resources.yaml)}
I am trying to create IAM roles and Lambda functions using the template. and the template takes the environment name, security groupId, bucket name where the lambda code resides as passing as parameters. and I am using !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/ to get the log group inside the template.
But I am ending up with an error " Invalid variable reference syntax for variable AWS::Region. You can only reference env vars, options, & files. You can check our docs for more info."
How can I handle this using serverless.yaml file.
Here is the serverless.yaml which i am trying
service: sample
frameworkVersion: ">=1.0.0 <2.0.0"
plugins:
- serverless-pseudo-parameters
provider:
name: aws
stackName: "${opt:stackName,env:StackName}"
parameters:
SecurityGroupId: "${opt:SecurityGroupId,env:SecurityGroupId}"
Subnets: "${opt:Subnets,env:Subnets}"
environment: "${opt:environment,env:environment}"
LambdacodeBucketName: "${opt:LambdacodeBucketName,env:LambdacodeBucketName}"
resources:
- ${file(test/template.yaml)}
Thanks in advance
I have a project to deploy a appsync API using this plugin (https://github.com/sid88in/serverless-appsync-plugin). And I am looking for a solution to split all infra. into multiple stacks (multiple serverless.yml file).
My project structure looks like:
main/serverless.yml
dataSources/serverless.yml
resolvers/serverless.yml
schema/serverless.yml
The main folder only deploys the Appsync instance and logging and authentication. It doesn't include any schema, resolvers etc.
And other folders each of which is to deploy schema, resolvers, dataSources to the Appsync deployed by the main folder. In these folders, they need to import the appsync infra in order to attach these resolvers.
That means there will be multiple cloudformation stacks created and using cross stack reference among them. I wonder how I can make this by using this plugin.
In general you can export CF variables that you might need in other stacks using Output such as:
resources:
Resources:
NotesTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: notes
# ...
Outputs:
Value:
Ref: NotesTable
Export:
Name: NotesTableName
And in another file read them like: 'Fn::ImportValue': NotesTableName
I am using examples from a wonderful source:
https://serverless-stack.com/chapters/cross-stack-references-in-serverless.html
Your example is AppSync...
You can define your data sources such as DynamoDb in a dedicated stack and in the AppSync sources only need to reference them by name such as:
- type: AMAZON_DYNAMODB
name: ItemSource
description: Item table
config:
tableName: ItemTable // Whatever name you used in your DynamoDb stack
For lambdas you would use the Output/import. In resolvers:
- type: AWS_LAMBDA
name: SomeLambdaSource
config:
functionName: someSource
lambdaFunctionArn:
Fn::ImportValue: SomeLambdaSource
In your lambda stack:
functions:
someSource:
name: SomeSource
handler: src/handlers/someSource.handler
resources:
Outputs:
SomeSource:
Value:
Fn::GetAtt:
- SomeSource
- Arn
Export:
Name: SomeSource
has somebody a hint how I have to transform !Ref und !Sub from CloudFormation into serverless.yml.
resources:
Resources:
AthenaCreateDatabaseQuery:
Type: 'AWS::Athena::NamedQuery'
Properties:
Description: Run this query to initialize the Athena database
QueryString: "CREATE DATABASE IF NOT EXISTS $(self:custom.etlDatabase};"
Database: ${self:custom.etlDataBase}
In Cloudformation the QueryString Property starts with !Sub and
the Database Property with !Ref.
Thanks Christian
!Sub isn't currently supported natively by serverless.com (see this issue on GitHub) but you can use the following plugin https://gitlab.com/kabo/serverless-cf-vars
Whenever you want the cloudformation template to have a string that contains ${}, simply use #{} instead, and it will get transformed into correct ${} (with Fn::Sub inserted for you) in the cloudformation template before deployment.
Or use a custom variable syntax as suggested here. Both require the use of Fn::Sub and Fn::Ref in yaml instead of the short form !Sub and !Ref