[英]how to build, package and deploy AWS SAM lambda function of python from azure Devops CI/CD pipeline to AWS
[英]How to create s3 buckets dynamically in azure devops CI/CD pipeline
我想根據 yaml 文件之一中提到的數據,通過 CI/CD 管道自動創建存儲桶的過程。 所以,我有 bucket.yaml 文件,其中包含所有存儲桶的名稱。 隨着將來添加更多存儲桶名稱,此文件會不斷更改。 目前,這就是 bucket.yaml 的樣子
BucketName:
- test-bucket
- test-bucket2
- test-bucket3
我有一個 template.yaml 文件,它是用於創建 s3 存儲桶的 cloudformation 模板。 這是它的外觀:
Resources:
S3Bucket:
Type: 'AWS::S3::Bucket'
DeletionPolicy: Retain
Properties:
BucketName: This will come from bucket.yaml
現在,template.yaml 將從 bucket.yaml 文件中獲取存儲桶名稱,並應創建 3 個存儲桶,如 bucket.yaml 中所述。 如果有人在 bucket.yaml 中再添加 2 個存儲桶,則 template.yaml 也應該創建這 2 個新存儲桶。 此外,如果有人從 bucket.yaml 中刪除任何存儲桶名稱,那么這些存儲桶也應該被刪除。 我在研究中找不到過程,只是找到了零碎的信息。所以,在這里我有一些具體的問題,如果可以的話:
如何從 bucket.yaml 和 template.yaml 中獲取存儲桶名稱應該創建所有存儲桶。
在bucket.yaml
,您可以使用參數來設置BucketName
。
例如:
parameters:
- name: BucketName
type: object
default:
- test-bucket
- test-bucket2
- test-bucket3
steps:
- ${{ each value in parameters.BucketName }}:
- script: echo ${{ value }}
此處的步驟可以遍歷參數BucketName
的值。
在template.yaml
中,您可以調用bucket.yaml
,如下所示。
trigger:
- main
extends:
template: bucket.yaml
如果有人在 bucket.yaml 中更新/添加/刪除存儲桶名稱,則 template.yaml 應相應地更新這些名稱。
沒有任何簡單的方法可以做到這一點。 您可以嘗試編寫一個腳本以在管道中運行以執行以下操作:
BucketName
的值列表進行比較,檢查哪些存儲桶需要添加,哪些存儲桶需要刪除。BucketName:
- test-bucket
- test-bucket2
- test-bucket3
這些要求意味着所有 S3 存儲桶都將以相同的方式創建,並且不需要偏離給定的 Cloudformation 模板 ( AWS::S3::Bucket
)。
這些要求要求我們跟蹤需要刪除哪些 S3 存儲桶。 Cloudformation 不會刪除 S3 存儲桶,因為 Cloudformation 模板片段包含保留的DeletionPolicy 。
解決方案:
可以以特定方式標記 S3 存儲桶,以將它們標識為當前 CI/CD 管道所擁有。 可以列出 S3 存儲桶,並以正確的方式標記所有 S3 存儲桶,但在存儲桶中不存在。然后可以刪除bucket.yaml
。
我個人會使用 AWS SDK 創建 CI/CD 管道所需的 S3 存儲桶並手動管理 S3 存儲桶刪除。 如果應用程序需要 S3 存儲桶,那么他們應該在其應用程序的 Cloudformation 堆棧中自己創建它,以便他們可以!引用它並按照他們想要的方式對其進行自定義(例如 rest 的加密、版本控制、生命周期規則等)。
技術說明:
要刪除 S3 存儲桶,還需要刪除其內容。 這將要求我們列出 S3 存儲桶中的所有對象,然后將其刪除。 Java SDK [這里]的一些文檔。 只有隨后調用 API 才能成功刪除 S3 存儲桶。
您可以讓 Cloudformation 使用自定義資源刪除您的 S3 對象。 也就是說,我沒有找到有趣的自定義資源 - 所以如果您可以在 CI/CD 管道中使用 AWS SDK,我可能會使用它。
用於刪除存儲桶內容的自定義資源在 Cloudformation 中可能如下所示:(它是一個自定義資源,類似於 Lambda。如果自定義資源被取消配置,Lambda 將刪除 S3 存儲桶內容)
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cfn-customresource.html
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/walkthrough-custom-resources-lambda-lookup-amiids.html
ExampleBucketOperationCustomResource:
Type: AWS::CloudFormation::CustomResource
DependsOn: [Bucket, ExampleBucketOperationLambdaFunction]
Properties:
ServiceToken: !GetAtt ExampleBucketOperationLambdaFunction.Arn
# Custom properties
BucketToUse: !Ref S3BucketName
ExampleBucketOperationLambdaFunctionExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName: "ExampleBucketOperationLambda-ExecutionRole"
Path: "/"
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- sts:AssumeRole
Principal:
Service:
- lambda.amazonaws.com
Policies:
- PolicyName: "ExampleBucketOperationLambda-CanAccessCloudwatchLogs"
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: arn:aws:logs:*:*:*
- PolicyName: "ExampleBucketOperationLambda-S3BucketLevelPermissions"
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- s3:ListBucket
Resource:
- !Sub "arn:aws:s3:::${S3BucketName}"
- PolicyName: "ExampleBucketOperationLambda-S3ObjectLevelPermissions"
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- s3:DeleteObject
- s3:PutObject
Resource:
- !Sub "arn:aws:s3:::${S3BucketName}/*"
# Test payload:
# {"RequestType":"Create","ResourceProperties":{"BucketToUse":"your-bucket-name"}}
ExampleBucketOperationLambdaFunction:
Type: AWS::Lambda::Function
DependsOn: ExampleBucketOperationLambdaFunctionExecutionRole
# DeletionPolicy: Retain
Properties:
FunctionName: "ExampleBucketOperationLambda"
Role: !GetAtt ExampleBucketOperationLambdaFunctionExecutionRole.Arn
Runtime: python3.8
Handler: index.handler
Timeout: 30
Code:
ZipFile: |
import boto3
import cfnresponse
def handler(event, context):
eventType = event["RequestType"]
print("The event type is: " + str(eventType));
bucketToUse = event["ResourceProperties"]["BucketToUse"]
print("The bucket to use: " + str(bucketToUse));
try:
# Requires s3:ListBucket permission
if (eventType in ["Delete"]):
print("Deleting everyting in bucket: " + str(bucketToUse));
s3Client = boto3.client("s3")
s3Bucket = boto3.resource("s3").Bucket(bucketToUse)
for currFile in s3Bucket.objects.all():
print("Deleting file: " + currFile.key);
s3Client.delete_object(Bucket=bucketToUse, Key=currFile.key)
print("All done")
responseData = {}
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData)
except Exception as e:
responseData = {}
errorDetail = "Exception: " + str(e)
errorDetail = errorDetail + "\n\t More detail can be found in CloudWatch Log Stream: " + context.log_stream_name
print(errorDetail)
cfnresponse.send(event=event, context=context, responseStatus=cfnresponse.FAILED, responseData=responseData, reason=errorDetail)
感謝以上回答。 我采取了不同的方式來解決這個問題。 我使用AWS CDK來實現我真正想要的。 我個人將 AWS CDK 用於 Python 並使用它創建了基礎設施。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.