How do I use the CodeBuild output artifact in CloudFormation?

So, I have a pretty simple stack that I'm trying to set up, consisting of a single Lambda function subscribed to the SNS topic. I would like to use CodePipeline with three steps: Source (GitHub) -> Build (CodeBuild) -> Deploy (CloudFormation).

I was able to put together a template and buildspec file that works, except I lost track of how I should be referencing the output artifact that CodeBuild creates in the CloudFormation template; right now I only have the placeholder code inline.

Basically, what should I put in a property Code:

of a Lambda function 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/*

      

+3


source to share


2 answers


Finally found a solution for this thanks to AWS support. First, I put this JSON in the parameter overrides during the CloudFormation deployment phase in CodePipeline:

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

      

Then changed my CF template like this:



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 byte name and the object key that CodeBuild outputs as parameters to CF, so that it can dynamically grab the output artifact location in S3 without the need for hard code, making the template more portable.

+3


source


Your CodeBuild should dump your zip file into an S3 bucket. Therefore, in the Code section of your LambdaFunction resource, you point to it.

Code:
   S3Bucket: the_bucket_where_CodeBuild_dropped_your_zip
   S3Key: the_name_of_the_zip_file_dropped

      



You don't need "ZipFile:"

+1


source







All Articles