Intégration et livraison continues (CI/CD) à l'aide de CDK Pipelines - AWS Cloud Development Kit (AWS CDK) v2

Ceci est le guide du AWS CDK développeur de la version 2. L'ancienne CDK version 1 est entrée en maintenance le 1er juin 2022 et a pris fin le 1er juin 2023.

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Intégration et livraison continues (CI/CD) à l'aide de CDK Pipelines

Utilisez le module CDK Pipelines de AWS la bibliothèque Construct pour configurer la livraison continue AWS CDK des applications. Lorsque vous validez le code source de votre application CDK dans AWS CodeCommitGitHub AWS CodeStar, CDK Pipelines peut automatiquement créer, tester et déployer votre nouvelle version.

Les CDK Pipelines se mettent à jour automatiquement. Si vous ajoutez des étapes ou des piles d'application, le pipeline se reconfigure automatiquement pour déployer ces nouvelles étapes ou piles.

Note

CDK Pipelines prend en charge deux API. L'une est l'API originale qui a été mise à disposition dans la version préliminaire de CDK Pipelines pour les développeurs. L'autre est une API moderne qui intègre les commentaires des clients du CDK reçus lors de la phase de prévisualisation. Les exemples présentés dans cette rubrique utilisent l'API moderne. Pour plus de détails sur les différences entre les deux API prises en charge, consultez l'API originale de CDK Pipelines dans le référentiel GitHub aws-cdk.

Bootstrap vos environnements AWS

Avant de pouvoir utiliser CDK Pipelines, vous devez démarrer AWS l'environnement dans lequel vous allez déployer vos stacks.

Un pipeline CDK implique au moins deux environnements. Le premier environnement est celui où le pipeline est approvisionné. Le second environnement est celui dans lequel vous souhaitez déployer les piles ou les étapes de l'application (les étapes sont des groupes de piles connexes). Ces environnements peuvent être identiques, mais l'une des meilleures pratiques consiste à isoler les étapes les unes des autres dans des environnements différents.

Note

Consultez AWS CDK bootstrap pour plus d'informations sur les types de ressources créées par le bootstrap et sur la façon de personnaliser la pile bootstrap.

Le déploiement continu avec CDK Pipelines nécessite l'inclusion des éléments suivants dans la pile CDK Toolkit :

  • Un bucket Amazon Simple Storage Service (Amazon S3).

  • Un référentiel Amazon ECR.

  • Des rôles IAM pour donner aux différentes parties d'un pipeline les autorisations dont elles ont besoin.

Le kit d'outils CDK mettra à niveau votre stack bootstrap existant ou en créera un nouveau si nécessaire.

Pour démarrer un environnement capable de provisionner un AWS CDK pipeline, invoquez-le cdk bootstrap comme indiqué dans l'exemple suivant. L'invocation du AWS CDK Toolkit via la npx commande l'installe temporairement si nécessaire. Il utilisera également la version du Toolkit installée dans le projet en cours, s'il en existe une.

--cloudformation-execution-policiesspécifie l'ARN d'une politique selon laquelle les futurs déploiements de CDK Pipelines seront exécutés. La AdministratorAccess politique par défaut garantit que votre pipeline peut déployer tous les types de AWS ressources. Si vous utilisez cette politique, assurez-vous de faire confiance à l'ensemble du code et aux dépendances qui constituent votre AWS CDK application.

La plupart des organisations imposent des contrôles plus stricts sur les types de ressources pouvant être déployés par automatisation. Renseignez-vous auprès du service approprié au sein de votre organisation pour déterminer la politique que votre pipeline doit utiliser.

Vous pouvez omettre --profile cette option si votre AWS profil par défaut contient la configuration d'authentification nécessaire et Région AWS.

macOS/Linux
npx cdk bootstrap aws://ACCOUNT-NUMBER/REGION --profile ADMIN-PROFILE \ --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess
Windows
npx cdk bootstrap aws://ACCOUNT-NUMBER/REGION --profile ADMIN-PROFILE ^ --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess

Pour démarrer des environnements supplémentaires dans lesquels AWS CDK les applications seront déployées par le pipeline, utilisez plutôt les commandes suivantes. L'--trustoption indique quel autre compte doit être autorisé à déployer AWS CDK des applications dans cet environnement. Pour cette option, spécifiez l'ID de AWS compte du pipeline.

Encore une fois, vous pouvez omettre --profile cette option si votre AWS profil par défaut contient la configuration d'authentification nécessaire et Région AWS.

macOS/Linux
npx cdk bootstrap aws://ACCOUNT-NUMBER/REGION --profile ADMIN-PROFILE \ --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess \ --trust PIPELINE-ACCOUNT-NUMBER
Windows
npx cdk bootstrap aws://ACCOUNT-NUMBER/REGION --profile ADMIN-PROFILE ^ --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess ^ --trust PIPELINE-ACCOUNT-NUMBER
Astuce

Utilisez les informations d'identification administratives uniquement pour démarrer et approvisionner le pipeline initial. Ensuite, utilisez le pipeline lui-même, et non votre machine locale, pour déployer les modifications.

Si vous mettez à niveau un environnement bootstrap existant, le compartiment Amazon S3 précédent devient orphelin lors de la création du nouveau compartiment. Supprimez-le manuellement à l'aide de la console Amazon S3.

Protéger votre stack bootstrap contre la suppression

Si une pile bootstrap est supprimée, les AWS ressources initialement provisionnées dans l'environnement pour prendre en charge les déploiements de CDK seront également supprimées. Cela empêchera le pipeline de fonctionner. Dans ce cas, il n'existe pas de solution générale pour le rétablissement.

Une fois votre environnement amorcé, ne supprimez pas et ne recréez pas la pile d'amorçage de l'environnement. Essayez plutôt de mettre à jour la pile bootstrap vers une nouvelle version en exécutant à nouveau la cdk bootstrap commande.

Pour vous protéger contre la suppression accidentelle de votre stack bootstrap, nous vous recommandons de fournir l'--termination-protectionoption avec la cdk bootstrap commande permettant d'activer la protection contre la résiliation. Vous pouvez activer la protection contre la résiliation sur les piles de bootstrap nouvelles ou existantes. Pour en savoir plus sur cette option, consultez--termination-protection.

Après avoir activé la protection contre la résiliation, vous pouvez utiliser la CloudFormation console AWS CLI or pour vérifier.

Pour activer la protection contre le licenciement
  1. Exécutez la commande suivante pour activer la protection contre la résiliation sur une pile bootstrap nouvelle ou existante :

    $ cdk bootstrap --termination-protection
  2. Utilisez la CloudFormation console AWS CLI or pour vérifier. Voici un exemple avec utilisation de l' AWS CLI. Si vous avez modifié le nom de votre pile bootstrap, remplacez-le CDKToolkit par le nom de votre pile :

    $ aws cloudformation describe-stacks --stack-name CDKToolkit --query "Stacks[0].EnableTerminationProtection" true

Initialisation d'un projet

Créez un nouveau GitHub projet vide et clonez-le sur votre poste de travail dans le my-pipeline répertoire. (Les exemples de code présentés dans cette rubrique utilisent GitHub. Vous pouvez également utiliser AWS CodeStar ou AWS CodeCommit.)

git clone GITHUB-CLONE-URL my-pipeline cd my-pipeline
Note

Vous pouvez utiliser un nom autre que celui my-pipeline du répertoire principal de votre application. Toutefois, si vous le faites, vous devrez modifier les noms de fichiers et de classes plus loin dans cette rubrique. Cela est dû au fait que le AWS CDK Toolkit base certains noms de fichiers et de classes sur le nom du répertoire principal.

Après le clonage, initialisez le projet comme d'habitude.

TypeScript
$ cdk init app --language typescript
JavaScript
$ cdk init app --language javascript
Python
$ cdk init app --language python

Une fois l'application créée, entrez également les deux commandes suivantes. Ils activent l'environnement virtuel Python de l'application et installent les dépendances AWS CDK principales.

$ source .venv/bin/activate # On Windows, run `.\venv\Scripts\activate` instead $ python -m pip install -r requirements.txt
Java
$ cdk init app --language java

Si vous utilisez un IDE, vous pouvez désormais ouvrir ou importer le projet. Dans Eclipse, par exemple, choisissez Fichier > Importer > Maven > Projets Maven existants. Assurez-vous que les paramètres du projet sont définis pour utiliser Java 8 (1.8).

C#
$ cdk init app --language csharp

Si vous utilisez Visual Studio, ouvrez le fichier de solution dans le src répertoire.

Go
$ cdk init app --language go

Une fois l'application créée, entrez également la commande suivante pour installer les modules AWS Construct Library dont l'application a besoin.

$ go get
Important

Assurez-vous de valider vos cdk.context.json fichiers cdk.json et dans le contrôle de source. Les informations contextuelles (telles que les indicateurs de fonctionnalités et les valeurs mises en cache extraites de votre AWS compte) font partie de l'état de votre projet. Les valeurs peuvent être différentes dans un autre environnement, ce qui peut entraîner des modifications inattendues de vos résultats. Pour plus d’informations, consultez Les valeurs contextuelles et le AWS CDK.

Définition d'un pipeline

Votre application CDK Pipelines comprendra au moins deux piles : une qui représente le pipeline lui-même et une ou plusieurs piles qui représentent l'application déployée par son intermédiaire. Les piles peuvent également être regroupées en étapes, que vous pouvez utiliser pour déployer des copies des piles d'infrastructure dans différents environnements. Pour l'instant, nous examinerons le pipeline, puis nous pencherons sur l'application qu'il déploiera.

La construction CodePipelineest la construction qui représente un pipeline CDK utilisé AWS CodePipeline comme moteur de déploiement. Lorsque vous instanciez CodePipeline dans une pile, vous définissez l'emplacement de la source pour le pipeline (tel qu'un GitHub référentiel). Vous définissez également les commandes pour créer l'application.

Par exemple, ce qui suit définit un pipeline dont la source est stockée dans un GitHub référentiel. Il inclut également une étape de génération pour une application TypeScript CDK. Renseignez les informations relatives à votre GitHub dépôt à l'endroit indiqué.

Note

Par défaut, le pipeline s'authentifie à GitHub l'aide d'un jeton d'accès personnel stocké dans Secrets Manager sous le nomgithub-token.

Vous devrez également mettre à jour l'instanciation de la pile de pipelines pour spécifier le AWS compte et la région.

TypeScript

Dans lib/my-pipeline-stack.ts (peut varier si le dossier de votre projet n'est pas nommémy-pipeline) :

import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; import { CodePipeline, CodePipelineSource, ShellStep } from 'aws-cdk-lib/pipelines'; export class MyPipelineStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); const pipeline = new CodePipeline(this, 'Pipeline', { pipelineName: 'MyPipeline', synth: new ShellStep('Synth', { input: CodePipelineSource.gitHub('OWNER/REPO', 'main'), commands: ['npm ci', 'npm run build', 'npx cdk synth'] }) }); } }

Dans bin/my-pipeline.ts (peut varier si le dossier de votre projet n'est pas nommémy-pipeline) :

#!/usr/bin/env node import * as cdk from 'aws-cdk-lib'; import { MyPipelineStack } from '../lib/my-pipeline-stack'; const app = new cdk.App(); new MyPipelineStack(app, 'MyPipelineStack', { env: { account: '111111111111', region: 'eu-west-1', } }); app.synth();
JavaScript

Dans lib/my-pipeline-stack.js (peut varier si le dossier de votre projet n'est pas nommémy-pipeline) :

const cdk = require('aws-cdk-lib'); const { CodePipeline, CodePipelineSource, ShellStep } = require('aws-cdk-lib/pipelines'); class MyPipelineStack extends cdk.Stack { constructor(scope, id, props) { super(scope, id, props); const pipeline = new CodePipeline(this, 'Pipeline', { pipelineName: 'MyPipeline', synth: new ShellStep('Synth', { input: CodePipelineSource.gitHub('OWNER/REPO', 'main'), commands: ['npm ci', 'npm run build', 'npx cdk synth'] }) }); } } module.exports = { MyPipelineStack }

Dans bin/my-pipeline.js (peut varier si le dossier de votre projet n'est pas nommémy-pipeline) :

#!/usr/bin/env node const cdk = require('aws-cdk-lib'); const { MyPipelineStack } = require('../lib/my-pipeline-stack'); const app = new cdk.App(); new MyPipelineStack(app, 'MyPipelineStack', { env: { account: '111111111111', region: 'eu-west-1', } }); app.synth();
Python

Dans my-pipeline/my-pipeline-stack.py (peut varier si le dossier de votre projet n'est pas nommémy-pipeline) :

import aws_cdk as cdk from constructs import Construct from aws_cdk.pipelines import CodePipeline, CodePipelineSource, ShellStep class MyPipelineStack(cdk.Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) pipeline = CodePipeline(self, "Pipeline", pipeline_name="MyPipeline", synth=ShellStep("Synth", input=CodePipelineSource.git_hub("OWNER/REPO", "main"), commands=["npm install -g aws-cdk", "python -m pip install -r requirements.txt", "cdk synth"] ) )

Dans app.py:

#!/usr/bin/env python3 import aws_cdk as cdk from my_pipeline.my_pipeline_stack import MyPipelineStack app = cdk.App() MyPipelineStack(app, "MyPipelineStack", env=cdk.Environment(account="111111111111", region="eu-west-1") ) app.synth()
Java

Dans src/main/java/com/myorg/MyPipelineStack.java (peut varier si le dossier de votre projet n'est pas nommémy-pipeline) :

package com.myorg; import java.util.Arrays; import software.constructs.Construct; import software.amazon.awscdk.Stack; import software.amazon.awscdk.StackProps; import software.amazon.awscdk.pipelines.CodePipeline; import software.amazon.awscdk.pipelines.CodePipelineSource; import software.amazon.awscdk.pipelines.ShellStep; public class MyPipelineStack extends Stack { public MyPipelineStack(final Construct scope, final String id) { this(scope, id, null); } public MyPipelineStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); CodePipeline pipeline = CodePipeline.Builder.create(this, "pipeline") .pipelineName("MyPipeline") .synth(ShellStep.Builder.create("Synth") .input(CodePipelineSource.gitHub("OWNER/REPO", "main")) .commands(Arrays.asList("npm install -g aws-cdk", "cdk synth")) .build()) .build(); } }

Dans src/main/java/com/myorg/MyPipelineApp.java (peut varier si le dossier de votre projet n'est pas nommémy-pipeline) :

package com.myorg; import software.amazon.awscdk.App; import software.amazon.awscdk.Environment; import software.amazon.awscdk.StackProps; public class MyPipelineApp { public static void main(final String[] args) { App app = new App(); new MyPipelineStack(app, "PipelineStack", StackProps.builder() .env(Environment.builder() .account("111111111111") .region("eu-west-1") .build()) .build()); app.synth(); } }
C#

Dans src/MyPipeline/MyPipelineStack.cs (peut varier si le dossier de votre projet n'est pas nommémy-pipeline) :

using Amazon.CDK; using Amazon.CDK.Pipelines; namespace MyPipeline { public class MyPipelineStack : Stack { internal MyPipelineStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { var pipeline = new CodePipeline(this, "pipeline", new CodePipelineProps { PipelineName = "MyPipeline", Synth = new ShellStep("Synth", new ShellStepProps { Input = CodePipelineSource.GitHub("OWNER/REPO", "main"), Commands = new string[] { "npm install -g aws-cdk", "cdk synth" } }) }); } } }

Dans src/MyPipeline/Program.cs (peut varier si le dossier de votre projet n'est pas nommémy-pipeline) :

using Amazon.CDK; namespace MyPipeline { sealed class Program { public static void Main(string[] args) { var app = new App(); new MyPipelineStack(app, "MyPipelineStack", new StackProps { Env = new Amazon.CDK.Environment { Account = "111111111111", Region = "eu-west-1" } }); app.Synth(); } } }
Go
package main import ( "github.com/aws/aws-cdk-go/awscdk/v2" codebuild "github.com/aws/aws-cdk-go/awscdk/v2/awscodebuild" ssm "github.com/aws/aws-cdk-go/awscdk/v2/awsssm" pipeline "github.com/aws/aws-cdk-go/awscdk/v2/pipelines" "github.com/aws/constructs-go/constructs/v10" "github.com/aws/jsii-runtime-go" "os" ) // my CDK Stack with resources func NewCdkStack(scope constructs.Construct, id *string, props *awscdk.StackProps) awscdk.Stack { stack := awscdk.NewStack(scope, id, props) // create an example ssm parameter _ = ssm.NewStringParameter(stack, jsii.String("ssm-test-param"), &ssm.StringParameterProps{ ParameterName: jsii.String("/testparam"), Description: jsii.String("ssm parameter for demo"), StringValue: jsii.String("my test param"), }) return stack } // my CDK Application func NewCdkApplication(scope constructs.Construct, id *string, props *awscdk.StageProps) awscdk.Stage { stage := awscdk.NewStage(scope, id, props) _ = NewCdkStack(stage, jsii.String("cdk-stack"), &awscdk.StackProps{Env: props.Env}) return stage } // my CDK Pipeline func NewCdkPipeline(scope constructs.Construct, id *string, props *awscdk.StackProps) awscdk.Stack { stack := awscdk.NewStack(scope, id, props) // GitHub repo with owner and repository name githubRepo := pipeline.CodePipelineSource_GitHub(jsii.String("owner/repo"), jsii.String("main"), &pipeline.GitHubSourceOptions{ Authentication: awscdk.SecretValue_SecretsManager(jsii.String("my-github-token"), nil), }) // self mutating pipeline myPipeline := pipeline.NewCodePipeline(stack, jsii.String("cdkPipeline"), &pipeline.CodePipelineProps{ PipelineName: jsii.String("CdkPipeline"), // self mutation true - pipeline changes itself before application deployment SelfMutation: jsii.Bool(true), CodeBuildDefaults: &pipeline.CodeBuildOptions{ BuildEnvironment: &codebuild.BuildEnvironment{ // image version 6.0 recommended for newer go version BuildImage: codebuild.LinuxBuildImage_FromCodeBuildImageId(jsii.String("aws/codebuild/standard:6.0")), }, }, Synth: pipeline.NewCodeBuildStep(jsii.String("Synth"), &pipeline.CodeBuildStepProps{ Input: githubRepo, Commands: &[]*string{ jsii.String("npm install -g aws-cdk"), jsii.String("cdk synth"), }, }), }) // deployment of actual CDK application myPipeline.AddStage(NewCdkApplication(stack, jsii.String("MyApplication"), &awscdk.StageProps{ Env: targetAccountEnv(), }), &pipeline.AddStageOpts{ Post: &[]pipeline.Step{ pipeline.NewCodeBuildStep(jsii.String("Manual Steps"), &pipeline.CodeBuildStepProps{ Commands: &[]*string{ jsii.String("echo \"My CDK App deployed, manual steps go here ... \""), }, }), }, }) return stack } // main app func main() { defer jsii.Close() app := awscdk.NewApp(nil) // call CDK Pipeline NewCdkPipeline(app, jsii.String("CdkPipelineStack"), &awscdk.StackProps{ Env: pipelineEnv(), }) app.Synth(nil) } // env determines the AWS environment (account+region) in which our stack is to // be deployed. For more information see: https://docs.aws.amazon.com/cdk/latest/guide/environments.html func pipelineEnv() *awscdk.Environment { return &awscdk.Environment{ Account: jsii.String(os.Getenv("CDK_DEFAULT_ACCOUNT")), Region: jsii.String(os.Getenv("CDK_DEFAULT_REGION")), } } func targetAccountEnv() *awscdk.Environment { return &awscdk.Environment{ Account: jsii.String(os.Getenv("CDK_DEFAULT_ACCOUNT")), Region: jsii.String(os.Getenv("CDK_DEFAULT_REGION")), } }

Vous devez déployer un pipeline manuellement une fois. Ensuite, le pipeline se tient à jour à partir du référentiel de code source. Assurez-vous donc que le code du dépôt est celui que vous souhaitez déployer. Enregistrez vos modifications, puis envoyez-les GitHub, puis déployez-les :

git add --all git commit -m "initial commit" git push cdk deploy
Astuce

Maintenant que vous avez effectué le déploiement initial, votre AWS compte local n'a plus besoin d'accès administratif. Cela est dû au fait que toutes les modifications apportées à votre application seront déployées via le pipeline. Tout ce que vous devez être capable de faire, c'est d'appuyer dessus GitHub.

Étapes de candidature

Pour définir une AWS application multi-stack pouvant être ajoutée au pipeline en une seule fois, définissez une sous-classe de. Stage (Ceci est différent de celui du CdkStage module CDK Pipelines.)

La scène contient les piles qui constituent votre application. S'il existe des dépendances entre les piles, celles-ci sont automatiquement ajoutées au pipeline dans le bon ordre. Les piles qui ne dépendent pas les unes des autres sont déployées en parallèle. Vous pouvez ajouter une relation de dépendance entre les piles en appelantstack1.addDependency(stack2).

Les stages acceptent un env argument par défaut, qui devient l'environnement par défaut pour les piles qu'ils contiennent. (Les piles peuvent toujours avoir leur propre environnement spécifié.)

Une application est ajoutée au pipeline en appelant addStage() avec des instances de Stage. Une étape peut être instanciée et ajoutée au pipeline plusieurs fois pour définir les différentes étapes de votre pipeline d'applications DTAP ou multirégional.

Nous allons créer une pile contenant une fonction Lambda simple et placer cette pile dans une phase. Ensuite, nous ajouterons la scène au pipeline afin qu'elle puisse être déployée.

TypeScript

Créez le nouveau fichier lib/my-pipeline-lambda-stack.ts contenant notre pile d'applications contenant une fonction Lambda.

import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; import { Function, InlineCode, Runtime } from 'aws-cdk-lib/aws-lambda'; export class MyLambdaStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); new Function(this, 'LambdaFunction', { runtime: Runtime.NODEJS_18_X, handler: 'index.handler', code: new InlineCode('exports.handler = _ => "Hello, CDK";') }); } }

Créez le nouveau fichier lib/my-pipeline-app-stage.ts pour héberger notre scène.

import * as cdk from 'aws-cdk-lib'; import { Construct } from "constructs"; import { MyLambdaStack } from './my-pipeline-lambda-stack'; export class MyPipelineAppStage extends cdk.Stage { constructor(scope: Construct, id: string, props?: cdk.StageProps) { super(scope, id, props); const lambdaStack = new MyLambdaStack(this, 'LambdaStack'); } }

Modifiez lib/my-pipeline-stack.ts pour ajouter l'étape à notre pipeline.

import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; import { CodePipeline, CodePipelineSource, ShellStep } from 'aws-cdk-lib/pipelines'; import { MyPipelineAppStage } from './my-pipeline-app-stage'; export class MyPipelineStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); const pipeline = new CodePipeline(this, 'Pipeline', { pipelineName: 'MyPipeline', synth: new ShellStep('Synth', { input: CodePipelineSource.gitHub('OWNER/REPO', 'main'), commands: ['npm ci', 'npm run build', 'npx cdk synth'] }) }); pipeline.addStage(new MyPipelineAppStage(this, "test", { env: { account: "111111111111", region: "eu-west-1" } })); } }
JavaScript

Créez le nouveau fichier lib/my-pipeline-lambda-stack.js contenant notre pile d'applications contenant une fonction Lambda.

const cdk = require('aws-cdk-lib'); const { Function, InlineCode, Runtime } = require('aws-cdk-lib/aws-lambda'); class MyLambdaStack extends cdk.Stack { constructor(scope, id, props) { super(scope, id, props); new Function(this, 'LambdaFunction', { runtime: Runtime.NODEJS_18_X, handler: 'index.handler', code: new InlineCode('exports.handler = _ => "Hello, CDK";') }); } } module.exports = { MyLambdaStack }

Créez le nouveau fichier lib/my-pipeline-app-stage.js pour héberger notre scène.

const cdk = require('aws-cdk-lib'); const { MyLambdaStack } = require('./my-pipeline-lambda-stack'); class MyPipelineAppStage extends cdk.Stage { constructor(scope, id, props) { super(scope, id, props); const lambdaStack = new MyLambdaStack(this, 'LambdaStack'); } } module.exports = { MyPipelineAppStage };

Modifiez lib/my-pipeline-stack.ts pour ajouter l'étape à notre pipeline.

const cdk = require('aws-cdk-lib'); const { CodePipeline, CodePipelineSource, ShellStep } = require('aws-cdk-lib/pipelines'); const { MyPipelineAppStage } = require('./my-pipeline-app-stage'); class MyPipelineStack extends cdk.Stack { constructor(scope, id, props) { super(scope, id, props); const pipeline = new CodePipeline(this, 'Pipeline', { pipelineName: 'MyPipeline', synth: new ShellStep('Synth', { input: CodePipelineSource.gitHub('OWNER/REPO', 'main'), commands: ['npm ci', 'npm run build', 'npx cdk synth'] }) }); pipeline.addStage(new MyPipelineAppStage(this, "test", { env: { account: "111111111111", region: "eu-west-1" } })); } } module.exports = { MyPipelineStack }
Python

Créez le nouveau fichier my_pipeline/my_pipeline_lambda_stack.py contenant notre pile d'applications contenant une fonction Lambda.

import aws_cdk as cdk from constructs import Construct from aws_cdk.aws_lambda import Function, InlineCode, Runtime class MyLambdaStack(cdk.Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) Function(self, "LambdaFunction", runtime=Runtime.NODEJS_18_X, handler="index.handler", code=InlineCode("exports.handler = _ => 'Hello, CDK';") )

Créez le nouveau fichier my_pipeline/my_pipeline_app_stage.py pour héberger notre scène.

import aws_cdk as cdk from constructs import Construct from my_pipeline.my_pipeline_lambda_stack import MyLambdaStack class MyPipelineAppStage(cdk.Stage): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) lambdaStack = MyLambdaStack(self, "LambdaStack")

Modifiez my_pipeline/my-pipeline-stack.py pour ajouter l'étape à notre pipeline.

import aws_cdk as cdk from constructs import Construct from aws_cdk.pipelines import CodePipeline, CodePipelineSource, ShellStep from my_pipeline.my_pipeline_app_stage import MyPipelineAppStage class MyPipelineStack(cdk.Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) pipeline = CodePipeline(self, "Pipeline", pipeline_name="MyPipeline", synth=ShellStep("Synth", input=CodePipelineSource.git_hub("OWNER/REPO", "main"), commands=["npm install -g aws-cdk", "python -m pip install -r requirements.txt", "cdk synth"])) pipeline.add_stage(MyPipelineAppStage(self, "test", env=cdk.Environment(account="111111111111", region="eu-west-1")))
Java

Créez le nouveau fichier src/main/java/com.myorg/MyPipelineLambdaStack.java contenant notre pile d'applications contenant une fonction Lambda.

package com.myorg; import software.constructs.Construct; import software.amazon.awscdk.Stack; import software.amazon.awscdk.StackProps; import software.amazon.awscdk.services.lambda.Function; import software.amazon.awscdk.services.lambda.Runtime; import software.amazon.awscdk.services.lambda.InlineCode; public class MyPipelineLambdaStack extends Stack { public MyPipelineLambdaStack(final Construct scope, final String id) { this(scope, id, null); } public MyPipelineLambdaStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); Function.Builder.create(this, "LambdaFunction") .runtime(Runtime.NODEJS_18_X) .handler("index.handler") .code(new InlineCode("exports.handler = _ => 'Hello, CDK';")) .build(); } }

Créez le nouveau fichier src/main/java/com.myorg/MyPipelineAppStage.java pour héberger notre scène.

package com.myorg; import software.constructs.Construct; import software.amazon.awscdk.Stack; import software.amazon.awscdk.Stage; import software.amazon.awscdk.StageProps; public class MyPipelineAppStage extends Stage { public MyPipelineAppStage(final Construct scope, final String id) { this(scope, id, null); } public MyPipelineAppStage(final Construct scope, final String id, final StageProps props) { super(scope, id, props); Stack lambdaStack = new MyPipelineLambdaStack(this, "LambdaStack"); } }

Modifiez src/main/java/com.myorg/MyPipelineStack.java pour ajouter l'étape à notre pipeline.

package com.myorg; import java.util.Arrays; import software.constructs.Construct; import software.amazon.awscdk.Environment; import software.amazon.awscdk.Stack; import software.amazon.awscdk.StackProps; import software.amazon.awscdk.StageProps; import software.amazon.awscdk.pipelines.CodePipeline; import software.amazon.awscdk.pipelines.CodePipelineSource; import software.amazon.awscdk.pipelines.ShellStep; public class MyPipelineStack extends Stack { public MyPipelineStack(final Construct scope, final String id) { this(scope, id, null); } public MyPipelineStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); final CodePipeline pipeline = CodePipeline.Builder.create(this, "pipeline") .pipelineName("MyPipeline") .synth(ShellStep.Builder.create("Synth") .input(CodePipelineSource.gitHub("OWNER/REPO", "main")) .commands(Arrays.asList("npm install -g aws-cdk", "cdk synth")) .build()) .build(); pipeline.addStage(new MyPipelineAppStage(this, "test", StageProps.builder() .env(Environment.builder() .account("111111111111") .region("eu-west-1") .build()) .build())); } }
C#

Créez le nouveau fichier src/MyPipeline/MyPipelineLambdaStack.cs contenant notre pile d'applications contenant une fonction Lambda.

using Amazon.CDK; using Constructs; using Amazon.CDK.AWS.Lambda; namespace MyPipeline { class MyPipelineLambdaStack : Stack { public MyPipelineLambdaStack(Construct scope, string id, StackProps props=null) : base(scope, id, props) { new Function(this, "LambdaFunction", new FunctionProps { Runtime = Runtime.NODEJS_18_X, Handler = "index.handler", Code = new InlineCode("exports.handler = _ => 'Hello, CDK';") }); } } }

Créez le nouveau fichier src/MyPipeline/MyPipelineAppStage.cs pour héberger notre scène.

using Amazon.CDK; using Constructs; namespace MyPipeline { class MyPipelineAppStage : Stage { public MyPipelineAppStage(Construct scope, string id, StageProps props=null) : base(scope, id, props) { Stack lambdaStack = new MyPipelineLambdaStack(this, "LambdaStack"); } } }

Modifiez src/MyPipeline/MyPipelineStack.cs pour ajouter l'étape à notre pipeline.

using Amazon.CDK; using Constructs; using Amazon.CDK.Pipelines; namespace MyPipeline { public class MyPipelineStack : Stack { internal MyPipelineStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { var pipeline = new CodePipeline(this, "pipeline", new CodePipelineProps { PipelineName = "MyPipeline", Synth = new ShellStep("Synth", new ShellStepProps { Input = CodePipelineSource.GitHub("OWNER/REPO", "main"), Commands = new string[] { "npm install -g aws-cdk", "cdk synth" } }) }); pipeline.AddStage(new MyPipelineAppStage(this, "test", new StageProps { Env = new Environment { Account = "111111111111", Region = "eu-west-1" } })); } } }

Chaque étape d'application ajoutée par addStage() entraîne l'ajout d'une étape de pipeline correspondante, représentée par une StageDeploymentinstance renvoyée par l'addStage()appel. Vous pouvez ajouter des actions de pré-déploiement ou de post-déploiement à la phase en appelant sa méthode addPre() oraddPost().

TypeScript
// import { ManualApprovalStep } from 'aws-cdk-lib/pipelines'; const testingStage = pipeline.addStage(new MyPipelineAppStage(this, 'testing', { env: { account: '111111111111', region: 'eu-west-1' } })); testingStage.addPost(new ManualApprovalStep('approval'));
JavaScript
// const { ManualApprovalStep } = require('aws-cdk-lib/pipelines'); const testingStage = pipeline.addStage(new MyPipelineAppStage(this, 'testing', { env: { account: '111111111111', region: 'eu-west-1' } })); testingStage.addPost(new ManualApprovalStep('approval'));
Python
# from aws_cdk.pipelines import ManualApprovalStep testing_stage = pipeline.add_stage(MyPipelineAppStage(self, "testing", env=cdk.Environment(account="111111111111", region="eu-west-1"))) testing_stage.add_post(ManualApprovalStep('approval'))
Java
// import software.amazon.awscdk.pipelines.StageDeployment; // import software.amazon.awscdk.pipelines.ManualApprovalStep; StageDeployment testingStage = pipeline.addStage(new MyPipelineAppStage(this, "test", StageProps.builder() .env(Environment.builder() .account("111111111111") .region("eu-west-1") .build()) .build())); testingStage.addPost(new ManualApprovalStep("approval"));
C#
var testingStage = pipeline.AddStage(new MyPipelineAppStage(this, "test", new StageProps { Env = new Environment { Account = "111111111111", Region = "eu-west-1" } })); testingStage.AddPost(new ManualApprovalStep("approval"));

Vous pouvez ajouter des étapes à une Wave pour les déployer en parallèle, par exemple lorsque vous déployez une étape sur plusieurs comptes ou régions.

TypeScript
const wave = pipeline.addWave('wave'); wave.addStage(new MyApplicationStage(this, 'MyAppEU', { env: { account: '111111111111', region: 'eu-west-1' } })); wave.addStage(new MyApplicationStage(this, 'MyAppUS', { env: { account: '111111111111', region: 'us-west-1' } }));
JavaScript
const wave = pipeline.addWave('wave'); wave.addStage(new MyApplicationStage(this, 'MyAppEU', { env: { account: '111111111111', region: 'eu-west-1' } })); wave.addStage(new MyApplicationStage(this, 'MyAppUS', { env: { account: '111111111111', region: 'us-west-1' } }));
Python
wave = pipeline.add_wave("wave") wave.add_stage(MyApplicationStage(self, "MyAppEU", env=cdk.Environment(account="111111111111", region="eu-west-1"))) wave.add_stage(MyApplicationStage(self, "MyAppUS", env=cdk.Environment(account="111111111111", region="us-west-1")))
Java
// import software.amazon.awscdk.pipelines.Wave; final Wave wave = pipeline.addWave("wave"); wave.addStage(new MyPipelineAppStage(this, "MyAppEU", StageProps.builder() .env(Environment.builder() .account("111111111111") .region("eu-west-1") .build()) .build())); wave.addStage(new MyPipelineAppStage(this, "MyAppUS", StageProps.builder() .env(Environment.builder() .account("111111111111") .region("us-west-1") .build()) .build()));
C#
var wave = pipeline.AddWave("wave"); wave.AddStage(new MyPipelineAppStage(this, "MyAppEU", new StageProps { Env = new Environment { Account = "111111111111", Region = "eu-west-1" } })); wave.AddStage(new MyPipelineAppStage(this, "MyAppUS", new StageProps { Env = new Environment { Account = "111111111111", Region = "us-west-1" } }));

Tester les déploiements

Vous pouvez ajouter des étapes à un pipeline CDK pour valider les déploiements que vous effectuez. Par exemple, vous pouvez utiliser la bibliothèque CDK Pipeline ShellStep pour effectuer des tâches telles que les suivantes :

  • Essayer d'accéder à un Amazon API Gateway récemment déployé soutenu par une fonction Lambda

  • Vérification d'un paramètre d'une ressource déployée en émettant une AWS CLI commande

Dans sa forme la plus simple, l'ajout d'actions de validation ressemble à ceci :

TypeScript
// stage was returned by pipeline.addStage stage.addPost(new ShellStep("validate", { commands: ['../tests/validate.sh'], }));
JavaScript
// stage was returned by pipeline.addStage stage.addPost(new ShellStep("validate", { commands: ['../tests/validate.sh'], }));
Python
# stage was returned by pipeline.add_stage stage.add_post(ShellStep("validate", commands=[''../tests/validate.sh''] ))
Java
// stage was returned by pipeline.addStage stage.addPost(ShellStep.Builder.create("validate") .commands(Arrays.asList("'../tests/validate.sh'")) .build());
C#
// stage was returned by pipeline.addStage stage.AddPost(new ShellStep("validate", new ShellStepProps { Commands = new string[] { "'../tests/validate.sh'" } }));

De nombreux AWS CloudFormation déploiements entraînent la génération de ressources aux noms imprévisibles. De ce fait, les CDK Pipelines fournissent un moyen de AWS CloudFormation lire les sorties après un déploiement. Cela permet de transmettre (par exemple) l'URL générée d'un équilibreur de charge à une action de test.

Pour utiliser les sorties, exposez l'CfnOutputobjet qui vous intéresse. Transmettez-le ensuite dans la envFromCfnOutputs propriété d'une étape pour le rendre disponible en tant que variable d'environnement au sein de cette étape.

TypeScript
// given a stack lbStack that exposes a load balancer construct as loadBalancer this.loadBalancerAddress = new cdk.CfnOutput(lbStack, 'LbAddress', { value: `https://${lbStack.loadBalancer.loadBalancerDnsName}/` }); // pass the load balancer address to a shell step stage.addPost(new ShellStep("lbaddr", { envFromCfnOutputs: {lb_addr: lbStack.loadBalancerAddress}, commands: ['echo $lb_addr'] }));
JavaScript
// given a stack lbStack that exposes a load balancer construct as loadBalancer this.loadBalancerAddress = new cdk.CfnOutput(lbStack, 'LbAddress', { value: `https://${lbStack.loadBalancer.loadBalancerDnsName}/` }); // pass the load balancer address to a shell step stage.addPost(new ShellStep("lbaddr", { envFromCfnOutputs: {lb_addr: lbStack.loadBalancerAddress}, commands: ['echo $lb_addr'] }));
Python
# given a stack lb_stack that exposes a load balancer construct as load_balancer self.load_balancer_address = cdk.CfnOutput(lb_stack, "LbAddress", value=f"https://{lb_stack.load_balancer.load_balancer_dns_name}/") # pass the load balancer address to a shell step stage.add_post(ShellStep("lbaddr", env_from_cfn_outputs={"lb_addr": lb_stack.load_balancer_address} commands=["echo $lb_addr"]))
Java
// given a stack lbStack that exposes a load balancer construct as loadBalancer loadBalancerAddress = CfnOutput.Builder.create(lbStack, "LbAddress") .value(String.format("https://%s/", lbStack.loadBalancer.loadBalancerDnsName)) .build(); stage.addPost(ShellStep.Builder.create("lbaddr") .envFromCfnOutputs( // Map.of requires Java 9 or later java.util.Map.of("lbAddr", loadBalancerAddress)) .commands(Arrays.asList("echo $lbAddr")) .build());
C#
// given a stack lbStack that exposes a load balancer construct as loadBalancer loadBalancerAddress = new CfnOutput(lbStack, "LbAddress", new CfnOutputProps { Value = string.Format("https://{0}/", lbStack.loadBalancer.LoadBalancerDnsName) }); stage.AddPost(new ShellStep("lbaddr", new ShellStepProps { EnvFromCfnOutputs = new Dictionary<string, CfnOutput> { { "lbAddr", loadBalancerAddress } }, Commands = new string[] { "echo $lbAddr" } }));

Vous pouvez écrire des tests de validation simples directement dans leShellStep, mais cette approche devient peu pratique lorsque le test ne se limite pas à quelques lignes. Pour les tests plus complexes, vous pouvez intégrer des fichiers supplémentaires (tels que des scripts shell complets ou des programmes dans d'autres langages) dans la inputs propriété ShellStep via. Les entrées peuvent être n'importe quelle étape ayant une sortie, y compris une source (telle qu'un GitHub dépôt) ou une autreShellStep.

L'importation de fichiers depuis le dépôt source est appropriée si les fichiers sont directement utilisables dans le test (par exemple, s'ils sont eux-mêmes exécutables). Dans cet exemple, nous déclarons notre GitHub dépôt comme source (plutôt que de l'instancier en ligne dans le cadre du). CodePipeline Ensuite, nous transmettons ce jeu de fichiers au pipeline et au test de validation.

TypeScript
const source = CodePipelineSource.gitHub('OWNER/REPO', 'main'); const pipeline = new CodePipeline(this, 'Pipeline', { pipelineName: 'MyPipeline', synth: new ShellStep('Synth', { input: source, commands: ['npm ci', 'npm run build', 'npx cdk synth'] }) }); const stage = pipeline.addStage(new MyPipelineAppStage(this, 'test', { env: { account: '111111111111', region: 'eu-west-1' } })); stage.addPost(new ShellStep('validate', { input: source, commands: ['sh ../tests/validate.sh'] }));
JavaScript
const source = CodePipelineSource.gitHub('OWNER/REPO', 'main'); const pipeline = new CodePipeline(this, 'Pipeline', { pipelineName: 'MyPipeline', synth: new ShellStep('Synth', { input: source, commands: ['npm ci', 'npm run build', 'npx cdk synth'] }) }); const stage = pipeline.addStage(new MyPipelineAppStage(this, 'test', { env: { account: '111111111111', region: 'eu-west-1' } })); stage.addPost(new ShellStep('validate', { input: source, commands: ['sh ../tests/validate.sh'] }));
Python
source = CodePipelineSource.git_hub("OWNER/REPO", "main") pipeline = CodePipeline(self, "Pipeline", pipeline_name="MyPipeline", synth=ShellStep("Synth", input=source, commands=["npm install -g aws-cdk", "python -m pip install -r requirements.txt", "cdk synth"])) stage = pipeline.add_stage(MyApplicationStage(self, "test", env=cdk.Environment(account="111111111111", region="eu-west-1"))) stage.add_post(ShellStep("validate", input=source, commands=["sh ../tests/validate.sh"], ))
Java
final CodePipelineSource source = CodePipelineSource.gitHub("OWNER/REPO", "main"); final CodePipeline pipeline = CodePipeline.Builder.create(this, "pipeline") .pipelineName("MyPipeline") .synth(ShellStep.Builder.create("Synth") .input(source) .commands(Arrays.asList("npm install -g aws-cdk", "cdk synth")) .build()) .build(); final StageDeployment stage = pipeline.addStage(new MyPipelineAppStage(this, "test", StageProps.builder() .env(Environment.builder() .account("111111111111") .region("eu-west-1") .build()) .build())); stage.addPost(ShellStep.Builder.create("validate") .input(source) .commands(Arrays.asList("sh ../tests/validate.sh")) .build());
C#
var source = CodePipelineSource.GitHub("OWNER/REPO", "main"); var pipeline = new CodePipeline(this, "pipeline", new CodePipelineProps { PipelineName = "MyPipeline", Synth = new ShellStep("Synth", new ShellStepProps { Input = source, Commands = new string[] { "npm install -g aws-cdk", "cdk synth" } }) }); var stage = pipeline.AddStage(new MyPipelineAppStage(this, "test", new StageProps { Env = new Environment { Account = "111111111111", Region = "eu-west-1" } })); stage.AddPost(new ShellStep("validate", new ShellStepProps { Input = source, Commands = new string[] { "sh ../tests/validate.sh" } }));

L'obtention des fichiers supplémentaires à partir de l'étape de synthèse est appropriée si vos tests doivent être compilés, ce qui est effectué dans le cadre de la synthèse.

TypeScript
const synthStep = new ShellStep('Synth', { input: CodePipelineSource.gitHub('OWNER/REPO', 'main'), commands: ['npm ci', 'npm run build', 'npx cdk synth'], }); const pipeline = new CodePipeline(this, 'Pipeline', { pipelineName: 'MyPipeline', synth: synthStep }); const stage = pipeline.addStage(new MyPipelineAppStage(this, 'test', { env: { account: '111111111111', region: 'eu-west-1' } })); // run a script that was transpiled from TypeScript during synthesis stage.addPost(new ShellStep('validate', { input: synthStep, commands: ['node tests/validate.js'] }));
JavaScript
const synthStep = new ShellStep('Synth', { input: CodePipelineSource.gitHub('OWNER/REPO', 'main'), commands: ['npm ci', 'npm run build', 'npx cdk synth'], }); const pipeline = new CodePipeline(this, 'Pipeline', { pipelineName: 'MyPipeline', synth: synthStep }); const stage = pipeline.addStage(new MyPipelineAppStage(this, "test", { env: { account: "111111111111", region: "eu-west-1" } })); // run a script that was transpiled from TypeScript during synthesis stage.addPost(new ShellStep('validate', { input: synthStep, commands: ['node tests/validate.js'] }));
Python
synth_step = ShellStep("Synth", input=CodePipelineSource.git_hub("OWNER/REPO", "main"), commands=["npm install -g aws-cdk", "python -m pip install -r requirements.txt", "cdk synth"]) pipeline = CodePipeline(self, "Pipeline", pipeline_name="MyPipeline", synth=synth_step) stage = pipeline.add_stage(MyApplicationStage(self, "test", env=cdk.Environment(account="111111111111", region="eu-west-1"))) # run a script that was compiled during synthesis stage.add_post(ShellStep("validate", input=synth_step, commands=["node test/validate.js"], ))
Java
final ShellStep synth = ShellStep.Builder.create("Synth") .input(CodePipelineSource.gitHub("OWNER/REPO", "main")) .commands(Arrays.asList("npm install -g aws-cdk", "cdk synth")) .build(); final CodePipeline pipeline = CodePipeline.Builder.create(this, "pipeline") .pipelineName("MyPipeline") .synth(synth) .build(); final StageDeployment stage = pipeline.addStage(new MyPipelineAppStage(this, "test", StageProps.builder() .env(Environment.builder() .account("111111111111") .region("eu-west-1") .build()) .build())); stage.addPost(ShellStep.Builder.create("validate") .input(synth) .commands(Arrays.asList("node ./tests/validate.js")) .build());
C#
var synth = new ShellStep("Synth", new ShellStepProps { Input = CodePipelineSource.GitHub("OWNER/REPO", "main"), Commands = new string[] { "npm install -g aws-cdk", "cdk synth" } }); var pipeline = new CodePipeline(this, "pipeline", new CodePipelineProps { PipelineName = "MyPipeline", Synth = synth }); var stage = pipeline.AddStage(new MyPipelineAppStage(this, "test", new StageProps { Env = new Environment { Account = "111111111111", Region = "eu-west-1" } })); stage.AddPost(new ShellStep("validate", new ShellStepProps { Input = synth, Commands = new string[] { "node ./tests/validate.js" } }));

Remarque de sécurité

Toute forme de livraison continue comporte des risques de sécurité inhérents. Dans le cadre du modèle de responsabilité AWS partagée, vous êtes responsable de la sécurité de vos informations dans le AWS cloud. La bibliothèque CDK Pipelines vous donne une longueur d'avance en incorporant des valeurs par défaut sécurisées et les meilleures pratiques de modélisation.

Cependant, de par sa nature même, une bibliothèque qui a besoin d'un niveau d'accès élevé pour remplir son objectif ne peut pas garantir une sécurité complète. Il existe de nombreux vecteurs d'attaque extérieurs AWS à votre organisation.

Gardez en particulier à l'esprit les points suivants :

  • Faites attention aux logiciels dont vous dépendez. Vérifiez tous les logiciels tiers que vous utilisez dans votre pipeline, car ils peuvent modifier l'infrastructure déployée.

  • Utilisez le verrouillage des dépendances pour éviter les mises à niveau accidentelles. CDK Pipelines package-lock.json respecte yarn.lock et veille à ce que vos dépendances soient celles que vous attendez.

  • CDK Pipelines fonctionne sur des ressources créées dans votre propre compte, et la configuration de ces ressources est contrôlée par les développeurs qui soumettent du code via le pipeline. Par conséquent, CDK Pipelines ne peut à lui seul protéger contre les développeurs malveillants qui tentent de contourner les contrôles de conformité. Si votre modèle de menace inclut des développeurs écrivant du code CDK, vous devez disposer de mécanismes de conformité externes tels que AWS CloudFormation Hooks (préventif) ou AWS Config (réactif) que le rôle AWS CloudFormation d'exécution n'est pas autorisé à désactiver.

  • Les informations d'identification pour les environnements de production doivent être de courte durée. Après le démarrage et le provisionnement initial, les développeurs n'ont pas du tout besoin d'avoir des informations d'identification de compte. Les modifications peuvent être déployées via le pipeline. Réduisez le risque de fuite d'informations d'identification en n'en ayant pas besoin au départ.

Résolution des problèmes

Les problèmes suivants sont fréquemment rencontrés lors de la prise en main de CDK Pipelines.

Pipeline : défaillance interne
CREATE_FAILED  | AWS::CodePipeline::Pipeline | Pipeline/Pipeline
Internal Failure

Vérifiez votre jeton GitHub d'accès. Il est peut-être absent ou ne dispose pas des autorisations nécessaires pour accéder au référentiel.

Clé : la politique contient une déclaration contenant un ou plusieurs principes non valides
CREATE_FAILED | AWS::KMS::Key | Pipeline/Pipeline/ArtifactsBucketEncryptionKey
Policy contains a statement with one or more invalid principals.

L'un des environnements cibles n'a pas été amorcé avec la nouvelle pile d'amorçage. Assurez-vous que tous vos environnements cibles sont démarrés.

La pile est dans l'état ROLLBACK_COMPLETE et ne peut pas être mise à jour.
Stack STACK_NAME is in ROLLBACK_COMPLETE state and can not be updated. (Service:
AmazonCloudFormation; Status Code: 400; Error Code: ValidationError; Request
ID: ...)

La pile a échoué lors de son déploiement précédent et est dans un état non réessayable. Supprimez la pile de la AWS CloudFormation console et réessayez le déploiement.