如何在 CloudFormation 中使用 CodeBuild 的输出工件?
How to use output artifact of CodeBuild in CloudFormation?
所以我有一个相当简单的堆栈,我正在尝试设置它,它由订阅 SNS 主题的单个 Lambda 函数组成。我想在三个阶段使用 CodePipeline:Source (GitHub) -> Build (CodeBuild) -> Deploy (CloudFormation)。
我设法拼凑了一个可用的模板和 buildspec 文件,但我不知道应该如何引用 CodeBuild 在 CloudFormation 模板中生成的输出工件;现在我只有占位符内联代码。
基本上,为了获取 CodeBuild 文件(这是我在 CodePipeline 中的输出工件),我应该在 Lambda 函数的 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
buildspec.yml:
version: 0.2
phases:
install:
commands:
- pip install -r requirements.txt -t libs
artifacts:
type: zip
files:
- template.yml
- main.py
- lib/*
您的 CodeBuild 应该将您的 zip 文件放到 S3 存储桶中。因此,在您的 LambdaFunction 资源的代码部分中,您指向它。
Code:
S3Bucket: the_bucket_where_CodeBuild_dropped_your_zip
S3Key: the_name_of_the_zip_file_dropped
你不需要'ZipFile: '
感谢 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 输出的输出工件存储桶名称和对象键作为参数传递给 CF,这样它就可以动态获取 S3 中的输出工件位置,而无需对任何内容进行硬编码,从而使模板更具可移植性。
我意识到这个问题很老了,但我想我会根据 SAM 来回答它
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
buildspec.yaml:
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
备注:
sam build
将 pip install
你的 lambda requirements.txt
sam package
将压缩您的 lambda,并使用其内容的 md5 命名并为您上传到 S3(仅当它已更改时)
sam deploy
将创建 CloudFormation 变更集并运行 为您
所以我有一个相当简单的堆栈,我正在尝试设置它,它由订阅 SNS 主题的单个 Lambda 函数组成。我想在三个阶段使用 CodePipeline:Source (GitHub) -> Build (CodeBuild) -> Deploy (CloudFormation)。
我设法拼凑了一个可用的模板和 buildspec 文件,但我不知道应该如何引用 CodeBuild 在 CloudFormation 模板中生成的输出工件;现在我只有占位符内联代码。
基本上,为了获取 CodeBuild 文件(这是我在 CodePipeline 中的输出工件),我应该在 Lambda 函数的 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
buildspec.yml:
version: 0.2
phases:
install:
commands:
- pip install -r requirements.txt -t libs
artifacts:
type: zip
files:
- template.yml
- main.py
- lib/*
您的 CodeBuild 应该将您的 zip 文件放到 S3 存储桶中。因此,在您的 LambdaFunction 资源的代码部分中,您指向它。
Code:
S3Bucket: the_bucket_where_CodeBuild_dropped_your_zip
S3Key: the_name_of_the_zip_file_dropped
你不需要'ZipFile: '
感谢 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 输出的输出工件存储桶名称和对象键作为参数传递给 CF,这样它就可以动态获取 S3 中的输出工件位置,而无需对任何内容进行硬编码,从而使模板更具可移植性。
我意识到这个问题很老了,但我想我会根据 SAM 来回答它
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
buildspec.yaml:
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
备注:
sam build
将pip install
你的 lambdarequirements.txt
sam package
将压缩您的 lambda,并使用其内容的 md5 命名并为您上传到 S3(仅当它已更改时)sam deploy
将创建 CloudFormation 变更集并运行 为您