Use Cloudformation4dotNET (cf4dotNet) to create the AWS Cloudformation templates you need to push your code on AWS (the idea is to only have to work on the code side and run cf4dotnet
on your deployment pipeline).
# create a cf4dotnet demo project (1 API Gateway Lambda and 1 standalone Lambda )
dotnet new -i NachoColl.Cloudformation4dotNET.Templates
dotnet new cf4dotnet -n MyDemoProject -as MyDemoAssemblyName -t MyAWSTagCode
# build your code and check everything is ok
dotnet publish ./src -o ../artifact --framework netcoreapp2.1 -c Release
# install cf4dotnet tool
dotnet tool install --global NachoColl.Cloudformation4dotNET --version 1.0.*
# get the required AWS Cloudformation templates to deploy your code on AWS
dotnet cf4dotnet api E:\<your-project-path>\artifact\MyDemoAssemblyName.dll -e prod
You get sam-base.yml and sam-prod.yml to deploy your code on AWS.
Cloudformation4dotNET uses reflection to check for functions that you want to deploy on AWS and outputs the required resources definition.
For example, if you mark a function as follows:
[Cloudformation4dotNET.APIGateway.APIGatewayResourceProperties("utils/status", EnableCORS=true, TimeoutInSeconds=5)]
public APIGatewayProxyResponse CheckStatusFunction(...) {
...
}
you get the related resources output:
...
CheckStatusFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: myapi-CheckStatus
Handler: MyDemoAssemblyName::MyDemoProject.APIGateway::CheckStatus
Role: !Ref myAPILambdaExecutionRole
Timeout: 5
statusAPIResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref myAPI
ParentId: !Ref utilsAPIResource
PathPart: status
CheckStatusAPIMethod:
Type: AWS::ApiGateway::Method
Properties:
RestApiId: !Ref myAPI
ResourceId: !Ref statusAPIResource
HttpMethod: POST
AuthorizationType: NONE
Integration:
Type: AWS_PROXY
IntegrationHttpMethod: POST
Uri: !Sub "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${CheckStatusFunction.Arn}:${!stageVariables.lambdaAlias}/invocations"
Credentials: !GetAtt myAPILambdaExecutionRole.Arn
...
To check how it works, I recommend that you install the available 'dotnet new' templates,
dotnet new -i NachoColl.Cloudformation4dotNET.Templates
and call dotnet new cf4dotnet
to get a ready-to-go project that will contain the next files:
MyApi.cs
, a simple AWS API Gateway functions class,
namespace MyAPI
{
public class APIGateway
{
/* A function that will get APIGateway + Lambda resources created. */
[Cloudformation4dotNET.APIGateway.APIGatewayResourceProperties("utils/status", APIKeyRequired=true, EnableCORS=true, TimeoutInSeconds=2)]
public APIGatewayProxyResponse CheckStatus(APIGatewayProxyRequest Request, ILambdaContext context) => new APIGatewayProxyResponse
{
StatusCode = 200,
Headers = new Dictionary<string,string>(){{"Content-Type","text/plain"}},
Body = String.Format("Running lambda version {0} {1}.", context.FunctionVersion, JsonConvert.SerializeObject(Request?.StageVariables))
};
}
}
MyLambdas.cs
, to code standalone Lambdas,
namespace MyAPI {
public class Lambdas
{
/* A function that will get Lambda resources created (only) */
[Cloudformation4dotNET.Lambda.LambdaResourceProperties(TimeoutInSeconds=20)]
public void Echo(Object Input, ILambdaContext Context) => Context?.Logger?.Log(JsonConvert.SerializeObject(Input));
}
}
- and two cloudformation templates,
sam.yml
andsamx.yml
, that are used as your project base cloudformation templates.
Once your code is ready, install and run dotnet-cf4dotnet indicating your code file, the environment name and the version number (version number is used to create new AWS Lambda versions):
dotnet-cf4dotnet <your-code-dll-file> -o <output-path> -b <build-version-number> -e <environment-name> -n <api-name> -r <rate-limit> -b <burst-limit>
As an example, if you run the command on the provided template project,
dotnet cf4dotnet api D:\Git\projects\cf4dotnet\dotnet-cf4dotnet\demo\artifact\MyDemoAssemblyName.dll
you get the next sam-base.yml and sam-prod.yml cloudformation templates ready to get deployed on AWS:
This is an initial 1.0.x version that fits my deployment needs! I will check for issues and add new features as soon as I need them. Please feel free to push/ask for improvements, questions or whatever.
While you can use cf4dotnet
to automatically build your dotNET code required AWS Cloudformation templates, those are the settings you can define for now:
- set a 2 level path for your API Gateway resources, e.g.
contact/get
orutils/status
- define if an API Key is required (
APIKeyRequired=true
) - enable CORS (
EnableCORS=true
) , that will add the next rules:method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,IdentityPoolId,IdentityId'" method.response.header.Access-Control-Allow-Methods: "'POST,OPTIONS'" method.response.header.Access-Control-Allow-Origin: "'*'"
- set an AWS Cognito user pool as an API authorizer (
Autorizer="us-east-1_xxxxxx"
).
- set the related AWS Lambdas timeout.