Aller au contenu

CodePipeline de bout en bout pour un SaaS — le gabarit qui livre vraiment en prod

Une référence complète de pipeline SaaS : Source, Build, tests en parallèle, déploiement staging, approbation manuelle, prod blue/green, validation post-déploiement. La strophe CloudFormation pour chaque étape, pas le diagramme marketing.

Une équipe SaaS a une application fonctionnelle, CodeBuild assemblé à la main et un script de déploiement que quelqu’un lance depuis son portable après un message Slack. Elle veut un vrai pipeline avant la prochaine revue de conformité. Elle a regardé les diagrammes d’architecture de référence AWS et les a trouvés trop génériques pour être copiés — les diagrammes montrent des boîtes « Build » et « Deploy », pas le paramètre aws cloudformation qui fait que l’étape de déploiement 4b ne s’exécute que si la 4a a réussi. Le pipeline ci-dessous est une définition CodePipeline fonctionnelle pour un SaaS typique — Source depuis un fournisseur Git, étapes de tests en parallèle, auto-déploiement staging, approbation manuelle, prod en blue/green via CodeDeploy, et une porte de validation post-déploiement.

Ce qui se passe

Un CodePipeline complet pour un SaaS a six étapes, dans cet ordre :

  1. Source — récupère le commit depuis CodeCommit ou GitHub via CodeStar Connections. Sortie : un seul artéfact zippé depuis le dépôt.
  2. Build — CodeBuild compile, fait le lint, lance les tests unitaires, produit l’artéfact déployable (image conteneur vers ECR, zip lambda vers S3, ou les deux). Sortie : artéfact de build plus un manifeste.
  3. Test — trois actions CodeBuild en parallèle : tests d’intégration sur un environnement éphémère, scan de sécurité (Snyk/Trivy/AWS Inspector) et plan d’infrastructure (terraform plan ou cdk diff). Les trois doivent réussir.
  4. Deploy-Staging — CodeDeploy ou CloudFormation pousse l’artéfact vers le compte staging. Sortie : santé du point d’accès staging.
  5. Approbation manuelle — SNS notifie le gestionnaire de compte de garde, qui clique approuver dans la console après un smoke-test du staging. L’approbation est la porte ; sans elle, l’étape prod ne s’exécute pas.
  6. Deploy-Prod — CodeDeploy en blue/green vers la production, avec rollback sur alarme. Sortie : santé du point d’accès prod, alarmes CloudWatch armées.
  7. Validation post-déploiement — action CodeBuild finale qui exécute des transactions synthétiques contre la prod. Si une synthétique échoue dans la fenêtre de validation, CodeDeploy effectue un rollback automatique de la bascule blue/green.

L’ordre compte. Source puis build puis test donne un échec rapide — une erreur de syntaxe n’atteint jamais l’étape de déploiement. Deploy-staging avant l’approbation manuelle signifie que l’approbateur voit un vrai point d’accès staging, pas un rapport de build. Approbation manuelle avant prod est la barre de sécurité que l’auditeur cherchera. La validation post-déploiement après la bascule attrape les pannes qui n’apparaissent que sous le trafic prod.

Comment vérifier

La définition de pipeline ci-dessous est en CloudFormation. Déposez-la dans un template, déployez-la, et le pipeline complet existe en 5 minutes. Les étapes référencent des projets CodeBuild et des applications CodeDeploy qui doivent exister séparément — les strophes pour les créer sont sous le pipeline.

AppPipeline:
  Type: AWS::CodePipeline::Pipeline
  Properties:
    Name: !Sub ${AppName}-pipeline
    RoleArn: !GetAtt PipelineRole.Arn
    ArtifactStore:
      Type: S3
      Location: !Ref ArtifactBucket
      EncryptionKey:
        Id: !GetAtt ArtifactKey.Arn
        Type: KMS
    Stages:
      - Name: Source
        Actions:
          - Name: Source
            ActionTypeId:
              Category: Source
              Owner: AWS
              Provider: CodeStarSourceConnection
              Version: '1'
            Configuration:
              ConnectionArn: !Ref GitHubConnection
              FullRepositoryId: 'stackharbor/app'
              BranchName: main
              DetectChanges: true
            OutputArtifacts:
              - Name: SourceOutput

      - Name: Build
        Actions:
          - Name: Build
            ActionTypeId:
              Category: Build
              Owner: AWS
              Provider: CodeBuild
              Version: '1'
            Configuration:
              ProjectName: !Ref BuildProject
            InputArtifacts:
              - Name: SourceOutput
            OutputArtifacts:
              - Name: BuildOutput

      - Name: Test
        Actions:
          - Name: IntegrationTests
            RunOrder: 1
            ActionTypeId: { Category: Test, Owner: AWS, Provider: CodeBuild, Version: '1' }
            Configuration: { ProjectName: !Ref IntegrationTestProject }
            InputArtifacts: [{ Name: BuildOutput }]
          - Name: SecurityScan
            RunOrder: 1
            ActionTypeId: { Category: Test, Owner: AWS, Provider: CodeBuild, Version: '1' }
            Configuration: { ProjectName: !Ref SecurityScanProject }
            InputArtifacts: [{ Name: BuildOutput }]
          - Name: InfraPlan
            RunOrder: 1
            ActionTypeId: { Category: Test, Owner: AWS, Provider: CodeBuild, Version: '1' }
            Configuration: { ProjectName: !Ref InfraPlanProject }
            InputArtifacts: [{ Name: BuildOutput }]

      - Name: DeployStaging
        Actions:
          - Name: DeployStaging
            ActionTypeId: { Category: Deploy, Owner: AWS, Provider: CodeDeploy, Version: '1' }
            Configuration:
              ApplicationName: !Ref StagingApp
              DeploymentGroupName: !Ref StagingGroup
            InputArtifacts: [{ Name: BuildOutput }]
            RoleArn: !GetAtt CrossAccountStagingRole.Arn

      - Name: Approval
        Actions:
          - Name: ManualApproval
            ActionTypeId: { Category: Approval, Owner: AWS, Provider: Manual, Version: '1' }
            Configuration:
              NotificationArn: !Ref ApprovalTopic
              CustomData: 'Vérifier le point d''accès staging, puis approuver pour déployer en prod.'
              ExternalEntityLink: !Sub 'https://staging.${DomainName}/healthz'

      - Name: DeployProd
        Actions:
          - Name: DeployProd
            ActionTypeId: { Category: Deploy, Owner: AWS, Provider: CodeDeploy, Version: '1' }
            Configuration:
              ApplicationName: !Ref ProdApp
              DeploymentGroupName: !Ref ProdGroup
            InputArtifacts: [{ Name: BuildOutput }]
            RoleArn: !GetAtt CrossAccountProdRole.Arn

      - Name: PostDeployValidation
        Actions:
          - Name: Synthetics
            ActionTypeId: { Category: Test, Owner: AWS, Provider: CodeBuild, Version: '1' }
            Configuration: { ProjectName: !Ref ProdSyntheticsProject }
            InputArtifacts: [{ Name: BuildOutput }]

Les groupes de déploiement (ProdGroup) référencent une application CodeDeploy avec DeploymentStyle: BLUE_GREEN et AlarmConfiguration pointant vers les alarmes CloudWatch qui déclenchent le rollback. Le blue/green garde l’ensemble de tâches précédent actif jusqu’à ce que le nouveau passe le transfert de trafic, et le rollback automatique piloté par alarme est ce qui rend la porte de synthétiques digne de confiance.

La correction

Cinq règles qu’on applique à chaque pipeline SaaS avant de le déclarer prêt pour la production :

Un artéfact, plusieurs étapes. L’artéfact de build produit à l’étape Build traverse staging et prod inchangé. Re-builder entre staging et prod est la façon la plus commune de livrer « staging testé, prod non testée » — et la façon la plus commune d’échouer une validation post-bascule qui aurait dû être impossible à échouer.

Tests en parallèle, portes en série. Intégration, sécurité et plan d’infra s’exécutent en parallèle dans l’étape Test (RunOrder: 1). Approbation manuelle et déploiement prod sont en série — ils ne peuvent pas démarrer tant que le RunOrder de l’étape précédente n’est pas satisfait. Mélanger les deux ne coûte rien en CloudFormation et économise des minutes par exécution de pipeline.

L’approbation manuelle est la porte, pas la documentation. L’action d’approbation ci-dessus a un ExternalEntityLink vers le point d’accès healthz du staging — ce lien est ce sur quoi l’approbateur clique avant d’approuver. Le NotificationArn est le sujet SNS qui contacte le gestionnaire de compte de garde. Configurez les deux. Une approbation manuelle sans notification est un pipeline qui se bloque silencieusement pendant 7 jours.

Déploiement multi-compte via RoleArn, pas des clés d’accès. Le RoleArn sur les actions de déploiement pointe vers un rôle dans le compte cible qui fait confiance au compte pipeline. C’est le pattern IAM-natif que CodePipeline fait mieux que la plupart des outils CI — il n’y a aucune authentification de longue durée nulle part dans le pipeline.

La validation post-déploiement n’est pas optionnelle. L’étape PostDeployValidation exécute des synthétiques contre la prod. Si elle échoue, l’AlarmConfiguration de CodeDeploy fait un rollback automatique du blue/green. Sans cette étape, un déploiement qui livre un point d’accès en erreur 500 reste actif jusqu’à ce que le garde remarque l’alarme — des minutes que vous n’avez pas sur un SaaS payant.

Le gabarit complet est le point de départ. Le travail après ça est spécifique au projet : quelles variables d’environnement, quelle image CodeBuild, quel framework de test. La forme du pipeline reste la même.


Stack Harbor bâtit et opère les workflows CodePipeline en production dans le cadre de l’onboarding Gestion AWS et de la couche Pipeline de déploiement en continu. Si votre chemin de release passe encore par SSH et un message Slack, commencez par une consultation d’infrastructure.