2017-08-29 141 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的部署。 –