从CodePipeline调用的AWS CodeBuild会生成不能用于AWS Lambda的人工制品

时间:2017-08-29 19:30:20

标签: aws-lambda aws-codepipeline aws-codebuild

我想自动部署在Java中开发的AWS Lambda。为此,我创建了CodePipeline,它在 git push 命令上触发到CodeCommit存储库。 CodePipeline的下一步是CodeBuild项目。 CodeBuild使用以下buildspec.yml文件:

version: 0.1

phases:
  build:
    commands:
      - echo Entering build phase...
      - echo Build started on `date`
      - mvn package shade:shade
      - mv target/Output-1.0.jar .
artifacts:
  files:
    - Output-1.0.jar

当手动运行CodeBuild项目时,它会将jar文件上传到s3存储桶。这个jar文件可以毫无问题地用于更新lambda,一切都按预期工作。但是如果CodeBuild是通过CodePipeline运行的,那么结果就是包含在zip中的jar文件。由于此zip不能用于更新lambda函数,我不知道我应该在这做什么,因为CodePipeline会覆盖CodeBuild项目的任何打包集。

想法是CodePipeline触发CodeBuild,它产生额外lambda将采用的输出并用它更新lambda函数。以某种方式可能从CodePipeline调用的CodeBuild输出是jar而不是zip吗?如果没有,那我该怎么做呢?

感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

zip或jar文件都可以用来更新Lambda函数,你只需要添加一个" Deploy Step"将Cloudformation用于CodePipeline。

这是一个nodejs构建/管道,尝试适应你的java项目:

项目文件

buildspec.yml

version: 0.2

phases:
  install:
    commands:
      - echo install phase
  pre_build:
    commands:
      - echo pre_build phase
  build:
    commands:
      - npm install --production      
  post_build:
    commands:
      - echo post build
artifacts:
  type: zip
  files:
    - index.js      
    - node_modules/**/*
    - package.json
    - template.yml
    - configuration.json    
  discard-paths: no

configuration.json

{
  "Parameters": {
    "BucketName" : { "Fn::GetArtifactAtt" : ["Build", "BucketName"]},
    "ObjectKey" : { "Fn::GetArtifactAtt" : ["Build", "ObjectKey"]}
  }
}

template.yml(您需要添加AWS :: Lambda :: Permission)

AWSTemplateFormatVersion: "2010-09-09"
Description: "My Lambda Template"
Parameters:
  BucketName:
    Type: String
  ObjectKey:
    Type: String
  Roles:
    Type: String
    Default: Roles
  LambdaRole:
    Type: String
    Default: LambdaRole

Resources:

  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      Description: 'My Lambda Handler'
      Handler: index.handler
      Runtime: nodejs6.10
      Timeout: 5
      Code:
        S3Bucket: 
          Ref: BucketName
        S3Key: 
          Ref: ObjectKey
      Role:
        Fn::Join:
          - ""
          - - "arn:aws:iam::"
            - !Ref AWS::AccountId
            - ":role/"          
            - Fn::ImportValue:
                Fn::Join:
                  - ""
                  - - Ref: Roles
                    - "-"
                    - Ref: LambdaRole

角色模板

AWSTemplateFormatVersion: '2010-09-09'
Description: 'The AWS Resource Roles'
Resources:
  CodeBuildRole:    
    Type: AWS::IAM::Role    
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          Effect: Allow
          Principal:
            Service: codebuild.amazonaws.com
          Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AWSCodeBuildAdminAccess
        - arn:aws:iam::aws:policy/CloudWatchFullAccess
        - arn:aws:iam::aws:policy/AWSCodeCommitFullAccess
        - arn:aws:iam::aws:policy/AmazonS3FullAccess

  CodePipelineRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          Effect: Allow
          Principal:
            Service: codepipeline.amazonaws.com
          Action: sts:AssumeRole      
      Policies:
        -
          PolicyName: CloudFormationFullAccess
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              -
                Effect: "Allow"
                Action: 
                  - "cloudformation:*"                  
                Resource: "*"  
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AWSCodePipelineFullAccess
        - arn:aws:iam::aws:policy/AWSCodeCommitFullAccess
        - arn:aws:iam::aws:policy/AmazonS3FullAccess
        - arn:aws:iam::aws:policy/AWSCodeBuildAdminAccess        
        - arn:aws:iam::aws:policy/AWSLambdaFullAccess

  CloudFormationRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          Effect: Allow
          Principal:
            Service: cloudformation.amazonaws.com
          Action: sts:AssumeRole    
      Policies:
        -
          PolicyName: CloudFormationFullAccess
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              -
                Effect: "Allow"
                Action: "cloudformation:*"
                Resource: "*"  
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AWSCodePipelineFullAccess
        - arn:aws:iam::aws:policy/AWSCodeCommitFullAccess
        - arn:aws:iam::aws:policy/AmazonS3FullAccess
        - arn:aws:iam::aws:policy/AWSCodeBuildAdminAccess
        - arn:aws:iam::aws:policy/AWSLambdaFullAccess
        - arn:aws:iam::aws:policy/AmazonAPIGatewayAdministrator        

  LambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          Effect: Allow
          Principal:
            Service: lambda.amazonaws.com
          Action: sts:AssumeRole          
      Policies:
        -
          PolicyName: CloudFormationFullAccess
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              -
                Effect: "Allow"
                Action: "cloudformation:*"
                Resource: "*"    
      ManagedPolicyArns:        
        - arn:aws:iam::aws:policy/AWSLambdaFullAccess
        - arn:aws:iam::aws:policy/AWSCodePipelineFullAccess
        - arn:aws:iam::aws:policy/AmazonSESFullAccess

Outputs:
  CodeBuildRoleOutput:
    Description: 'Maybe API CodeBuildRole ARN'
    Value: !Ref 'CodeBuildRole'
    Export: 
      Name: !Sub '${AWS::StackName}-CodeBuildRole'
  CodePipelineRoleOutput:
    Description: 'Maybe API CodePipelineRole ARN'
    Value: !Ref 'CodePipelineRole'
    Export: 
      Name: !Sub '${AWS::StackName}-CodePipelineRole'    
  CloudFormationRoleOutput:
    Description: 'Maybe API CloudFormationRole ARN'
    Value: !Ref 'CloudFormationRole'
    Export: 
      Name: !Sub '${AWS::StackName}-CloudFormationRole'
  LambdaRoleOutput:
    Description: 'Maybe API LambdaRole ARN'
    Value: !Ref 'LambdaRole'
    Export: 
      Name: !Sub '${AWS::StackName}-LambdaRole'

CodePipeline Bucket

AWSTemplateFormatVersion: '2010-09-09'
Description: 'The AWS S3 CodePipeline Bucket'
Resources:

  CodePipelineBucket:    
    Type: AWS::S3::Bucket 
    DeletionPolicy: Retain
    Properties:
      BucketName: my-code-pipeline-bucket
      VersioningConfiguration:
        Status: Enabled
      AccessControl: BucketOwnerFullControl           

Outputs:
  CodePipelineBucketOutput:
    Description: 'CodePipeline Bucket Ref'
    Value: !Ref CodePipelineBucket
    Export: 
      Name: !Sub '${AWS::StackName}-CodePipelineBucketRef'    

CodeBuild模板

AWSTemplateFormatVersion: '2010-09-09'
Description: 'Nodejs CodeBuild Template'
Parameters:
  Artifact:
    Type: String
    Default: artifact
  Roles:
    Type: String
    Default: Roles
  CodeBuildRole:
    Type: String
    Default: CodeBuildRole  

Resources:  

  NodejsCodeBuild:
    Type: AWS::CodeBuild::Project
    DeletionPolicy: Retain
    Properties:
      ServiceRole:
        Fn::ImportValue:
          Fn::Join:
            - ""
            - - Ref: Roles
              - "-"
              - Ref: CodeBuildRole    
      Artifacts: 
        Type: no_artifacts      
      Environment:
        ComputeType: BUILD_GENERAL1_SMALL
        Image: aws/codebuild/eb-nodejs-6.10.0-amazonlinux-64:4.0.0
        Type: LINUX_CONTAINER
      Source:
        Type: S3
        Location: !Ref Artifact
Outputs:
  NodejsCodeBuildOutput:
    Description: 'Nodejs CodeBuild Ref'
    Value: !Ref 'NodejsCodeBuild'
    Export: 
      Name: !Sub '${AWS::StackName}-NodejsCodeBuildRef'

CodePipeline模板

AWSTemplateFormatVersion: '2010-09-09'
Description: 'CodePipeline for Nodejs Applications'

Parameters:

  Roles:
    Type: String
    Default: Roles
  CodePipelineRole:
    Type: String
    Default: CodePipelineRole
  CloudFormationRole:
    Type: String
    Default: CloudFormationRole  
  CodePipelineBucket:
    Type: String
    Default: CodePipelineBucket
  CodePipelineBucketRef:
    Type: String
    Default: CodePipelineBucketRef
  PipelineName:
    Type: String
    Default: PipelineName
  CodeBuildProject:
    Type: String
    Default: NodejsCodeBuild
  CodeBuildProjectRef:
    Type: String
    Default: NodejsCodeBuildRef
  Branch:
    Type: String
    Default: master
  Repository:
    Type: String
    Default: my-repository-name
  LambdaStack:
    Type: String
    Default: LambdaStack


Resources:

  NodejsCodePipeline:    
    Type: AWS::CodePipeline::Pipeline
    Properties:
      Name: !Ref PipelineName
      RoleArn:
        Fn::Join:
          - ""
          - - "arn:aws:iam::"
            - !Ref AWS::AccountId
            - ":role/"          
            - Fn::ImportValue:
                Fn::Join:
                  - ""
                  - - Ref: Roles
                    - "-"
                    - Ref: CodePipelineRole


      ArtifactStore:
        Location:          
          Fn::Join:
            - ""
            - - Fn::ImportValue:
                  Fn::Join:
                    - ""
                    - - Ref: CodePipelineBucket
                      - "-"
                      - Ref: CodePipelineBucketRef
        Type: S3

      Stages:

        - Name: Source
          Actions:
            - InputArtifacts: []
              Name: Source
              ActionTypeId:
                Category: Source
                Owner: AWS
                Version: 1
                Provider: CodeCommit
              OutputArtifacts:
                - Name: Master
              Configuration:
                BranchName: !Ref Branch
                RepositoryName: !Ref Repository
              RunOrder: 1

        - Name: Build
          Actions:            
            - Name: Build                
              ActionTypeId:
                Category: Build
                Owner: AWS
                Version: 1
                Provider: CodeBuild
              InputArtifacts:
                - Name: Master
              OutputArtifacts:
                - Name: Build            
              Configuration:
                ProjectName:
                  Fn::Join:
                    - ""
                    - - Fn::ImportValue:
                          Fn::Join:
                            - ""
                            - - Ref: CodeBuildProject
                              - "-"
                              - Ref: CodeBuildProjectRef
              RunOrder: 1

        - Name: Stage
          Actions:            
            - Name: Sandbox                
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Version: 1
                Provider: CloudFormation
              InputArtifacts:
                - Name: Build
              OutputArtifacts:
                - Name: Deploy            
              Configuration:
                StackName: !Ref LambdaStack
                ActionMode: CREATE_UPDATE
                Capabilities: CAPABILITY_IAM
                TemplateConfiguration: Build::configuration.json
                TemplatePath: Build::template.yml
                ParameterOverrides: |
                  {
                    "BucketName" : { "Fn::GetArtifactAtt" : ["Build", "BucketName"]},
                    "ObjectKey" : { "Fn::GetArtifactAtt" : ["Build", "ObjectKey"]} 
                  }                
                RoleArn:
                  Fn::Join:
                    - ""
                    - - "arn:aws:iam::"
                      - !Ref AWS::AccountId
                      - ":role/"          
                      - Fn::ImportValue:
                          Fn::Join:
                            - ""
                            - - Ref: Roles
                              - "-"
                              - Ref: CloudFormationRole
              RunOrder: 1