代码之家  ›  专栏  ›  技术社区  ›  mth

如何在CloudFormation中使用代码构建的输出工件?

  •  10
  • mth  · 技术社区  · 9 年前

    所以我有一个相当简单的堆栈,我正试图设置一个单一的Lambda函数订阅的SNS主题组成。我希望将代码管道分为三个阶段:源代码(GitHub)->构建(CodeBuild)->部署(CloudFormation)。

    基本上,我应该在 Code:

    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
    

    version: 0.2
    phases:
      install:
        commands:
          - pip install -r requirements.txt -t libs
    artifacts:
      type: zip
      files:
        - template.yml
        - main.py
        - lib/*
    
    3 回复  |  直到 9 年前
        1
  •  14
  •   mth    9 年前

    由于AWS的支持,最终找到了解决方案。首先,我将这个JSON放在CodePipeline中CloudFormation部署步骤的参数覆盖中:

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

    然后将我的CF模板更改为:

    AWSTemplateFormatVersion: 2010-09-09
    Parameters:
      buildBucketName:
        Type: String
      buildObjectKey:
        Type: String
    
      Resources:
        ...
        LambdaFunction:
            ...
            Code:
                S3Bucket: !Ref buildBucketName
                S3Key: !Ref buildObjectKey
    

    这会将CodeBuild输出的输出工件bucket名称和对象键作为参数传递给CF,这样它就可以在S3中动态获取输出工件的位置,而无需硬编码任何内容,从而使模板方式更具可移植性。

        2
  •  1
  •   Alex Nelson    9 年前

    您的代码构建应该将zip文件放到S3存储桶中。因此,在LambdaFunction资源的代码部分,您可以指向它。

    Code:
       S3Bucket: the_bucket_where_CodeBuild_dropped_your_zip
       S3Key: the_name_of_the_zip_file_dropped
    

    你不需要“ZipFile”:

        3
  •  1
  •   Neil McGuigan    6 年前

    project_root/
      template.yaml
      buildspec.yaml
      my_lambda/
        my_lambda.py
        requirements.txt
    

    template.yaml:

    Transform: AWS::Serverless-2016-10-31
    
    Resources:
      MyLambda:
        Type: AWS::Serverless::Function
        Properties:
          Handler: my_lambda.lambda_handler
          CodeUri: my_lambda/
          Runtime: python3.8
    

    version: 0.2
    
    phases:
      install:
        runtime-versions:
          python: 3.8
        commands:
          - pip install aws-sam-cli
      build:
        commands:
          - sam build
          - sam package --s3-bucket mybucket --s3-prefix sam | sam deploy -t /dev/stdin --stack-name FOOSTACK --capabilities CAPABILITY_IAM
    

    笔记:

    1. sam build pip install requirements.txt
    2. sam package 将压缩您的lambda,并用其内容的md5命名,然后为您上传到S3(仅当它已更改时)
    3. sam deploy