BLOGS

 
  • Subhas Patil

CI/CD pipeline for AWS Lambda functions via zip file

Lambda is a compute service that lets you run code without provisioning or managing servers. Lambda runs your code on a high-availability compute infrastructure and performs all of the administration of the compute resources, including server and operating system maintenance, capacity provisioning and automatic scaling, code monitoring and logging. With Lambda, you can run code for virtually any type of application or backend service.

In this article we will deploy a .NET Core lambda function using the zip file created by the .NET CLI publish command.


A .zip file archive includes your application code and its dependencies. When you author functions using the Lambda console or a toolkit, Lambda automatically creates a .zip file archive of your code.


There are 2 conventional ways of deploying the zip file to Lambda:

  1. Use AWS toolkit for visual studio

  2. Upload the zip via console directly

While these options work greatly, think of a situation where each developer is working on their own machine and you want to control the deployment. There might be situations where you do not want to give permission to the lambda functions to all the developers as it can cause issues.


So we look at the other option of using S3 to store the zip file and deploy the code via AWS CodePipeline. With this method you only assign S3 permission to the developers to upload their code, rest of the permissions required for deployment is assigned to the CodeBuild role.


Lets look at the steps to achieve this:


Step 1:

  1. Upload the zip file to the S3 bucket.

  2. Lets use this path for reference S3://mybucket/lambda/app.zip

Step 2:

  1. Create a role for codepipeline and attach the following policy:

  2. Role name: 'codepipeline'

{
    "Statement": [
        {
            "Action": [
                "iam:PassRole"
            ],
            "Resource": "*",
            "Effect": "Allow",
            "Condition": {
                "StringEqualsIfExists": {
                    "iam:PassedToService": [
                        "cloudformation.amazonaws.com",
                        "elasticbeanstalk.amazonaws.com",
                        "ec2.amazonaws.com",
                        "ecs-tasks.amazonaws.com"
                    ]
                }
            }
        },
        {
            "Action": [
                "codecommit:CancelUploadArchive",
                "codecommit:GetBranch",
                "codecommit:GetCommit",
                "codecommit:GetRepository",
                "codecommit:GetUploadArchiveStatus",
                "codecommit:UploadArchive"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "codedeploy:CreateDeployment",
                "codedeploy:GetApplication",
                "codedeploy:GetApplicationRevision",
                "codedeploy:GetDeployment",
                "codedeploy:GetDeploymentConfig",
                "codedeploy:RegisterApplicationRevision"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "codestar-connections:UseConnection"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "elasticbeanstalk:*",
                "ec2:*",
                "elasticloadbalancing:*",
                "autoscaling:*",
                "cloudwatch:*",
                "s3:*",
                "sns:*",
                "cloudformation:*",
                "rds:*",
                "sqs:*",
                "ecs:*"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "lambda:InvokeFunction",
                "lambda:ListFunctions"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "opsworks:CreateDeployment",
                "opsworks:DescribeApps",
                "opsworks:DescribeCommands",
                "opsworks:DescribeDeployments",
                "opsworks:DescribeInstances",
                "opsworks:DescribeStacks",
                "opsworks:UpdateApp",
                "opsworks:UpdateStack"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "cloudformation:CreateStack",
                "cloudformation:DeleteStack",
                "cloudformation:DescribeStacks",
                "cloudformation:UpdateStack",
                "cloudformation:CreateChangeSet",
                "cloudformation:DeleteChangeSet",
                "cloudformation:DescribeChangeSet",
                "cloudformation:ExecuteChangeSet",
                "cloudformation:SetStackPolicy",
                "cloudformation:ValidateTemplate"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "codebuild:BatchGetBuilds",
                "codebuild:StartBuild",
                "codebuild:BatchGetBuildBatches",
                "codebuild:StartBuildBatch"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Effect": "Allow",
            "Action": [
                "devicefarm:ListProjects",
                "devicefarm:ListDevicePools",
                "devicefarm:GetRun",
                "devicefarm:GetUpload",
                "devicefarm:CreateUpload",
                "devicefarm:ScheduleRun"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "servicecatalog:ListProvisioningArtifacts",
                "servicecatalog:CreateProvisioningArtifact",
                "servicecatalog:DescribeProvisioningArtifact",
                "servicecatalog:DeleteProvisioningArtifact",
                "servicecatalog:UpdateProduct"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "cloudformation:ValidateTemplate"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ecr:DescribeImages"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "states:DescribeExecution",
                "states:DescribeStateMachine",
                "states:StartExecution"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "appconfig:StartDeployment",
                "appconfig:StopDeployment",
                "appconfig:GetDeployment"
            ],
            "Resource": "*"
        }
    ],b
    "Version": "2012-10-17"
}


Step 3:

  1. Create pipeline

  2. Enter the name

  3. Select the role created in step 2

  4. At the source stage, select 'S3' as source and provide the bucket and object path

5. At the build stage, select AWS CodeBuild as the build provider.

6. Create a build project:

- Select OS as 'Amazon Linux 2'

- Runtime standard

- Select any image

- Provide a role name and let CodeBuild create this role

- In the buildspec stage, select on 'insert build commands,' switch to editor and enter t the following:

version: 0.2phases:
  build:
    commands:
       - aws --version
       - aws lambda update-function-code --function-name mylambda_functionname_here --s3-bucket mybucket --s3-key lambda/app.zip


Step 4:


Assign the following policy to the CodeBuild role (myrole) created by CodeBuild project:

  • AWSLambda_FullAccess (Required to deploy function to lambda)

  • AmazonS3FullAccess (Required to get the zip file from S3 bucket)

  1. Select the CodeBuild project just created in the CodePipeline build stage

  2. Click on 'next' and skip the deploy stage

  3. Review the Pipeline and create

Now your pipeline will start the execution and within few minutes you will see that your function is deployed successfully.











21 views0 comments

Recent Posts

See All