amazon-web-services - 为 AWS Cognito + API Gateway + Lambdas + DynamoDB + SNS 创建 CI 管道的最佳实践
问题描述
从 AWS 开始,并希望从一开始就做好。拥有完整 CI 管道的当前最先进的方法是什么?
我们的想法是将所有内容都放在公司的本地 git 存储库中,然后我们可以触发部署到不同的 AWS 阶段。一切都是我们的意思,所以我们可以自动化一切,并且完全无需 aws Web 界面即可生活。
我浏览了一些教程,他们似乎都以不同的方式做这件事,出现了 Apex、Amplify、CloudFormation、SAM 等工具,其中一些似乎很旧并且已被弃用。因此,我们试图弄清楚,当前的技术是什么,哪些不应该再使用。
哪个编辑器好?是否有任何支持直接从 IDE 使用的插件部署?
此外,如果有一个示例项目可以完成所有这些或大部分工作,那将是一个真正的帮助!
解决方案
我个人的“最新技术”如下:
- 对于每个(mirco)服务,我在 AWS CodeCommit 中创建一个单独的 Git 存储库
- 每个存储库都有自己的带有 AWS CodePipeline 的 CI/CD 管道。管道有以下阶段:
- 来源 (AWS CodeCommit)
- 构建 (AWS CodeBuild)
- 部署暂存[*] (AWS CloudFormation)
- 批准(手动批准)
- 部署生产[*] (AWS CloudFormation)
整个基础设施和管道都是用 CloudFormation 编写的(在AWS SAM Syntax中),我强烈建议也这样做。这也将帮助您解决您的要求“ [...] 完全没有 aws Web 界面。 ”
[*]:两个阶段都使用相同的(!)AWS CloudFormation 模板,我只是将不同的Environment
参数传递到基础设施模板中,以便能够根据环境做出一些差异。
我的大部分服务都是用 TypeScript 编写的,为了开发它,我使用WebStorm和一个很酷的插件来帮助我编写 AWS CloudFormation 模板。
示例pipeline.yml
:
AWSTemplateFormatVersion: 2010-09-09
Parameters:
RepositoryName:
Type: String
ArtifactStoreBucket:
Type: String
Resources:
Pipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
RoleArn: !GetAtt CodePipelineRole.Arn
ArtifactStore:
Location: !Ref ArtifactStoreBucket
Type: S3
Stages:
- Name: Source
Actions:
- Name: CodeCommit
ActionTypeId:
Category: Source
Owner: AWS
Version: 1
Provider: CodeCommit
Configuration:
RepositoryName: !Ref RepositoryName
BranchName: master
InputArtifacts: []
OutputArtifacts:
- Name: SourceOutput
RunOrder: 1
- Name: Build
Actions:
- Name: Build
ActionTypeId:
Category: Build
Owner: AWS
Version: 1
Provider: CodeBuild
Configuration:
ProjectName: !Ref Build
InputArtifacts:
- Name: SourceOutput
OutputArtifacts:
- Name: BuildOutput
RunOrder: 1
- Name: Staging
Actions:
- Name: Deploy
ActionTypeId:
Category: Deploy
Owner: AWS
Version: 1
Provider: CloudFormation
Configuration:
ActionMode: CREATE_UPDATE
Capabilities: CAPABILITY_IAM,CAPABILITY_AUTO_EXPAND
StackName: !Sub ${AWS::StackName}-Infrastructure-Staging
RoleArn: !GetAtt CloudFormationRole.Arn
TemplatePath: BuildOutput::infrastructure-packaged.yml
ParameterOverrides:
!Sub |
{
"Environment": "Staging"
}
InputArtifacts:
- Name: BuildOutput
OutputArtifacts: []
RunOrder: 1
- Name: Approval
Actions:
- Name: Approval
ActionTypeId:
Category: Approval
Owner: AWS
Version: 1
Provider: Manual
InputArtifacts: []
OutputArtifacts: []
RunOrder: 1
- Name: Production
Actions:
- Name: Deploy
ActionTypeId:
Category: Deploy
Owner: AWS
Version: 1
Provider: CloudFormation
Configuration:
ActionMode: CREATE_UPDATE
Capabilities: CAPABILITY_IAM,CAPABILITY_AUTO_EXPAND
StackName: !Sub ${AWS::StackName}-Infrastructure-Production
RoleArn: !GetAtt CloudFormationRole.Arn
TemplatePath: BuildOutput::infrastructure-packaged.yml
ParameterOverrides:
!Sub |
{
"Environment": "Production"
}
InputArtifacts:
- Name: BuildOutput
OutputArtifacts: []
RunOrder: 1
Build:
Type: AWS::CodeBuild::Project
Properties:
Artifacts:
Type: CODEPIPELINE
Environment:
ComputeType: BUILD_GENERAL1_MEDIUM
Image: aws/codebuild/nodejs:10.14.1
Type: LINUX_CONTAINER
Name: !Sub ${AWS::StackName}-Build
ServiceRole: !Ref CodeBuildRole
Source:
Type: CODEPIPELINE
BuildSpec:
!Sub |
version: 0.2
phases:
build:
commands:
- npm install
- npm run lint
- npm run test:unit
- npm run build
- aws cloudformation package --s3-bucket ${ArtifactStoreBucket} --template-file ./infrastructure.yml --output-template-file infrastructure-packaged.yml
artifacts:
files:
- infrastructure-packaged.yml
BuildLogGroup:
Type: AWS::Logs::LogGroup
Properties:
RetentionInDays: 14
LogGroupName: !Sub /aws/codebuild/${Build}
CodePipelineRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: codepipeline.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: CodePipelineRolePolicy
PolicyDocument:
Statement:
- Effect: Allow
Action:
- iam:PassRole
Resource:
- !GetAtt CloudFormationRole.Arn
- Effect: Allow
Action:
- s3:*
Resource:
- !Sub arn:aws:s3:::${ArtifactStoreBucket}/*
- Effect: Allow
Action:
- codecommit:*
Resource:
- !Sub arn:aws:codecommit:${AWS::Region}:${AWS::AccountId}:${RepositoryName}
- Effect: Allow
Action:
- codebuild:*
Resource:
- !Sub arn:aws:codebuild:${AWS::Region}:${AWS::AccountId}:project/${AWS::StackName}-Build
- Effect: Allow
Action:
- cloudformation:*
Resource:
- !Sub arn:aws:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/${AWS::StackName}-Infrastructure-Staging/*
- !Sub arn:aws:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/${AWS::StackName}-Infrastructure-Production/*
CodeBuildRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: codebuild.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: CodeBuildRolePolicy
PolicyDocument:
Statement:
- Effect: Allow
Action:
- s3:*
Resource:
- !Sub arn:aws:s3:::${ArtifactStoreBucket}/*
- Effect: Allow
Action:
- codecommit:*
Resource:
- !Sub arn:aws:codecommit:${AWS::Region}:${AWS::AccountId}:${RepositoryName}
- Effect: Allow
Action:
- logs:*
Resource:
- !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${AWS::StackName}-Build*
CloudFormationRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: cloudformation.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AdministratorAccess
示例infrastructure.yml
:
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Parameters:
Environment:
Type: String
AllowedValues:
- Staging
- Production
Resources:
Api:
Type: AWS::Serverless::Function
Properties:
Handler: api.handler
CodeUri: .build
Runtime: nodejs10.x
MemorySize: 128
Timeout: 10
Events:
ProxyApi:
Type: Api
Properties:
Path: /{proxy+}
Method: ANY
Environment:
Variables:
ENVIRONMENT: !Ref Environment
DeploymentPreference:
Enabled: false
ApiLogGroup:
Type: AWS::Logs::LogGroup
Properties:
RetentionInDays: 14
LogGroupName: !Sub /aws/lambda/${Api}
Outputs:
ApiEndpoint:
Value: !Sub https://${ServerlessRestApi}.execute-api.${AWS::Region}.${AWS::URLSuffix}/${ServerlessRestApiProdStage}
推荐阅读
- google-bigquery - 将广泛而深入的 BigQuery 表导入 Google Dataprep
- r - 在函数参数中使用文件名
- azure - 将 Azure VM 和 On Prem 服务器连接到 Azure Active Directory 域服务
- neo4j - 在多个节点之间创建关系时出错
- c# - 在存储在共享目录中的 C# WPF 应用程序中使用哪个数据库?
- mysql - 用新字符串更新字符串
- python - 如何从字典python中获取键和值
- r - 将列表元素(表)的频率转换为 R 中的数据框
- oracle - 创建表后在光标中选择表
- python - 遍历列表并将结果附加到熊猫数据框