I have found questions to convert terraform to cloudformation , but wondering if there is one for this . I am creating a REST api , with api gateway and lambda ( code below) . the stack is working with cloudformation, trying to convert this to terraform. I have version (AWS::Lambda::Version) and asynconfig (AWS::Lambda::EventInvokeConfig) set up for my lambda , but don't see anything similar in terraform.
lambdaFunc
Type: AWS::Serverless::Function
Properties:
FunctionName: something
...
version:
Type: AWS::Lambda::Version
Properties:
FunctionName:
Ref: lambdaFunc
asyncconfig:
Type: AWS::Lambda::EventInvokeConfig
Properties:
FunctionName:
Ref: lambdaFunc
MaximumRetryAttemps: 0
Qualifier: $LATEST
Related
I am trying to achieve something similar to below in a AWS Cloudformation YAML file:
AWSTemplateFormatVersion: 2010-09-09
testAttribute = "test"
Resources:
Lambda:
Type: AWS::Lambda::Function
Properties:
Runtime: python3.7
Role: !GetAtt iam.Arn
MemorySize: 128
Timeout: 10
Handler: lambda_function.lambda_handler
FunctionName: "testName"+${testAttribute}
Description: 'This is my lambda'
Code:
S3Bucket: myBucket
S3Key: "lambda/testName"+${testAttribute}+".zip"
I know that above isn't quite correct, but I cant find a good answer when searching how to achieve it. Anyone who have some guidance on this matter?
It depends on the use case but if the "variable" would be static and you don't need the change it when deploying the stack, I would suggest an alternative solution, to use the Mappings section.
This allows you to define some static values without sending them when deploying the stack (you will have much cleaner deploy commands, and the logic would be on the template side instead of the deploy side).
In this case, I'm using !Sub intrinsic function with a mapping (you can set multiple variables to be substituted using !Sub):
AWSTemplateFormatVersion: 2010-09-09
Mappings:
attributes:
lambda:
testAttribute: "test"
Resources:
Lambda:
Type: AWS::Lambda::Function
Properties:
Runtime: python3.7
Role: !GetAtt iam.Arn
MemorySize: 128
Timeout: 10
Handler: lambda_function.lambda_handler
FunctionName: !Sub
- "testName${attr}"
- {attr: !FindInMap [attributes, lambda, testAttribute]}
Description: 'This is my lambda'
Code:
S3Bucket: myBucket
S3Key: !Sub
- "lambda/testName${attr}.zip"
- {attr: !FindInMap [attributes, lambda, testAttribute]}
Note: Mappings have a mandatory three-level nesting, take this into consideration while designing your solution
You could use Parameters with a default value, and Sub later in the template:
AWSTemplateFormatVersion: 2010-09-09
Parameters:
testAttribute:
Type: String
Default: test
Resources:
Lambda:
Type: AWS::Lambda::Function
Properties:
Runtime: python3.7
Role: !GetAtt iam.Arn
MemorySize: 128
Timeout: 10
Handler: lambda_function.lambda_handler
FunctionName: !Sub "testName${testAttribute}"
Description: 'This is my lambda'
Code:
S3Bucket: myBucket
S3Key: !Sub "lambda/testName${testAttribute}.zip"
[Edited for typo]
I created a cloud formation stack as below, I'm setting MaximumRetryAttempts: 1 , but once the function is created the retry events is always set to 2 ( attached screenshot) . how can i change the value of this.
HelloWorldLambdaFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: hello-world
Runtime: python3.7
Handler: index.lambda_handler
version:
Type: AWS::Lambda::Version
Properties:
FunctionName: !Ref HelloWorldLambdaFunction
asynconfig:
Type: AWS::Lambda::EventInvokeConfig
Properties:
FunctionName: !Ref HelloWorldLambdaFunction
MaximumRetryAttempts: 1
Qualifier: !GetAtt version.Version
The code looks fine. However, it seems to me that you are viewing $LATEST version in the console.
However, you set the asynconfig for version 1. Thus, in the console you have to explicitly select the correct lambda function version:
Update
To use latest version:
asynconfig:
Type: AWS::Lambda::EventInvokeConfig
Properties:
FunctionName: !Ref HelloWorldLambdaFunction
MaximumRetryAttempts: 1
Qualifier: $LATEST
I am learning working with AWS lambda and api gateway. I started with sam cli, initialized a hello world template ( code below). when deploy.yaml file is generated via - sam package ... command and stack is generated via cloud formation , it looks like this already generates an api end point. I wanted to create an api gateway with resource, methods, usage plan , api key and so forth. so I started adding following resources to the original template. How can i wire up my api gateway with the lambda function.
ApiGatewayRestApi:
Type: AWS::ApiGateway::RestApi
Properties:
ApiKeySourceType: HEADER
Description: An API Gateway with a Lambda Integration
EndpointConfiguration:
Types:
- EDGE
Name: lambda-api
ApiGatewayResource:
Type: AWS::ApiGateway::Resource
Properties:
ParentId: !GetAtt ApiGatewayRestApi.RootResourceId
PathPart: 'lambda'
RestApiId: !Ref ApiGatewayRestApi
ApiGatewayMethod:
Type: AWS::ApiGateway::Method
Properties:
ApiKeyRequired: false
AuthorizationType: NONE
HttpMethod: GET
ResourceId: !Ref ApiGatewayResource
RestApiId: !Ref ApiGatewayRestApi
original template
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
simple-node-api
Sample SAM Template for simple-node-api
Globals:
Function:
Timeout: 3
Resources:
HelloWorldfunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello-world/
Handler: app.lambdaHandler
Runtime: python3.7
Events:
HelloWorld:
Type: Api
Properties:
Path: /{proxy+}
Method: get
Outputs:
HelloWorldApi:
Description: API Gateway endpoint URL for Prod stage for Hello World function
Value:
Fn::Sub: https://${ServerlessHttpApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
HelloWorldfunction:
Description: Express Backend Lambda Function ARN
Value: !Sub HelloWorldfunction.Arn
HelloWorldFunctionIamRole:
Description: Implicit IAM Role created for Hello World function
Value: !Sub HelloWorldFunctionRole.Arn
I am creating a cloudformation template, with few resources, couple of lambda functions , S3 bucket.see code below, it is work on progress and so far I have a S3 bucket and a lamda function triggered by S3. we have vpc defined in our team that we are supposed to use. I would like to add private subnet under that vpc for my lambda function and assign public subnet for the s3 bucket. how to get reference of the vpc , and pass it to my template and use it? sample code will be helpful.
AWSTemplateFormatVersion: 2010-09-09
Resources:
# S3 Bucket
S3Bucket:
Type: AWS::S3::Bucket
# Functions
S3-Lambda-trigger:
Type: AWS::Serverless::Function
Properties:
CodeUri: .
Handler: lambda.handler
Description: s3 object creation triggers lambda
Runtime: nodejs12.x
Events:
S3Bucket:
Type: S3
Properties:
Bucket: !Ref S3Bucket
Events: 's3:ObjectCreated:*'
# Permissions
Allow-lamda-invocation-s3:
Type: AWS::Lambda::Permission
Properties:
Action: 'lambda:InvokeFunction'
FunctionName: !Ref S3-Lambda-trigger
Principal: s3.amazonaws.com
SourceArn: !GetAtt S3Bucket.Arn
how to get reference of the vpc , and pass it to my template and use it?
One way would be through AWS-Specific Parameter Types, specifically AWS::EC2::VPC::Id, in a Parameters section.
For example:
AWSTemplateFormatVersion: 2010-09-09
Parameters:
VPCId:
Type: AWS::EC2::VPC::Id
Resources:
MySubnet:
Type: AWS::EC2::Subnet
Properties:
# other properties
VpcId: !Ref VPCId
Thanks to this, when creating the stack in AWS Console, you would be able to choose existing VPCId to pass to the template.
I'm trying to set up a local dev environment for my Lambda functions using SAM. I had everything working until I added a reference to a layer in my configuration.
I followed the instructions here: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-layers.html. I added my ARN for my layer version in my template.ymal as follows:
# template.ymal
TestLayerFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: TestLayer
Role: arn:aws:iam::111111111111:role/ReadStreamingTable
CodeUri: src/streaming/test-layer/
Handler: app.handler
Runtime: nodejs8.10
Layers:
- arn:aws:lambda:eu-west-1:111111111111:layer:Global:7
However when running a "sam local invoke" I get the following error:
botocore.exceptions.EndpointConnectionError: Could not connect to the endpoint URL:
"https://lambda.eu-west-1a.amazonaws.com/2018-10-31/layers/arn%3Aaws%3Alambda%3Aeu-west-1%3A111111111111%3Alayer%3AGlobal/versions/7"
The way I've added the layer ARN in the configuration seems to be exactly how they do it in the example so I'm not sure what is causing the error.
I know it's not exactly a solution but can you not have your layer as part of your SAM file?
If you have a look on this article on the AWS site they use both the layer and the lambda function on the same yaml file so you'd end up with something like this:
Resources:
TempConversionFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello-world/
Handler: app.lambdaHandler
Layers:
- !Ref TempConversionDepLayer
Events:
HelloWorld:
Type: Api
Properties:
Path: /{conversion}/{value}
Method: get
TempConversionDepLayer:
Type: AWS::Serverless::LayerVersion
Properties:
LayerName: sam-app-dependencies
Description: Dependencies for sam app [temp-units-conv]
ContentUri: dependencies/
CompatibleRuntimes:
- nodejs6.10
- nodejs8.10
LicenseInfo: 'MIT'
RetentionPolicy: Retain