DEV Community

Cover image for Migrating .NET Console App Cron from GitHub Action to AWS Lamda

Migrating .NET Console App Cron from GitHub Action to AWS Lamda

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

  1. 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.
  2. Setting up the code dependencies with Amazon.Lambda.Logging.AspNetCore, AWSSDK.Extensions.NETCore.Setup, Amazon.Lambda.Core, Amazon.Lambda.Serialization.SystemTextJson, and Amazon.Lambda.Annotations. I also add BervProject.MergePDF.S3 as the project dependencies.
  3. Setting up the Dependency Injection. I update the ConfigureServices.

            var builder = new ConfigurationBuilder()
                                        .AddJsonFile("appsettings.json", true)
            //// 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.AddLogging(logger =>
            services.AddScoped<IDownloader, Downloader>();
            services.AddScoped<IPdfMerger, PdfMerger>();
            services.AddScoped<IUploader, Uploader>();
            services.AddScoped<IMerger, Merger>();
  4. I remove all the codes in Functions.cs except Default function.

        /// <summary>
        /// Root route that provides information about the other requests that can be made.
        /// </summary>
        /// <returns></returns>
        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}");
  5. 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[] {
                    " 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/"
            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());
  6. 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.

  7. You can see the architecture like this.


  8. 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?

  1. I want to have some data regarding the execution, for example, execution time and logs. I can check the metrics for the data.
  2. 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.

Thanks gif

Top comments (0)