2

我想爲我的AWS基礎架構和AWS Lambda函數設置CI/CD管道。這個想法是讓代碼,版本控制和自動化。我只想將git push存儲到存儲庫中,然後讓CodePipeline從那裏接管,更新我的基礎架構,運行測試,並在成功時使用最新的代碼更新Lambda函數。通過Cloudformation,CodeBuild和CodePipeline將AWS包部署到AWS Lambda

我基於我的CloudFormation模板this excellent example。它看起來像這樣:

AWSTemplateFormatVersion: 2010-09-09 
Description: playground pipeline 1 
Parameters: 
    SourceRepositoryName: 
    Type: String 
    Default: lambda-playground 
    SourceBranchName: 
    Type: String 
    Default: master 

Resources: 
    ArtifactsBucket: 
    Type: AWS::S3::Bucket 
    DependsOn: CloudFormationRole 
    DeletionPolicy: Delete 
    Properties: 
     BucketName: lambda-playground-artifacts 

    CodeBuildRole: 
    Type: AWS::IAM::Role 
    DependsOn: CloudFormationRole 
    Properties: 
     AssumeRolePolicyDocument: 
     Version: 2012-10-17 
     Statement: 
      - Effect: Allow 
      Action: 
       - sts:AssumeRole 
      Principal: 
       Service: 
       - codebuild.amazonaws.com 
     Policies: 
     - PolicyName: ServiceRole 
      PolicyDocument: 
      Version: 2012-10-17 
      Statement: 
       - Sid: CloudWatchWriteLogsPolicy 
       Effect: Allow 
       Action: 
        - logs:CreateLogGroup 
        - logs:CreateLogStream 
        - logs:PutLogEvents 
       Resource: '*' 
       - Sid: CodeCommitPullPolicy 
       Effect: Allow 
       Action: 
        - codecommit:GitPull 
       Resource: '*' 
       - Sid: S3GetObjectPolicy 
       Effect: Allow 
       Action: 
        - s3:GetObject 
        - s3:GetObjectVersion 
       Resource: '*' 
       - Sid: S3PutObjectPolicy 
       Effect: Allow 
       Action: 
        - s3:PutObject 
       Resource: '*' 

    CodePipelineRole: 
    Type: AWS::IAM::Role 
    DependsOn: CloudFormationRole 
    Properties: 
     AssumeRolePolicyDocument: 
     Version: 2012-10-17 
     Statement: 
      - Effect: Allow 
      Action: 
       - sts:AssumeRole 
      Principal: 
       Service: 
       - codepipeline.amazonaws.com 
     ManagedPolicyArns: 
     - arn:aws:iam::aws:policy/AdministratorAccess 

    CloudFormationRole: 
    Type: AWS::IAM::Role 
    Properties: 
     AssumeRolePolicyDocument: 
     Version: 2012-10-17 
     Statement: 
      - Effect: Allow 
      Action: 
       - sts:AssumeRole 
      Principal: 
       Service: 
       - cloudformation.amazonaws.com 
     ManagedPolicyArns: 
     - arn:aws:iam::aws:policy/AdministratorAccess 

    CodeCommitRepository: 
    Type: AWS::CodeCommit::Repository 
    Properties: 
     RepositoryName: !Ref SourceRepositoryName 

    CodeBuildProject: 
    Type: AWS::CodeBuild::Project 
    DependsOn: CloudFormationRole 
    Properties: 
     Description: A playground of Lambda 
     Artifacts: 
     Type: CODEPIPELINE 
     Environment: 
     ComputeType: BUILD_GENERAL1_SMALL 
     Image: aws/codebuild/python:2.7.12 
     Type: LINUX_CONTAINER 
     Name: lambda-playground 
     ServiceRole: !GetAtt CodeBuildRole.Arn 
     Source: 
     Type: CODEPIPELINE 
     TimeoutInMinutes: 5 

    CodePipeline: 
    Type: AWS::CodePipeline::Pipeline 
    Properties: 
     ArtifactStore: 
     Type: S3 
     Location: !Ref ArtifactsBucket 
     Name: !Ref AWS::StackName 
     RestartExecutionOnUpdate: true 
     RoleArn: !GetAtt CodePipelineRole.Arn 
     Stages: 
     - Name: Source 
      Actions: 
      - Name: Source 
       ActionTypeId: 
       Category: Source 
       Owner: AWS 
       Provider: CodeCommit 
       Version: 1 
       Configuration: 
       RepositoryName: !Ref SourceRepositoryName 
       BranchName: !Ref SourceBranchName 
       OutputArtifacts: 
       - Name: SourceOutput 
     - Name: PipelineDeploy 
      Actions: 
      - Name: UpdatePipeline 
       ActionTypeId: 
       Category: Deploy 
       Owner: AWS 
       Provider: CloudFormation 
       Version: 1 
       Configuration: 
       ActionMode: CREATE_UPDATE 
       Capabilities: CAPABILITY_IAM 
       RoleArn: !GetAtt CloudFormationRole.Arn 
       StackName: !Ref AWS::StackName 
       TemplatePath: SourceOutput::infra.yml 
       InputArtifacts: 
       - Name: SourceOutput 
     - Name: Build 
      Actions: 
      - Name: BuildAndTest 
       ActionTypeId: 
       Category: Build 
       Owner: AWS 
       Provider: CodeBuild 
       Version: 1 
       Configuration: 
       ProjectName: !Ref CodeBuildProject 
       InputArtifacts: 
       - Name: SourceOutput 
       OutputArtifacts: 
       - Name: BuildOutput 

    LambdaFunction: 
    Type: AWS::Lambda::Function 
    Properties: 
     Code: 
     S3Bucket: !Ref ArtifactsBucket 
     S3Key: !Ref BuildOutput # DOES NOT WORK 
     FunctionName: playground-fc 
     Handler: src.main.handler 
     # TODO: Role: foo 
     Runtime: python2.7 

Outputs: 
    ArtifactsBucketURL: 
    Description: Artifacts bucket URL 
    Value: !GetAtt ArtifactsBucket.WebsiteURL 
    RepositoryURL: 
    Description: SSH URL of the repository 
    Value: !GetAtt CodeCommitRepository.CloneUrlSsh 

所以我有3個階段CodePipeline - Source,它從一個CodeCommit回購,PipelineDeploy,這將更新我的CloudFormation堆棧如果有必要和Build,它運行的配置CodeBuild項目抓起代碼。

我buildspec.yml是在這裏:

version: 0.1 

phases: 
    install: 
    commands: 
     - pip install -r requirements.txt -t lib 
    pre_build: 
    commands: 
     - python lib/pytest.py src 
artifacts: 
    type: zip 
    files: 
    - src/**/* 
    - lib/**/* 

它只是安裝必要的庫,通過pytest運行測試和創建部署拉鍊。這個zip文件然後是Build階段的OutputArtifact並且存儲在ArtifactsBucket中。但是,每次都會得到一個唯一的名稱(例如dfVV6Uh),這很有道理,但我不知道如何在LambdaFunction - > Properties - > Code - > S3Key字段中引用它。

所以我的問題是,我如何創建一個堆棧/管道,在完成所有步驟之後,將最新版本部署到我的AWS Lambda函數中?有沒有辦法可能使用CodeDeploy來做到這一點?這裏最好的做法是什麼?

回答

3

您可以使用Parameter OverrideFn::GetArtifactAttObjectKey屬性來動態地提供由AWS CodePipeline生成您的CloudFormation部署行動神器.zip的名稱。

使用你的榜樣,爲您UpdatePipeline CloudFormation部署行動的配置會是這個樣子:

Configuration: 
    ActionMode: CREATE_UPDATE 
    Capabilities: CAPABILITY_IAM 
    RoleArn: !GetAtt CloudFormationRole.Arn 
    StackName: !Ref AWS::StackName 
    TemplatePath: SourceOutput::infra.yml 
    ParameterOverrides: 
    { 
     "LambdaKey" : { "Fn::GetArtifactAtt" : ["LambdaFunctionSource", "ObjectKey"]} 
    } 
InputArtifacts: 
- Name: SourceOutput 
- Name: BuildOutput 

然後,聲明,然後你的CloudFormation堆棧模板內引用LambdaKey參數:

Parameters: 
    LambdaKey: 
    Type: String 
    # ... 
Resources: 
    LambdaFunction: 
    Type: AWS::Lambda::Function 
    Properties: 
     Code: 
     S3Bucket: !Ref ArtifactsBucket 
     S3Key: !Ref LambdaKey 
     # ... 
+0

所以想法是在單獨的CloudFormation模板中聲明AWS :: Lambda :: Function?最初,我想在一個模板中包含所有東西,這就是爲什麼'UpdatePipeline'(一個誤導性名稱,現在我意識到)的步驟是我的管道中第二個。我的Lambda函數代碼是CodeBuild步驟的輸出,在管道中是第三個,所以我想我不能在第二步中引用它(我還沒有嘗試過)。 –

+0

我基於您在您的問題中提供的模板回答了您的問題,該模板引用了'SourceOutput :: infra.yml'。可以將源代碼回購庫中的模板設置爲您用來定義代碼管道資源的相同模板,以使其自引用。使用GitHub查看我的回購https://github.com/wjordan/aws-starter-kit以獲得完全獨立的示例。 – wjordan

+0

我研究了你的aws-starter-kit,並且試圖根據你的建議修改我的模板,但沒有成功。問題是我想把所有東西都放在一個模板中,這樣我就可以引導我的基礎架構並不斷更新它。爲此,在創建Lambda函數資源時,我還沒有S3Key,它只是作爲我的第三個流水線步驟的輸出 - Build操作。我想我會爲引導步驟創建一個虛擬部署包。 –

1

有一個如何實現類似的例子(通過CodePipeline/CodeBuild部署lambda函數)。 http://docs.aws.amazon.com/lambda/latest/dg/automating-deployment.html

這個例子是用NodeJS編寫的lambda函數,但其​​基本思想是相同的。在通過CodeBuild構建工件後,使用CloudFormation部署/更新您的lambda函數,並讓CodePipeline分階段管理工件傳播。

讓我知道這是否有幫助。

相關問題