Intellipaat Back

Explore Courses Blog Tutorials Interview Questions
0 votes
2 views
in AWS by (19.1k points)

So I have a fairly simple stack I'm trying to set up consisting of a single Lambda function subscribed to an SNS topic. I'd like to use CodePipeline with three stages: Source (GitHub) -> Build (CodeBuild) -> Deploy (CloudFormation).

I managed to cobble together a template and buildspec file that that work, except I'm lost on how I'm supposed to reference the output artifact that CodeBuild makes in the CloudFormation template; right now I just have placeholder inline code.

Basically, what am I supposed to put in the Code: property of the Lambda function in order to get the CodeBuild files (which is my output artifact in CodePipeline)?

template.yml:

AWSTemplateFormatVersion: 2010-09-09

Resources:

  SNSTopic:

    Type: 'AWS::SNS::Topic'

    Properties:

      Subscription:

        - Endpoint: !GetAtt

            - LambdaFunction

            - Arn

          Protocol: lambda

  LambdaFunction:

    Type: 'AWS::Lambda::Function'

    Properties:

      Runtime: python3.6

      Handler: main.lamda_handler

      Timeout: '10'

      Role: !GetAtt

        - LambdaExecutionRole

        - Arn

      Code:

        ZipFile: >

          def lambda_handler(event, context):

            print(event)

            return 'Hello, world!'

  LambdaExecutionRole:

    Type: 'AWS::IAM::Role'

    Properties:

      AssumeRolePolicyDocument:

        Version: 2012-10-17

        Statement:

          - Effect: Allow

            Principal:

              Service:

                - lambda.amazonaws.com

            Action:

              - 'sts:AssumeRole'

      ManagedPolicyArns:

        - 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'

  LambdaInvokePermission:

    Type: 'AWS::Lambda::Permission'

    Properties:

      FunctionName: !GetAtt

        - LambdaFunction

        - Arn

      Action: 'lambda:InvokeFunction'

      Principal: sns.amazonaws.com

      SourceArn: !Ref SNSTopic

buildspec.yml:

version: 0.2

phases:

  install:

    commands:

      - pip install -r requirements.txt -t libs

artifacts:

  type: zip

  files:

    - template.yml

    - main.py

    - lib/*

1 Answer

0 votes
by (44.4k points)

Finally found a solution to this thanks to AWS support. First, I placed this JSON in the Parameter Overrides in the CloudFormation deployment step in CodePipeline:

{

  "buildBucketName" : { "Fn::GetArtifactAtt" : ["MyAppBuild", "BucketName"]},

  "buildObjectKey" : { "Fn::GetArtifactAtt" : ["MyAppBuild", "ObjectKey"]}

}

Then changed my CF template like so:

AWSTemplateFormatVersion: 2010-09-09

Parameters:

  buildBucketName:

    Type: String

  buildObjectKey:

    Type: String

  Resources:

    ...

    LambdaFunction:

        ...

        Code:

            S3Bucket: !Ref buildBucketName

            S3Key: !Ref buildObjectKey

This passes the output artifact bucket name and object key that CodeBuild outputs as parameters to CF, so that it can dynamically grab the output artifact location in S3 without having to hardcode anything, making the template way more portable.

Related questions

Want to get 50% Hike on your Salary?

Learn how we helped 50,000+ professionals like you !

31k questions

32.8k answers

501 comments

693 users

Browse Categories

...