Previously, I managed to refactor the code cleaner. I want to run the workload or the cron from GitHub Action to the AWS Lambda and Event Bridge.
Migration Steps
- Creating Lambda Project using Amazon.Lambda.Templates. I use Amazon.Lambda.Annotations because it will be similar to my previous console program, and we can use dependency injection.
- Setting up the code dependencies with
Amazon.Lambda.Logging.AspNetCore
,AWSSDK.Extensions.NETCore.Setup
,Amazon.Lambda.Core
,Amazon.Lambda.Serialization.SystemTextJson
, andAmazon.Lambda.Annotations
. I also addBervProject.MergePDF.S3
as the project dependencies. -
Setting up the Dependency Injection. I update the
ConfigureServices
.
var builder = new ConfigurationBuilder() .AddJsonFile("appsettings.json", true) .AddEnvironmentVariables(); //// Add AWS Systems Manager as a potential provider for the configuration. This is //// available with the Amazon.Extensions.Configuration.SystemsManager NuGet package. // builder.AddSystemsManager("/mergepdf/settings"); var configuration = builder.Build(); services.AddSingleton<IConfiguration>(configuration); services.AddLogging(logger => { logger.AddLambdaLogger(); logger.SetMinimumLevel(LogLevel.Debug); }); services.Configure<S3Settings>(configuration.GetSection("S3")); services.AddAWSService<IAmazonS3>(); services.AddScoped<IDownloader, Downloader>(); services.AddScoped<IPdfMerger, PdfMerger>(); services.AddScoped<IUploader, Uploader>(); services.AddScoped<IMerger, Merger>();
-
I remove all the codes in
Functions.cs
exceptDefault
function.
/// <summary> /// Root route that provides information about the other requests that can be made. /// </summary> /// <returns></returns> [LambdaFunction()] public async Task Default(ILambdaContext context) { var generatedTimestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); var destinationPath = $"merged/certificates-{generatedTimestamp}.pdf"; var result = await _merger.Merge("certificates", destinationPath); context.Logger.LogInformation($"Result: {result}"); }
-
The Lambda is ready! I want to use CDK to provision the Lambda and Event Bridge.
var role = Role.FromRoleName(this, "PDFMergeLambdaRole", "S3RoleLambda"); var buildOption = new BundlingOptions() { Image = Runtime.DOTNET_6.BundlingImage, User = "root", OutputType = BundlingOutput.ARCHIVED, Command = new string[] { "/bin/sh", "-c", " dotnet tool install -g Amazon.Lambda.Tools"+ " && cd BervProject.MergePDF.Lambda/src/BervProject.MergePDF.Lambda" + " && dotnet build --configuration Release"+ " && dotnet lambda package --output-package /asset-output/function.zip" } }; var pdfMergerLambdaFunction = new Function(this, "PdfMerger", new FunctionProps { Runtime = Runtime.DOTNET_6, Timeout = Duration.Minutes(1), MemorySize = 512, Handler = "BervProject.MergePDF.Lambda::BervProject.MergePDF.Lambda.Functions_Default_Generated::Default", Code = Code.FromAsset(Directory.GetCurrentDirectory(), new Amazon.CDK.AWS.S3.Assets.AssetOptions { Bundling = buildOption }), Environment = new Dictionary<string, string> { { "S3__BucketName", System.Environment.GetEnvironmentVariable("BucketName") ?? "" } }, Role = role, }); var rule = new Rule(this, "CronRule", new RuleProps { Schedule = Schedule.Cron(new CronOptions { Minute = "0", Hour = "10", Day = "1", Month = "*", Year = "*", }), }); var lambdaFunctionTarget = new Amazon.CDK.AWS.Events.Targets.LambdaFunction(pdfMergerLambdaFunction, new LambdaFunctionProps()); rule.AddTarget(lambdaFunctionTarget);
There are three components. Firstly, for the Execution Role, I use the existing role with the name S3RoleLambda. Secondly, the Lambda itself, I have some configuration to build the Lambda before packing it into a zip file and uploading it to the Lambda. Lastly, in Event Bridge, I integrate the cron rule with Lambda.
-
You can see the architecture like this.
For more details about the code changes, please look here. Thanks to Dmitry Balabanov for helping me figure out my mistake.
Why I'm migrating to Lambda?
- I want to have some data regarding the execution, for example, execution time and logs. I can check the metrics for the data.
- I want to limit access to the S3 bucket only from internal AWS Services. :)
Lessons Learn
It's a great benefit from the community AWS re:post. I will still think about my mistake because I don't understand how BundlingOptions
works. :D Even though it could take a while for a response, depending on your question, I advise asking there.
I just realized BundlingOptions works like a docker build. :)
Thank you
Thank you for reading. If you have some questions or feedback, feel free to comment here.
Top comments (0)