2017-08-29 143 views
1

我想自動部署在java中開發的AWS Lambda。爲此,我創建了CodePipeline,這是通過git push命令觸發CodeCommit存儲庫。 CodePipeline的下一步是CodeBuild項目。 CodeBuild採用以下buildspec.yml文件:從CodePipeline調用的AWS CodeBuild產生不能用於AWS的artefact Lambda

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運行,結果是jar文件被封裝在zip中。由於此zip不能用於更新lambda函數,因此我不知道該怎麼做,因爲CodePipeline將覆蓋CodeBuild項目的任何包裝集。

想法是,CodePipeline會觸發CodeBuild,它將產生輸出,其中的額外lambda將使用並更新lambda函數。從CodePipeline調用的CodeBuild的輸出是jar而不是zip嗎?如果不是,那麼我應該在這裏做什麼?

任何幫助表示讚賞。

回答

1

既可以使用zip或jar文件來更新Lambda函數,只需要將使用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(你需要添加一個AW與s :: LAMBDA ::許可)

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桶

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 
+0

湯姆你好。 Tnx爲我們的答案。我想避免CloudFormation。沒有它可以完成嗎? – newbie

+0

我想這可以在沒有云信息的情況下完成。在您的buildspec中,您可以使用AWS CLI來使用生成的工件(mvn包)更新Lambda代碼,請參閱:http://docs.aws.amazon.com/cli/latest/reference/lambda/update- function-code.html 您也可以在管道中添加另一個步驟來調用Lambda函數。然後你可以使用aws sdk來執行生成的jar的部署。 –