Bài viết được chắp bút bởi Chetan Makvana, Sr. Solutions Architect.
Bài viết gốc: Link
Khách hàng thường sử dụng các mẫu kiến trúc theo mô-đun và mô hình hoạt động serverless để xây dựng các ứng dụng bền vững, có thể khả năng mở rộng và linh hoạt hơn trong quá trình phát triển ứng dụng về sau. AWS Lambda là một trong những lựa chọn phổ biến cho việc xây dựng các ứng dụng thuộc loại này.
Tuy nhiên, nếu khách hàng đã đầu tư và sở hữu bộ công cụ container cho quy trình phát triển phần mềm của mình, thì họ có thể triển khai chúng lên Lambda bằng cách sử dụng định dạng đóng gói image container cho workload như học máy (ML) hoặc workload đòi hỏi xử lý nhiều dữ liệu. Khi sử dụng các Lambda function để triển khai các container images, khách hàng sẽ được hưởng lợi từ sự đơn giản trong việc vận hành, khả năng tự động mở rộng, tính sẵn sàng cao và khả năng tích hợp với nhiều dịch vụ khác.
Các ứng dụng được đóng gói thường sở hữu một số môi trường và tài khoản riêng biệt, chẳng hạn như dev, test và prod. Thông thường, một ứng dụng sẽ phải trải qua quá trình triển khai và thử nghiệm trên các môi trường này. Một mẫu phổ biến để triển khai các ứng dụng được đóng gói thành container là chỉ tạo image trên một tài khoản AWS trung tâm và tiến hành triển khai lên trên các tài khoản AWS khác. Để triển khai ứng dụng một cách tự động trên các môi trường khác nhau, khách hàng sẽ áp dụng quy trình CI/CD và sử dụng các công cụ container phổ biến.
Bài viết này sẽ tìm hiểu về cách sử dụng AWS Serverless Application Model (AWS SAM) Pipelines để khởi tạo quy trình triển khai CI/CD và triển khai container trên Lambda function ở nhiều tài khoản khác nhau.
I. Tổng quan về giải pháp
Giải pháp này bao gồm ba tài khoản: tooling, test và prod. Tài khoản tooling là tài khoản trung tâm nơi bạn khởi tạo pipeline và dựng container. Pipeline sẽ triển khai container vào Lambda trong Tài khoản test và prod bằng AWS CodeBuild. Pipeline cũng yêu cầu các tài nguyên cần thiết trong Tài khoản test và prod. Để làm điều đó, ta cần một IAM role cấp quyền cho Tài khoản tooling với các quyền cần thiết dành riêng cho việc triển khai. AWS CodeBuild sẽ nhận IAM role này trong Tài khoản tooling để tiến hành triển khai.
Giải pháp sử dụng AWS SAM pipeline để tạo tài nguyên cho pipeline triển khai CI/CD. Nó cung cấp các lệnh để tạo ra các tài nguyên cơ sở hạ tầng AWS cần thiết và tệp cấu hình pipeline mà hệ thống CI/CD có thể sử dụng để triển khai bằng AWS SAM. Xem mã ví dụ cho giải pháp này trong GitHub repository.
Kiến trúc giải pháp đầy đủ
AWS CodePipeline thực hiện các bước sau để triển khai container trên Lambda function trong tài khoản test và prod:
- Người phát triển đẩy đoạn code của Lambda function lên AWS CodeCommit hoặc các kho lưu trữ mã nguồn khác, từ đó kích hoạt quy trình CI/CD.
- AWS CodeBuild build code, tạo container image và đẩy nó tới kho lưu trữ Amazon Elastic Container Register (ECR) bằng AWS SAM.
- AWS CodeBuild đảm nhận cross-account role trên tài khoản test.
- AWS CodeBuild sử dụng AWS SAM để triển khai Lambda function bằng cách kéo image từ Amazon ECR.
- Nếu quá trình triển khai thành công, AWS CodeBuild sẽ triển khai cùng một image đó trong tài khoản prod bằng AWS SAM.
II. Triển khai giải pháp
1. Yêu cầu tiên quyết
- Một tài khoản AWS. IAM user mà bạn sử dụng phải có đủ quyền để thực hiện các lệnh gọi các dịch vụ AWS cần thiết và quản lý tài nguyên AWS.
- Cài đặt và cấu hình trước AWS CLI.
- Đã cài đặt Git.
- Đã cài đặt AWS SAM.
- Thiết lập .aws/credentials với các profile được đặt tên cho tài khoản tooling, test và prod để bạn có thể chạy các lệnh CLI và AWS SAM.
- Đặt các biến env TOOLS_ACCOUNT_ID, TEST_ACCOUNT_ID và PROD_ACCOUNT_ID:
export TOOLS_ACCOUNT_ID=<Tooling Account Id>
export TEST_ACCOUNT_ID=<Test Account Id>
export PROD_ACCOUNT_ID=<Prod Account Id>
2. Tạo Git Repo và đẩy code
Chạy lệnh sau trong tài khoản tooling từ terminal trên máy của bạn để tạo kho lưu trữ code mới trên CodeCommit:
aws codecommit create-repository --repository-name lambda-container-repo --profile tooling
Khởi tạo Git repo và đẩy code lên đó:
cd ~/environment/cicd-lambda-container
git init -b main
git add .
git commit -m "Initial commit"
git remote add origin codecommit://lambda-container-repo
git push -u origin main
3. Tạo cross-account roles trong tài khoản test và prod
Để pipeline có quyền truy cập vào môi trường test và production, pipeline cần phải đảm nhận IAM role. Trong bối cảnh có nhiều tài khoản, IAM role cho pipeline phải được tạo trên tài khoản test và production.
Thay đổi thư mục thành thư mục templates và chạy lệnh sau để triển khai các role cho tài khoản test và prod bằng cách sử dụng profile cấu hình có tên tương ứng.
Test profile
cd ~/environment/cicd-lambda-container/templates
aws cloudformation deploy --template-file crossaccount_pipeline_roles.yml --stack-name codepipeline-crossaccount-roles --capabilities CAPABILITY_NAMED_IAM --profile test --parameter-overrides ToolAccountID=${TOOLS_ACCOUNT_ID}
aws cloudformation describe-stacks --stack-name codepipeline-crossaccount-roles --query "Stacks[0].Outputs" --output json --profile test
Mở tệp codepipeline_parameters.json tại thư mục gốc. Thay thế giá trị của TestCodePipelineCrossAccountRoleArn và TestCloudFormationCrossAccountRoleArn bằng giá trị đầu ra từ CloudFormation của CodePipelineCrossAccountRole và CloudFormationCrossAccountRole.
Prod Profile
aws cloudformation deploy --template-file crossaccount_pipeline_roles.yml --stack-name codepipeline-crossaccount-roles --capabilities CAPABILITY_NAMED_IAM --profile prod --parameter-overrides ToolAccountID=${TOOLS_ACCOUNT_ID}
aws cloudformation describe-stacks --stack-name codepipeline-crossaccount-roles --query "Stacks[0].Outputs" --output json --profile prod
Mở tệp codepipeline_parameters.json từ thư mục gốc. Thay thế giá trị của ProdCodePipelineCrossAccountRoleArn và ProdCloudFormationCrossAccountRoleArn bằng giá trị đầu ra từ CloudFormation của CodePipelineCrossAccountRole và CloudFormationCrossAccountRole..
Tạo các IAM roles và cơ sở hạ tầng cần thiết trong tài khoản công cụ.
Thay đổi thư mục templates và chạy lệnh sau bằng cách sử dụng profile có tên tooling:
aws cloudformation deploy --template-file tooling_resources.yml --stack-name tooling-resources --capabilities CAPABILITY_NAMED_IAM --parameter-overrides TestAccountID=${TEST_ACCOUNT_ID} ProdAccountID=${PROD_ACCOUNT_ID} --profile tooling
aws cloudformation describe-stacks --stack-name tooling-resources --query "Stacks[0].Outputs" --output json --profile tooling
Mở tệp codepipeline_parameters.json từ thư mục gốc. Thay thế giá trị của ImageRepositoryURI, ArtifactsBucket, ToolingCodePipelineExecutionRoleArn và ToolingCloudFormationExecutionRoleArn bằng giá trị từ đầu ra của CloudFormation.
Cập nhật cross-account IAM roles
Các cross-account IAM roles trên tài khoản test và production yêu cầu quyền truy cập vào các artifacts chứa phần mã của ứng dụng ( S3 bucket và ECR repository). Lưu ý rằng cross-account roles được triển khai hai lần. Điều này là xảy ra do có sự phụ thuộc xoay vòng giữa các roles trong tài khoản test và production cũng như tài nguyên pipeline artifact được cấp trong tài khoản tooling.
Pipeline phải tham chiếu đến các ARN của các roles mà nó cần đảm nhận để triển khai ứng dụng vào tài khoản test và prod, do đó các roles này phải được triển khai trước khi pipeline được cung cấp. Tuy nhiên, các chính sách (policies) gắn vào các roles cần bao gồm S3 bucket và ECR repository. Tuy nhiên, S3 bucket và ECR repository chưa được tạo ra cho đến khi các tài nguyên được triển khai ở bước trước. Thông qua việc triển khai các roles hai lần, lần đầu chưa có chính sách (policy) nên ARN sẽ được dùng xử lý và lần thứ hai sẽ gán các chính sách (policies) vào các role đã có tham chiếu đến các tài nguyên trong Tài khoản tooling.
Thay thế giá trị biến ImageRepositoryArn và ArtifactBucketArn bằng giá trị đầu ra từ bước trên trong lệnh bên dưới và chạy nó từ thư mục templates bằng cách sử dụng profile có tên Test và Prod.
Test profile
aws cloudformation deploy --template-file crossaccount_pipeline_roles.yml --stack-name codepipeline-crossaccount-roles --capabilities CAPABILITY_NAMED_IAM --profile test --parameter-overrides ToolAccountID=${TOOLS_ACCOUNT_ID} ImageRepositoryArn=<ImageRepositoryArn value> ArtifactsBucketArn=<ArtifactsBucketArn value>
Prod profile
aws cloudformation deploy --template-file crossaccount_pipeline_roles.yml --stack-name codepipeline-crossaccount-roles --capabilities CAPABILITY_NAMED_IAM --profile prod --parameter-overrides ToolAccountID=${TOOLS_ACCOUNT_ID} ImageRepositoryArn=<ImageRepositoryArn value> ArtifactsBucketArn=<ArtifactsBucketArn value>
Triển khai pipeline
Thay thế giá trị DeploymentRegion bằng giá trị AWS Region hiện tại và CodeCommitRepositoryName bằng tên CodeCommit repository trong tệp codepipeline_parameters.json.
Đẩy code mới với các thay đổi vào CodeCommit Repo sử dụng lệnh Git.
Thay thế giá trị CodeCommitRepositoryName bằng tên CodeCommit repository được tạo ở bước đầu tiên và chạy lệnh sau từ thư mục gốc của dự án bằng cách sử dụng profile có tên tooling.
sam deploy -t codepipeline.yaml --stack-name cicd-lambda-container-pipeline --capabilities=CAPABILITY_IAM --parameter-overrides CodeCommitRepositoryName=<CodeCommit Repository Name> --profile tooling
4. Dọn dẹp tài nguyên
- Chạy lệnh sau trong thư mục gốc của dự án để xóa pipeline:
sam delete --stack-name cicd-lambda-container-pipeline --profile tooling
- Làm trống artifacts bucket. Thaythế tên artifacts bucket bằng giá trị đầu ra từ bước trước đó:
aws s3 rm s3://<Arifacts bucket name> --recursive --profile tooling
- Xóa các hàm Lambda khỏi tài khoản test và prod:
aws cloudformation delete-stack --stack-name lambda-container-app-test --profile test
aws cloudformation delete-stack --stack-name lambda-container-app-prod --profile prod
- Xóa các cross-account role khỏi tài khoản test và prod:
aws cloudformation delete-stack --stack-name codepipeline-crossaccount-roles --profile test
aws cloudformation delete-stack --stack-name codepipeline-crossaccount-roles --profile prod
- Xóa kho lưu trữ ECR:
aws ecr delete-repository --repository-name image-repository --profile tooling --force
- Xóa tài nguyên khỏi tài khoản tooling:
aws cloudformation delete-stack --stack-name tooling-resources --profile tooling
III. Kết luận
Bài đăng này thảo luận về cách tự động hóa việc triển khai Lambda dựa trên container ở nhiều tài khoản khác nhau bằng AWS SAM Pipelines.
Chuyển đến GitHub Repo và xem lại quá trình triển khai để xem cách CodePipeline đẩy container image lên Amazon ECR và triển khai image lên Lambda bằng cross-account role. Kiểm tra tệp codepipeline.yml để xem AWS SAM Pipeline tạo tài nguyên CI/CD bằng template như thế nào.
Để tìm thêm học liệu về chủ đề Serverless, hãy truy cập Serverless Land.