{"id":19809561,"url":"https://github.com/didier-durand/lambda-cobol","last_synced_at":"2025-06-12T11:35:24.281Z","repository":{"id":42053816,"uuid":"338232175","full_name":"didier-durand/lambda-cobol","owner":"didier-durand","description":"Serverless Legacy Modernization : AWS Lambda + Cobol","archived":false,"fork":false,"pushed_at":"2023-03-02T01:36:13.000Z","size":987,"stargazers_count":36,"open_issues_count":2,"forks_count":11,"subscribers_count":4,"default_branch":"main","last_synced_at":"2023-03-05T22:02:07.083Z","etag":null,"topics":["aws","cloudformation","cobol","lambda","legacy","mainframe","modernization","nfr","serverless","serverless-framework"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/didier-durand.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-02-12T05:27:17.000Z","updated_at":"2023-03-05T22:02:07.084Z","dependencies_parsed_at":"2023-02-14T13:05:37.405Z","dependency_job_id":null,"html_url":"https://github.com/didier-durand/lambda-cobol","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/didier-durand%2Flambda-cobol","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/didier-durand%2Flambda-cobol/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/didier-durand%2Flambda-cobol/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/didier-durand%2Flambda-cobol/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/didier-durand","download_url":"https://codeload.github.com/didier-durand/lambda-cobol/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224245658,"owners_count":17279649,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","cloudformation","cobol","lambda","legacy","mainframe","modernization","nfr","serverless","serverless-framework"],"created_at":"2024-11-12T09:17:22.666Z","updated_at":"2024-11-12T09:17:23.368Z","avatar_url":"https://github.com/didier-durand.png","language":"Shell","readme":"\u003cimg src=\"https://github.com/didier-durand/lambda-cobol/blob/main/img/aws-lambda.png\" height=\"110\"\u003e \u003cimg src=\"https://github.com/didier-durand/lambda-cobol/blob/main/img/cobol-logo.jpeg\" height=\"110\"\u003e\n\n# Legacy Serverless Modernization: Cobol and AWS Lambda functions\n\n![Cobol Lambdas on AWS](https://github.com/didier-durand/lambda-cobol/workflows/Cobol%20Lambdas%20on%20AWS/badge.svg)\n\n* [Goal](README.md#goal)\n* [Cobol](README.md#cobol)\n* [Lambda Functions and Serverless Architecture](README.md#lambda-functions-and-serverless-architecture)\n* [Serverless Application Model](README.md#serverless-application-model)\n* [Workflow and Components](README.md#workflow-and-components)\n* [Fork and Setup](README.md#fork-and-setup)\n* [Execution Highlights](README.md#execution-highlights)\n\n\n## Goal\n\nThis repository implements a fully automated [Github Workflow](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions) to deploy \nand run as an [AWS Lambda function](https://aws.amazon.com/lambda/) a ['Hello World' Cobol program](hello-world.cob) compiled with [GnuCOBOL](https://en.wikipedia.org/wiki/GnuCOBOL). \nGnuCOBOL compiles the source code as a native x86 module depending on the libcob library. Both are packaged and uploaded as a [custom Lambda runtime](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-walkthrough.html)\nby the workflow. The workflow is scheduled by cron on a minimalweekly basis to make sure that it keeps working.\n\nThe [benefits of the serverless architecture](https://aws.amazon.com/lambda/serverless-architectures-learn-more/) are not reserved to newly written \napplications. The purpose of this showcase is to demonstrate how those benefits can be combined with legacy code, still \"doing the job\" and \ndelivering solid business value, to further extend its life.\n\nThe deployed Cobol program is accessible over http via the definition of a REST service on the [AWS API gateway](https://aws.amazon.com/api-gateway/). The results of the various executions of the workflow in this repo can be seen in [Actions](https://github.com/didier-durand/lambda-cobol/actions) tab here above. Also, some highlights of last execution are reported in last section of this page.\n\nThis initial use case will be refined in upcoming versions by adding a database, calling subprograms, etc.\n\nLambda functions were chosen here because they are the canonical service proposed by AWS [to support the strategic serverless architecture](https://aws.amazon.com/serverless/). \nIts virtues are described below. Lambdas can execute [uninterruptedly at scale](https://aws.amazon.com/blogs/compute/operating-lambda-application-design-scaling-and-concurrency-part-2/) \nwith no effort on the customer side. \n\nThe purpose of this unusual / unexpected use case with Cobol is to trigger further ideas around \"serverless legacy\". The Cobol numbers \nbelow will demonstrate that it makes quite a lot of sense to reuse the massive existing assets on a modern cloud platform to further extend their \nlife and leverage them in new ways. It's especially attractive given the incredibly affordable costs of Lambdas when compared to costs of mainframe Mips!\n\nFeel free to fork and replicate this repo in your own environment (see Setup section below). All feedback and suggestions for extensions welcome! (Please, open a [Github issue ticket](https://github.com/didier-durand/lambda-cobol/issues) for this purpose). If you like this repository, please, give it a star!\n\n## Cobol\n\n[Cobol](https://en.wikipedia.org/wiki/COBOL) was initially specified more than 60 years ago by [Grace Hopper](https://en.wikipedia.org/wiki/Grace_Hopper), \naka \"the grandmother of Cobol\". This language remains quite vivid despite its age. It is still heavily used in [mainframe shops](https://en.wikipedia.org/wiki/Mainframe_computer) \nlike banks, insurance companies, administrations, etc.\n\nFor example, issues at the beginning of the Covid-19 pandemic have shown how critical this programming language remains to run daily operations in \nUS administrations. Old Cobol applications are still heavily used by several states to [process unemployment claims](https://www.shrm.org/hr-today/news/hr-news/pages/desperate-need-for-cobol-programmers-underlines-importance-of-workforce-planning.aspx).\n\nA [report of 2017 by Thomson Reuters](http://fingfx.thomsonreuters.com/gfx/rngs/USA-BANKS-COBOL/010040KH18J/index.html) states that 200+ billion \nlines of Cobol are still in operation. It also asserts that 43% of banking systems are built on Cobol and that 95% of ATM swipes rely on this language.\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"http://fingfx.thomsonreuters.com/gfx/rngs/USA-BANKS-COBOL/010040KH18J/index.html\"\u003e\n\u003cimg src=\"img/thomson-reuters-cobol-numbers.jpeg\" height=\"380\" /\u003e\n\u003c/a\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n\u003cb\u003eCobol Use in Finance Service Industry (Thomson Reuters)\u003c/b\u003e\n\u003c/p\u003e\n\nAnd this importance is not going to decline anytime soon: [IBM reports](https://techchannel.com/Enterprise/10/2019/closing-cobol-programming-skills-gap) that more than 5 billion additional lines are produced each year!\n\n## Lambda Functions and Serverless Architecture\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://github.com/didier-durand/lambda-cobol/blob/main/img/lambda-arch.jpeg\" height=\"320\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n\u003cb\u003eCanonical Lambda architecture (Python example)\u003c/b\u003e\n\u003c/p\u003e\n\nAs per AWS documentation: *\"AWS Lambda is a serverless compute service that lets you run code without provisioning or managing servers, \ncreating workload-aware cluster scaling logic, maintaining event integrations, or managing runtimes. With Lambda, you can run code for virtually \nany type of application or backend service - all with zero administration. Just upload your code as a ZIP file or container image, and \nLambda automatically and precisely allocates compute execution power and runs your code based on the incoming request or event, for any scale of \ntraffic.\"*\n\nIt means that AWS Lambda service does the heavyweight lifting to the benefit of its users: all the [non-functional requirements (NFRs)](https://en.wikipedia.org/wiki/Non-functional_requirement) \nlike high availability, scalability, security, resource and performance optimization, etc. are implemented by the AWS experts. Customer teams can \nremain focused on functional code and rely on this scalable platform to run their applications uninterruptedly at scale.\n\nThis serverless architecture is the optimal solution to run applications with very stringent [SLAs](https://en.wikipedia.org/wiki/Service-level_agreement) \n(incl. extremely low [RTO](https://en.wikipedia.org/wiki/Disaster_recovery#Recovery_Time_Objective) \u0026 [RPO](https://en.wikipedia.org/wiki/Disaster_recovery#Recovery_Point_Objective)). \nThose highly demanding SLAs are usually out of reach of most organizations by themselves. With Lambdas, it become extremely easy as AWS encapsulates \nits domain expertise in the underlying platform design and makes the thorough investments to deploy and operate the underlying infrastructure \nin a multi-tenant fashion. \n\nAdditionally, the service strictly respects the \"pay-per-use\" model: AWS will charge only for the memory consumption and \nexecution time of executed Lambdas. If they remain unused, no cost!\n\nThese virtues of serverless architecture make it the ideal target when the functional needs and technical requirements allow for it. It should be the \nprimary goal of any corporate cloud architect to make maximum use of managed serverless features.\n\n## Serverless Application Model\n\nAWS open sourced at end of 2016 the [Serverless Application Model (SAM) framework](https://github.com/aws/serverless-application-model) to [describe \nsuch serverless applications](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html) made of multiple \nLamdba functions with all their dependencies. The main purpose of SAM is to reduce the effort by developers when creating such applications. \nRequired artefacts and definitions are specified at a high-level of abstraction. The SAM processor on AWS, in collaboration with the \n[CloudFormation service](https://aws.amazon.com/cloudformation/), which it extends, will take care of all the low-level definitions of corresponding required AWS resources to deploy the Lambda function and make it \npublicly accessible through the API gateway. \n\nThis allows the implementation of [Infrastructure-as-Code](https://en.wikipedia.org/wiki/Infrastructure_as_code) best practices.\n\nThe SAM model for our Cobol Lambda is in the file [lambda-cobol-sam.yaml](lambda-cobol-sam.yaml). It contains a single [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html) with its parameters. During deployment, SAM \u0026 CloudFormation expand it into 6 more granular resources that can be located with \"Resource creation Initiated\" in last section below.\n\n## Workflow and Components\n\nImplemented as a Github Action, the workflow  - scripted in [lambda-cobol.sh](lambda-cobol.sh) - comprises following key steps:\n\n1) A Docker image [is constructed](Dockerfile) to install the GnuCOBOL compiler and its dependencies on top of the base Amazon Linux image. The \npurpose of such a container is to leverage the isolation provided by containers. Consequently, the build environment is fully controlled.\n2) This Cobol builder imports the source code of [hello-world.cob](hello-world.cob) and compiles it to generate an x86 native binary named ```hello-world```.\n3) This binary is packaged, via SAM CLI, with other required runtime artefacts. The libcob library is required by GnuCOBOL. The shell script ```bootstrap```(name \nimposed by specifications) implements the requirements of [custom Lambda runtimes](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-walkthrough.html).\n4) This package is deployed on the Lambda service via [SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html).\n5) The SAM description is processed by AWS Lambda and CloudFormation to deploy the function.\n6) SAM CLI is used to check proper deployment.\n7) SAM CLI invokes the function synchronously.\n8) curl calls the URL with the obtained DNS to validate the proper execution of the newly deployed Lambda. The URL for curl is built   following template: https://$API_ID.execute-api.$AWS_REGION.amazonaws.com/Prod/$LAMBDA_NAME. $API_ID is dynamic and obtained via a ```aws apigateway get-rest-apis``` CLI command.\n\nWhen a previous deployment of the CloudFormation stack is active, it gets deleted just before the SAM build to trigger the entire CloudFormation deployment process.\n\n**Note:** the version of GnuCOBOL currently used is v2.2. A [version 3.1 was published](https://sourceforge.net/projects/gnucobol/files/gnucobol/) in late December, 2020. But, its libcob runtime library has hardwired dependencies on very recent Linux system libraries, that are not yet available with proper version in Lambda runtime. We'll bump to newest GnuCOBOL when Lambda runtime gets updated. The official repository for all available versions of GnuCOBOL is [here]( https://ftp.gnu.org/gnu/gnucobol/?C=M;O=D).\n\n## Fork and Setup  \n\nWhen you fork this repository to run it on your own, you will need to recreate three [Github secrets](https://docs.github.com/en/actions/configuring-and-managing-workflows/using-variables-and-secrets-in-a-workflow) in your own repository for workflows to work properly: \n\n- ${{ secrets.AWS_ACCESS_KEY_ID }}: the access key under which the workflow will run\n- ${{ secrets.AWS_SECRET_ACCESS_KEY }}: the secret key validating the use of the above access key\n- ${{ secrets.AWS_REGION }}: the region in which you want the workflow to be deployed and executed\n\nThe credentials given to this identity via [AWS IAM](https://aws.amazon.com/iam/) must grant permissions to deploy and run Lambda functions as well \nas create corresponding API gateway definitions. In addition, an S3 bucket must be created to import the uploaded artefacts in AWS when they get deployed.\n\n## Execution Highlights\n\nBelow are the logs of the last execution related to the Lamdba service operated from SAM CLI:\n\n\n\n```\n \n### execution date: Thu Mar  9 01:33:05 UTC 2023\n \n### Check existing Lambdas functions...\n{\n    \"Functions\": [\n        {\n            \"FunctionName\": \"Hello-world-Python\",\n            \"FunctionArn\": \"arn:aws:lambda:us-east-1:514764745669:function:Hello-world-Python\",\n            \"Runtime\": \"python3.8\",\n            \"Role\": \"arn:aws:iam::514764745669:role/service-role/Hello-world-Python-role-lyqky200\",\n            \"Handler\": \"lambda_function.lambda_handler\",\n            \"CodeSize\": 299,\n            \"Description\": \"\",\n            \"Timeout\": 3,\n            \"MemorySize\": 128,\n            \"LastModified\": \"2021-02-06T10:48:38.267+0000\",\n            \"CodeSha256\": \"fI06ZlRH/KN6Ra3twvdRllUYaxv182Tjx0qNWNlKIhI=\",\n            \"Version\": \"$LATEST\",\n            \"TracingConfig\": {\n                \"Mode\": \"PassThrough\"\n            },\n            \"RevisionId\": \"d90d1b6d-667c-46d9-b9d5-e7fdefdfc004\",\n            \"PackageType\": \"Zip\",\n            \"Architectures\": [\n                \"x86_64\"\n            ],\n            \"EphemeralStorage\": {\n                \"Size\": 512\n            },\n            \"SnapStart\": {\n                \"ApplyOn\": \"None\",\n                \"OptimizationStatus\": \"Off\"\n            }\n        }\n    ]\n}\n \n### Starting SAM build...\n\nBuild Succeeded\n\nBuilt Artifacts  : build\nBuilt Template   : build/template.yaml\n\nCommands you can use next\n=========================\n[*] Validate SAM template: sam validate\n[*] Invoke Function: sam local invoke -t build/template.yaml\n[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch\n[*] Deploy: sam deploy --guided --template-file build/template.yaml\n \n### Starting SAM deployment...\n\n\tDeploying with following values\n\t===============================\n\tStack name                   : lambda-cobol-stack\n\tRegion                       : us-east-1\n\tConfirm changeset            : False\n\tDisable rollback             : False\n\tDeployment s3 bucket         : net.didier-durand.lambda-code\n\tCapabilities                 : [\"CAPABILITY_IAM\"]\n\tParameter overrides          : {}\n\tSigning Profiles             : {}\n\nInitiating deployment\n=====================\n\nWaiting for changeset to be created..\nCloudFormation stack changeset\n-------------------------------------------------------------------------------------------------\nOperation                LogicalResourceId        ResourceType             Replacement            \n-------------------------------------------------------------------------------------------------\n+ Add                    HelloWorldCobolGetReso   AWS::Lambda::Permissio   N/A                    \n                         urcePermissionProd       n                                               \n+ Add                    HelloWorldCobolRole      AWS::IAM::Role           N/A                    \n+ Add                    HelloWorldCobol          AWS::Lambda::Function    N/A                    \n+ Add                    ServerlessRestApiDeplo   AWS::ApiGateway::Deplo   N/A                    \n                         ymentaf1c952223          yment                                           \n+ Add                    ServerlessRestApiProdS   AWS::ApiGateway::Stage   N/A                    \n                         tage                                                                     \n+ Add                    ServerlessRestApi        AWS::ApiGateway::RestA   N/A                    \n                                                  pi                                              \n-------------------------------------------------------------------------------------------------\n\nChangeset created successfully. arn:aws:cloudformation:us-east-1:514764745669:changeSet/samcli-deploy1678325694/7f9ee7f0-fc45-4a76-a364-87bc073b74ec\n\n\n2023-03-09 01:35:06 - Waiting for stack create/update to complete\n\nCloudFormation events from stack operations (refresh every 0.5 seconds)\n-------------------------------------------------------------------------------------------------\nResourceStatus           ResourceType             LogicalResourceId        ResourceStatusReason   \n-------------------------------------------------------------------------------------------------\nCREATE_IN_PROGRESS       AWS::IAM::Role           HelloWorldCobolRole      -                      \nCREATE_IN_PROGRESS       AWS::IAM::Role           HelloWorldCobolRole      Resource creation      \n                                                                           Initiated              \nCREATE_COMPLETE          AWS::IAM::Role           HelloWorldCobolRole      -                      \nCREATE_IN_PROGRESS       AWS::Lambda::Function    HelloWorldCobol          -                      \nCREATE_IN_PROGRESS       AWS::Lambda::Function    HelloWorldCobol          Resource creation      \n                                                                           Initiated              \nCREATE_COMPLETE          AWS::Lambda::Function    HelloWorldCobol          -                      \nCREATE_IN_PROGRESS       AWS::ApiGateway::RestA   ServerlessRestApi        -                      \n                         pi                                                                       \nCREATE_IN_PROGRESS       AWS::ApiGateway::RestA   ServerlessRestApi        Resource creation      \n                         pi                                                Initiated              \nCREATE_COMPLETE          AWS::ApiGateway::RestA   ServerlessRestApi        -                      \n                         pi                                                                       \nCREATE_IN_PROGRESS       AWS::ApiGateway::Deplo   ServerlessRestApiDeplo   -                      \n                         yment                    ymentaf1c952223                                 \nCREATE_IN_PROGRESS       AWS::Lambda::Permissio   HelloWorldCobolGetReso   -                      \n                         n                        urcePermissionProd                              \nCREATE_IN_PROGRESS       AWS::Lambda::Permissio   HelloWorldCobolGetReso   Resource creation      \n                         n                        urcePermissionProd       Initiated              \nCREATE_IN_PROGRESS       AWS::ApiGateway::Deplo   ServerlessRestApiDeplo   Resource creation      \n                         yment                    ymentaf1c952223          Initiated              \nCREATE_COMPLETE          AWS::ApiGateway::Deplo   ServerlessRestApiDeplo   -                      \n                         yment                    ymentaf1c952223                                 \nCREATE_IN_PROGRESS       AWS::ApiGateway::Stage   ServerlessRestApiProdS   -                      \n                                                  tage                                            \nCREATE_IN_PROGRESS       AWS::ApiGateway::Stage   ServerlessRestApiProdS   Resource creation      \n                                                  tage                     Initiated              \nCREATE_COMPLETE          AWS::ApiGateway::Stage   ServerlessRestApiProdS   -                      \n                                                  tage                                            \nCREATE_COMPLETE          AWS::Lambda::Permissio   HelloWorldCobolGetReso   -                      \n                         n                        urcePermissionProd                              \nCREATE_COMPLETE          AWS::CloudFormation::S   lambda-cobol-stack       -                      \n                         tack                                                                     \n-------------------------------------------------------------------------------------------------\n\nSuccessfully created/updated stack - lambda-cobol-stack in us-east-1\n\n \n \n### Inkoking deployed Lambda synchronously from CLI...\n{\n    \"StatusCode\": 200,\n    \"ExecutedVersion\": \"$LATEST\"\n}\ninvocation result:\n\n  {\n    \"isBase64Encoded\": false,\n    \"statusCode\": 200, \n    \"body\": \"Hello World from COBOL!\" \n  } \n \n### Obtaining API gateway config...\n{\n    \"items\": [\n        {\n            \"id\": \"eioy58x8l3\",\n            \"name\": \"lambda-cobol-stack\",\n            \"createdDate\": \"2023-03-09T01:36:00+00:00\",\n            \"version\": \"1.0\",\n            \"apiKeySource\": \"HEADER\",\n            \"endpointConfiguration\": {\n                \"types\": [\n                    \"EDGE\"\n                ]\n            },\n            \"tags\": {\n                \"aws:cloudformation:logical-id\": \"ServerlessRestApi\",\n                \"aws:cloudformation:stack-id\": \"arn:aws:cloudformation:us-east-1:514764745669:stack/lambda-cobol-stack/9843f110-be1a-11ed-a5ac-0e778226314b\",\n                \"aws:cloudformation:stack-name\": \"lambda-cobol-stack\"\n            },\n            \"disableExecuteApiEndpoint\": false\n        }\n    ]\n}\napi id: eioy58x8l3\n \n### Running curl https request to https://eioy58x8l3.execute-api.us-east-1.amazonaws.com/Prod/lambda-cobol-hello-world ...\nHello World from COBOL! \n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdidier-durand%2Flambda-cobol","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdidier-durand%2Flambda-cobol","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdidier-durand%2Flambda-cobol/lists"}