Лучшие практики для создания конвейера CI для AWS Cognito + API Gateway + Lambdas + DynamoDB + SNS - PullRequest
1 голос
/ 13 октября 2019

Начиная с AWS и хочу делать это с самого начала. Каков нынешний современный подход к созданию полного конвейера CI?

Наша идея состоит в том, чтобы иметь все в локальном git-репозитории в компании, и тогда мы можем инициировать развертывание на разных этапах AWS. И со всем мы имеем в виду все, поэтому мы можем автоматизировать все и жить полностью без веб-интерфейса aws.

Я прошел некоторые уроки, и все они, кажется, делают это по-разному, инструменты lile Apex, Amplify, CloudFormation, SAMи т. д., и некоторые из них, кажется, очень старые и устарели. Таким образом, мы пытаемся получить четкое представление о том, каковы текущие технологии и какие из них больше не должны использоваться.

Какие редакторы были бы хороши? Есть ли какие-либо, которые поддерживают развертывание с помощью плагинов для использования непосредственно из IDE?

Также, если есть пример проекта, который выполняет все это или большинство, это будет реальная помощь!

1 Ответ

0 голосов
/ 14 октября 2019

Мой личный «уровень техники» заключается в следующем:

  • Для каждого (mirco) сервиса я создаю отдельный репозиторий Git в AWS CodeCommit
  • Каждый репозиторий имеетсобственный конвейер CI / CD с AWS CodePipeline. Конвейер имеет следующие этапы:
    • Источник (AWS CodeCommit)
    • Сборка (AWS CodeBuild)
    • Развертывание Staging [*] (AWS CloudFormation)
    • Утверждение (ручное утверждение)
    • Развертывание производства [*] (AWS CloudFormation)

Вся инфраструктура и конвейер написаны в CloudFormation (в AWSСинтаксис SAM ) и я настоятельно рекомендую сделать то же самое. Это также поможет вам выполнить ваше требование " [...] полностью без веб-интерфейса aws. "

[*] : на обоих этапах используетсятот же (!) шаблон AWS CloudFormation, я просто передаю другой параметр Environment в шаблон инфраструктуры, чтобы иметь возможность внести некоторые отличия в зависимости от env.

Большинство моих услугнаписанный для 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}
...