RichardAtkin
RichardAtkin

Reputation: 33

CICD in AWS - GitHub to Lambda

I'm trying to build a CICD pipeline that supports the very simple process laid out below. I am trying to do this all in AWS (ie, avoiding GitHub Actions), and I do not want to have to manually zip code or transfer anything.

Target process:

  1. Git Push code to GitHub Repository.
  2. AWS Updates code within existing Lambda function and updates the $latest alias accordingly.

Progress so far

I have been able to link AWS CodePipeline to GitHub. When code is pushed to the repository, the pipeline triggers and a compressed file that contains the contents from GitHub is added to an S3 bucket.

Long term I will likely be interested in pre- and post-deployment testing, approvals, etc etc... but for now I just want a simple setup as described above.

Challenge

I cannot fathom how then to actually update the Lamda function now I have this compressed file in S3. I've tried various Build/Deploy things from within the CodeDeloy Pipeline, but I get various errors. I'm not even entirely sure if this entire approach is the best way to go about what I want to do?!

Ask

  1. Is this a valid approach to implementing this kind of CICD pipeline? If no, please suggest alternative and justify why you think it's better.
  2. How do you automatically take the code from within the compressed S3 file and get it in to the Lambda function?

Thanks for your help! Richard

Upvotes: 1

Views: 622

Answers (2)

Farzad Khandan
Farzad Khandan

Reputation: 1

You can use AWS CLI to updated the Lambda with the new code:

$ aws lambda update-function-code \
    --function-name your-lambda-name \
    --s3-bucket your-bucket \
    --s3-key your-key

Upvotes: 0

stijndepestel
stijndepestel

Reputation: 3554

What you could do, is include an AWS SAM (CloudFormation) template in your repository. You could then in a build step, use the build/package step of AWS SAM, which will create a packaged.yaml CloudFormation template. This template is then usable with the CloudFormation deployment actions.

This is part of a CloudFormation template that sets up such a flow, some things are omitted for brevity:


  CodeBuildProject:
    Type: AWS::CodeBuild::Project
    Properties:
        Name: codebuildproject
        Description: Package and Deploy
        Artifacts:
          Type: CODEPIPELINE
        Environment:
            Type: LINUX_CONTAINER
            ComputeType: BUILD_GENERAL1_SMALL
            Image: aws/codebuild/amazonlinux2-x86_64-standard:3.0
            EnvironmentVariables:
              - Name: IAC_BUCKET
                Type: PLAINTEXT
                Value: !Sub iac-${AWS::Region}-${AWS::AccountId} # Bucket needed for SAM deployment
        ServiceRole: !Ref CodeBuildServiceRole
        Source:
          Type: CODEPIPELINE
          BuildSpec: |
            version: 0.2
            phases:
              install:
                runtime-versions:
                  python: 3.8
                commands:
                  - 'pip install --upgrade --user aws-sam-cli'
              build:
                commands:
                  - sam build
                  - sam package --s3-bucket $IAC_BUCKET --output-template-file packaged.yaml
            artifacts:
              files:
                - 'packaged.yaml'

  Pipeline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      ArtifactStore:
        Location: !Sub "codepipeline-${AWS::Region}-${AWS::AccountId}"
        Type: S3
      Name: deployment-pipeline
      RoleArn: !GetAtt PipelineExecutionRole.Arn
      Stages:
        - Name: Source
          Actions:
            - YourGithubSourceAction
        - Name: Package
          Actions:
            - Name: SamPackage
              ActionTypeId:
                Category: Build 
                Owner: AWS
                Provider: CodeBuild 
                Version: '1'
              Configuration:
                ProjectName: !Ref CodeBuildProject
              InputArtifacts:
                - Name: SourceZip
              OutputArtifacts:
                - Name: samArtifact
              RunOrder: 1
        - Name: Deployment
          Actions:
            - Name: CreateChangeSet
              ActionTypeId:
                Category: Deploy 
                Owner: AWS
                Provider: CloudFormation 
                Version: '1'
              Configuration:
                ActionMode: "CHANGE_SET_REPLACE"
                ChangeSetName: !Sub "${ApplicationName}-${Environment}-changeset"
                Capabilities: CAPABILITY_NAMED_IAM
                StackName: your-stack-name
                RoleArn: !GetAtt PipelineExecutionRole.Arn  
                ParameterOverrides: !Sub '{ "Environment" : "${Environment}" }'
                TemplatePath: 'samArtifact::packaged.yaml'
              InputArtifacts:
                - Name: samArtifact
              RunOrder: 1
            - Name: ExecuteChangeSet
              ActionTypeId:
                Category: Deploy 
                Owner: AWS
                Provider: CloudFormation 
                Version: '1'
              Configuration:
                ActionMode: CHANGE_SET_EXECUTE
                ChangeSetName: !Sub ${ApplicationName}-${Environment}-changeset
                StackName: your-stack-name
              RunOrder: 2

Be sure to have a look at AWS SAM if you're not familiar with it to see all the possibilities and how to construct your template itself.

Upvotes: 1

Related Questions