

Ceci est le guide du développeur du AWS CDK v2. L'ancien CDK v1 est entré 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.

# Déployer des AWS applications CDK
<a name="deploy"></a>

Le déploiement d'un AWS Cloud Development Kit (AWS CDK) est le processus de mise en service de votre infrastructure. AWS

## Comment fonctionnent les déploiements AWS CDK
<a name="deploy-how"></a>

Le AWS CDK utilise le AWS CloudFormation service pour effectuer des déploiements. Avant de déployer, vous synthétisez vos piles de CDK. Cela crée un CloudFormation modèle et des artefacts de déploiement pour chaque pile de CDK de votre application. Les déploiements sont initiés à partir d'une machine de développement locale ou d'un *environnement d'intégration et de livraison continues (CI/CD*). Pendant le déploiement, les ressources sont téléchargées vers les ressources bootstrap et le CloudFormation modèle est soumis pour CloudFormation provisionner vos AWS ressources.

Pour qu'un déploiement soit réussi, les éléments suivants sont requis :
+ L'interface de ligne de commande AWS CDK (AWS CDK CLI) doit être dotée d'autorisations valides.
+ L' AWS environnement doit être amorcé.
+ Le AWS CDK doit connaître les ressources d'amorçage dans lesquelles télécharger les actifs.

## Conditions préalables pour les déploiements de CDK
<a name="deploy-prerequisites"></a>

Avant de déployer une application AWS CDK, vous devez effectuer les opérations suivantes :
+ Configurez les informations d'identification de sécurité pour la CLI CDK.
+ Bootstrap votre AWS environnement.
+ Configurez un AWS environnement pour chacune de vos piles de CDK.
+ Développez votre application CDK.<a name="deploy-prerequisites-creds"></a>

 **Configuration des informations d'identification de sécurité**   
Pour utiliser la CLI CDK pour interagir avec AWS, vous devez configurer les informations d'identification de sécurité sur votre machine locale. Pour obtenir des instructions, voir [Configurer les informations d'identification de sécurité pour la CLI AWS CDK](configure-access.md).<a name="deploy-prerequisites-bootstrap"></a>

 **Bootstrap votre environnement AWS **   
Un déploiement est toujours associé à un ou plusieurs AWS [environnements](environments.md). Avant de procéder au déploiement, l'environnement doit d'abord être [amorcé.](bootstrapping.md) Le bootstrap fournit les ressources de votre environnement que le CDK utilise pour effectuer et gérer les déploiements. [Ces ressources incluent un bucket Amazon Simple Storage Service (Amazon S3) et un référentiel Amazon Elastic Container Registry (Amazon ECR) pour stocker et gérer les actifs.](assets.md) Ces ressources incluent également les rôles AWS Identity and Access Management (IAM) utilisés pour fournir des autorisations lors du développement et du déploiement.  
Nous vous recommandons d'utiliser la commande AWS CDK Command Line Interface (AWS CDK CLI) `cdk bootstrap` pour démarrer votre environnement. Vous pouvez personnaliser le bootstrap ou créer manuellement ces ressources dans votre environnement si nécessaire. Pour obtenir des instructions, consultez [Bootstrap votre environnement pour l'utiliser avec le AWS CDK](bootstrapping-env.md).<a name="deploy-prerequisites-env"></a>

 **Configuration AWS des environnements**   
Chaque pile CDK doit être associée à un environnement pour déterminer où la pile est déployée. Pour obtenir des instructions, voir [Configurer les environnements à utiliser avec le AWS CDK.](configure-env.md)<a name="deploy-prerequisites-develop"></a>

 **Développez votre application CDK**   
Dans le cadre d'un [projet](projects.md) CDK, vous créez et développez votre application CDK. [Dans votre application, vous créez une ou plusieurs piles de CDK.](stacks.md) Dans vos piles, vous importez et utilisez [des constructions](constructs.md) de la bibliothèque de AWS constructions pour définir votre infrastructure. Avant de pouvoir être déployée, votre application CDK doit contenir au moins une pile.

## Synthèse de l'application CDK
<a name="deploy-how-synth"></a>

Pour effectuer la synthèse, nous vous recommandons d'utiliser la `cdk synth` commande CDK CLI. La `cdk deploy` commande effectuera également une synthèse avant de lancer le déploiement. Cependant, en utilisant`cdk synth`, vous pouvez valider votre application CDK et détecter les erreurs avant de lancer le déploiement.

Le comportement de synthèse est déterminé par le [synthétiseur de pile](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib-readme.html#stack-synthesizers) que vous configurez pour votre pile CDK. Si vous ne configurez pas de synthétiseur, il ` [DefaultStackSynthesizer](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.DefaultStackSynthesizer.html) ` sera utilisé. Vous pouvez également configurer et personnaliser la synthèse en fonction de vos besoins. Pour obtenir des instructions, voir [Configuration et exécution de la synthèse de piles CDK](configure-synth.md).

Pour que votre CloudFormation modèle synthétisé soit déployé avec succès dans votre environnement, il doit être compatible avec la façon dont votre environnement a été amorcé. Par exemple, votre CloudFormation modèle doit spécifier le compartiment Amazon S3 approprié dans lequel déployer les actifs. Si vous utilisez la méthode par défaut pour amorcer votre environnement, le synthétiseur de pile par défaut fonctionnera. Si vous personnalisez le comportement du CDK, comme la personnalisation du démarrage ou de la synthèse, le comportement de déploiement du CDK peut varier.<a name="deploy-how-synth-app"></a>

 **Le cycle de vie des applications**   
Lorsque vous effectuez une synthèse, votre application CDK passe par les phases suivantes, appelées *cycle de vie de l'application* :    
 **Construction (ou initialisation)**   
Votre code instancie toutes les constructions définies, puis les lie entre elles. À ce stade, toutes les constructions (app, stacks et leurs constructions dérivées) sont instanciées et la chaîne de constructeurs est exécutée. La majeure partie du code de votre application est exécutée au cours de cette étape.  
 **Préparation**   
Toutes les constructions qui ont implémenté la `prepare` méthode participent à une dernière série de modifications afin de définir leur état final. La phase de préparation se déroule automatiquement. En tant qu'utilisateur, vous ne recevez aucun commentaire concernant cette phase. Il est rare d'avoir besoin d'utiliser le crochet « Prepare », et ce n'est généralement pas recommandé. Soyez très prudent lorsque vous mutez l'arbre de construction au cours de cette phase, car l'ordre des opérations peut avoir un impact sur le comportement.  
Au cours de cette phase, une fois que l'arbre de construction a été créé, tous [les aspects](aspects.md) que vous avez configurés sont également appliqués.  
 **Validation**   
Toutes les constructions qui ont implémenté la `validate` méthode peuvent se valider pour s'assurer qu'elles sont dans un état permettant un déploiement correct. Vous serez informé de tout échec de validation survenant au cours de cette phase. En général, nous recommandons d'effectuer la validation dès que possible (généralement dès que vous recevez des informations) et de lancer des exceptions le plus tôt possible. La validation précoce améliore la fiabilité, car les traces de pile seront plus précises et garantiront que votre code peut continuer à s'exécuter en toute sécurité.  
 **Synthèse**   
Il s'agit de la dernière étape de l'exécution de votre application CDK. Il est déclenché par un appel à`app.synth()`, traverse l'arbre de construction et invoque la `synthesize` méthode sur toutes les constructions. Les constructions mises en œuvre `synthesize` peuvent participer à la synthèse et produire des artefacts de déploiement pour l'assemblage cloud qui en résulte. Ces artefacts incluent des CloudFormation modèles, des ensembles d'applications AWS Lambda, des fichiers et des images Docker, ainsi que d'autres artefacts de déploiement. Dans la plupart des cas, il n'est pas nécessaire d'implémenter la `synthesize` méthode.<a name="deploy-how-synth-run"></a>

 **Exécution de votre application**   
La CLI CDK doit savoir comment exécuter votre application CDK. Si vous avez créé le projet à partir d'un modèle à l'aide de la `cdk init` commande, le `cdk.json` fichier de votre application inclut une `app` clé. Cette clé indique la commande nécessaire pour la langue dans laquelle l'application est écrite. Si votre langue nécessite une compilation, la ligne de commande exécute cette étape avant d'exécuter automatiquement l'application.  

**Example**  

```
{
  "app": "npx ts-node --prefer-ts-exts bin/my-app.ts"
}
```

```
{
  "app": "node bin/my-app.js"
}
```

```
{
    "app": "python app.py"
}
```

```
{
  "app": "mvn -e -q compile exec:java"
}
```

```
{
  "app": "dotnet run -p src/MyApp/MyApp.csproj"
}
```

```
{
  "app": "go mod download && go run my-app.go"
}
```
Si vous n'avez pas créé votre projet à l'aide de la CLI CDK, ou si vous souhaitez remplacer la ligne de commande indiquée`cdk.json`, vous pouvez fournir ` --app ` cette option lors de l'exécution de la `cdk` commande.

```
$ cdk --app '<executable>' <cdk-command> ...
```

La `<executable>` partie de la commande indique la commande qui doit être exécutée pour exécuter votre application CDK. Utilisez les guillemets comme indiqué, car ces commandes contiennent des espaces. `<cdk-command>`Il s'agit d'une sous-commande similaire à `synth` ou `deploy` qui indique à la CLI CDK ce que vous voulez faire avec votre application. Suivez cette procédure avec toutes les options supplémentaires nécessaires pour cette sous-commande.

La CLI CDK peut également interagir directement avec un assemblage cloud déjà synthétisé. Pour ce faire, transmettez le répertoire dans lequel l'assemblage cloud est stocké`--app`. L'exemple suivant répertorie les piles définies dans l'assemblage cloud stocké sous`./my-cloud-assembly`.

```
$ cdk --app <./my-cloud-assembly> ls
```<a name="deploy-how-synth-assemblies"></a>

 **Assemblages cloud**   
L'appel à `app.synth()` indique au AWS CDK de synthétiser un assemblage cloud à partir d'une application. En général, vous n'interagissez pas directement avec les assemblages cloud. Il s'agit de fichiers contenant tout ce dont vous avez besoin pour déployer votre application dans un environnement cloud. Par exemple, il inclut un AWS CloudFormation modèle pour chaque pile de votre application. Il inclut également une copie de tous les fichiers ou images Docker auxquels vous faites référence dans votre application.  
Consultez la [spécification des assemblages cloud](https://github.com/aws/aws-cdk/blob/master/design/cloud-assembly.md) pour plus de détails sur le formatage des assemblages cloud.  
Pour interagir avec l'assemblage cloud créé par votre application AWS CDK, vous utilisez généralement la AWS CLI CDK. Cependant, tout outil capable de lire le format d'assemblage du cloud peut être utilisé pour déployer votre application.

## Déploiement de votre application
<a name="deploy-how-deploy"></a>

Pour déployer votre application, nous vous recommandons d'utiliser la `cdk deploy` commande CDK CLI pour lancer des déploiements ou pour configurer des déploiements automatisés.

Lorsque vous exécutez`cdk deploy`, la CLI CDK démarre pour `cdk synth` préparer le déploiement. Le schéma suivant illustre le cycle de vie de l'application dans le contexte d'un déploiement :

![\[Organigramme du cycle de vie de l'application <shared id="AWS"/> CDK.\]](http://docs.aws.amazon.com/fr_fr/cdk/v2/guide/images/app-lifecycle_cdk-flowchart.png)


Lors du déploiement, la CLI CDK prend l'assemblage cloud produit par synthèse et le déploie dans un AWS environnement. Les actifs sont chargés sur Amazon S3 et Amazon ECR et le CloudFormation modèle est soumis à des AWS CloudFormation fins de déploiement.

Au début de la phase de AWS CloudFormation déploiement, votre application CDK est déjà terminée et s'est terminée. Cela a les conséquences suivantes :
+ L'application CDK ne peut pas répondre aux événements qui se produisent pendant le déploiement, tels que la création d'une ressource ou la fin complète du déploiement. Pour exécuter du code pendant la phase de déploiement, vous devez l'injecter dans le AWS CloudFormation modèle en tant que [ressource personnalisée](cfn-layer.md#develop-customize-custom). Pour plus d'informations sur l'ajout d'une ressource personnalisée à votre application, consultez le [AWS CloudFormation module](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_cloudformation-readme.html) ou l'exemple de [ressource personnalisée](https://github.com/aws-samples/aws-cdk-examples/tree/master/typescript/custom-resource/). Vous pouvez également configurer le module [Triggers](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.triggers-readme.html) pour exécuter du code lors des déploiements.
+ L'application CDK devra peut-être fonctionner avec des valeurs qui ne peuvent pas être connues au moment de son exécution. Par exemple, si l'application AWS CDK définit un compartiment Amazon S3 avec un nom généré automatiquement et que vous récupérez l'attribut `bucket.bucketName` (Python :`bucket_name`), cette valeur n'est pas le nom du compartiment déployé. Au lieu de cela, vous obtenez une `Token` valeur. Pour déterminer si une valeur particulière est disponible, appelez `cdk.isUnresolved(value)` (Python :`is_unresolved`). Voir [Tokens et AWS CDK](tokens.md) pour plus de détails.<a name="deploy-how-deploy-permissions"></a>

 **Autorisations de déploiement**   
Avant que le déploiement puisse être effectué, les autorisations doivent être établies. Le schéma suivant illustre les autorisations utilisées lors d'un déploiement par défaut, lors de l'utilisation du processus d'amorçage par défaut et du synthétiseur de pile :  

![\[Organigramme du processus de déploiement du <shared id="AWS"/> CDK par défaut.\]](http://docs.aws.amazon.com/fr_fr/cdk/v2/guide/images/default-deploy-process_cdk_flowchart.png)
  
 **L'acteur lance le déploiement**   
Les déploiements sont initiés par un *acteur* à l'aide de la CLI CDK. Un acteur peut être soit une personne, soit un service tel que AWS CodePipeline.  
Si nécessaire, la CLI CDK s'exécute `cdk synth` lorsque vous exécutez`cdk deploy`. Lors de la synthèse, l' AWS identité suppose `LookupRole` d'effectuer des recherches de contexte dans l' AWS environnement.  
 **Les autorisations sont établies**   
Tout d'abord, les informations de sécurité de l'acteur sont utilisées pour s'authentifier AWS et obtenir la première identité IAM du processus. Pour les acteurs humains, la manière dont les informations d'identification de sécurité sont configurées et obtenues dépend de la façon dont vous ou votre organisation gérez les utilisateurs. Pour plus d'informations, consultez [Configurer les informations d'identification de sécurité pour la CLI AWS CDK](configure-access.md). Pour les acteurs du service, par exemple CodePipeline, un rôle d'exécution IAM est assumé et utilisé.  
Ensuite, les rôles IAM créés dans votre AWS environnement lors du démarrage sont utilisés pour établir des autorisations permettant d'effectuer les actions nécessaires au déploiement. Pour plus d'informations sur ces rôles et les raisons pour lesquelles ils accordent des autorisations, consultez la section [Rôles IAM créés lors du démarrage](bootstrapping-env.md#bootstrapping-env-roles). Ce processus inclut les éléments suivants :  
+ L' AWS identité assume le `DeploymentActionRole` rôle et le `CloudFormationExecutionRole` transmet CloudFormation, en veillant à ce qu'elle CloudFormation assume le rôle lorsqu'elle exécute des actions dans votre AWS environnement. `DeploymentActionRole`accorde l'autorisation d'effectuer des déploiements dans votre environnement et `CloudFormationExecutionRole` détermine les actions CloudFormation pouvant être effectuées.
+ L' AWS identité suppose le`FilePublishingRole`, qui détermine les actions qui peuvent être effectuées sur le compartiment Amazon S3 créé lors du démarrage.
+ L' AWS identité suppose le`ImagePublishingRole`, qui détermine les actions qui peuvent être effectuées sur le référentiel Amazon ECR créé lors du démarrage.
+ Si nécessaire, l' AWS identité suppose d'`LookupRole`effectuer des recherches contextuelles dans l' AWS environnement. Cette action peut également être effectuée lors de la synthèse du modèle.  
 **Le déploiement est effectué**   
Pendant le déploiement, la CLI CDK lit le paramètre de version du bootstrap pour confirmer le numéro de version du bootstrap. AWS CloudFormation lit également ce paramètre au moment du déploiement pour le confirmer. Si les autorisations dans l'ensemble du flux de travail de déploiement sont valides, le déploiement est effectué. Les ressources sont téléchargées vers les ressources bootstrap et le CloudFormation modèle produit lors de la synthèse est déployé en utilisant le CloudFormation service en tant que CloudFormation pile pour provisionner vos ressources.

# AWS Validation de la politique CDK au moment de la synthèse
<a name="policy-validation-synthesis"></a>

## Validation des politiques au moment de la synthèse
<a name="policy-validation"></a>

Si vous ou votre organisation utilisez un outil de validation des politiques, tel que [AWS CloudFormation Guard](https://docs.aws.amazon.com/cfn-guard/latest/ug/what-is-guard.html) ou [OPA](https://www.openpolicyagent.org/), pour définir des contraintes sur votre AWS CloudFormation modèle, vous pouvez les intégrer au AWS CDK au moment de la synthèse. En utilisant le plugin de validation des politiques approprié, vous pouvez faire en sorte que l'application AWS CDK vérifie le AWS CloudFormation modèle généré par rapport à vos politiques immédiatement après la synthèse. En cas de violation, la synthèse échouera et un rapport sera imprimé sur la console.

La validation effectuée par le AWS CDK au moment de la synthèse valide les contrôles à un moment donné du cycle de vie du déploiement, mais elle ne peut pas affecter les actions qui se produisent en dehors de la synthèse. Les exemples incluent les actions effectuées directement dans la console ou via le service APIs. Ils ne résistent pas à l'altération des AWS CloudFormation modèles après la synthèse. Un autre mécanisme permettant de valider le même ensemble de règles de manière plus fiable doit être configuré indépendamment, comme les [AWS CloudFormation hooks](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/hooks.html) ou [AWS Config](https://docs.aws.amazon.com/config/latest/developerguide/WhatIsConfig.html). Néanmoins, la capacité du AWS CDK à évaluer l'ensemble de règles pendant le développement est toujours utile car elle améliorera la vitesse de détection et la productivité des développeurs.

L'objectif de la validation des politiques AWS CDK est de minimiser le nombre de configurations nécessaires au cours du développement et de le rendre aussi simple que possible.

**Note**  
Cette fonctionnalité est considérée comme expérimentale, et l'API du plugin et le format du rapport de validation sont susceptibles d'être modifiés à l'avenir.

## Pour les développeurs d'applications
<a name="for-application-developers"></a>

Pour utiliser un ou plusieurs plugins de validation dans votre application, utilisez la `policyValidationBeta1` propriété suivante `Stage` :

```
import { CfnGuardValidator } from '@cdklabs/cdk-validator-cfnguard';
const app = new App({
  policyValidationBeta1: [
    new CfnGuardValidator()
  ],
});
// only apply to a particular stage
const prodStage = new Stage(app, 'ProdStage', {
  policyValidationBeta1: [...],
});
```

Immédiatement après la synthèse, tous les plugins enregistrés de cette manière seront invoqués pour valider tous les modèles générés dans le champ que vous avez défini. En particulier, si vous enregistrez les modèles dans l'`App`objet, tous les modèles seront soumis à validation.

**Avertissement**  
Outre la modification de l'assemblage du cloud, les plugins peuvent faire tout ce que peut faire votre application AWS CDK. Ils peuvent lire les données du système de fichiers, accéder au réseau, etc. En tant que consommateur d'un plugin, il est de votre responsabilité de vérifier que son utilisation est sûre.

### AWS CloudFormation Plug-in Guard
<a name="cfnguard-plugin"></a>

L'utilisation du [https://github.com/cdklabs/cdk-validator-cfnguard](https://github.com/cdklabs/cdk-validator-cfnguard)plugin vous permet d'utiliser [AWS CloudFormation Guard](https://github.com/aws-cloudformation/cloudformation-guard) pour effectuer des validations de politiques. Le `CfnGuardValidator` plugin est livré avec un ensemble sélectionné de [AWS contrôles proactifs intégrés de la Control Tower](https://docs.aws.amazon.com/controltower/latest/userguide/proactive-controls.html). L'ensemble de règles actuel se trouve dans la [documentation du projet](https://github.com/cdklabs/cdk-validator-cfnguard/blob/main/README.md). Comme indiqué dans la section [Validation des politiques au moment de la synthèse](#policy-validation), nous recommandons aux organisations de mettre en place une méthode de validation plus fiable à l'aide de [AWS CloudFormation crochets.](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/hooks.html)

Pour les clients [AWS de Control Tower](https://docs.aws.amazon.com/controltower/latest/userguide/what-is-control-tower.html), ces mêmes contrôles proactifs peuvent être déployés dans l'ensemble de leur organisation. Lorsque vous activez AWS les contrôles proactifs de la AWS Control Tower dans votre environnement Control Tower, les contrôles peuvent arrêter le déploiement de ressources non conformes déployées via AWS CloudFormation. Pour plus d'informations sur les contrôles proactifs gérés et leur fonctionnement, consultez la [documentation AWS de Control Tower](https://docs.aws.amazon.com/controltower/latest/userguide/proactive-controls.html).

Il est préférable d'utiliser ensemble ces contrôles fournis par AWS CDK et ces contrôles proactifs gérés par AWS Control Tower. Dans ce scénario, vous pouvez configurer ce plugin de validation avec les mêmes contrôles proactifs que ceux actifs dans votre environnement cloud AWS Control Tower. Vous pouvez alors rapidement être sûr que votre application AWS CDK passera les commandes de la AWS Control Tower en s'exécutant `cdk synth` localement.

### Rapport de validation
<a name="validation-report"></a>

Lorsque vous synthétiserez l'application AWS CDK, les plugins de validation seront appelés et les résultats seront imprimés. Un exemple de rapport est présenté ci-dessous.

```
Validation Report (CfnGuardValidator)
-------------------------------------
(Summary)
╔═══════════╤════════════════════════╗
║ Status    │ failure                ║
╟───────────┼────────────────────────╢
║ Plugin    │ CfnGuardValidator      ║
╚═══════════╧════════════════════════╝
(Violations)
Ensure S3 Buckets are encrypted with a KMS CMK (1 occurrences)
Severity: medium
  Occurrences:

    - Construct Path: MyStack/MyCustomL3Construct/Bucket
    - Stack Template Path: ./cdk.out/MyStack.template.json
    - Creation Stack:
        └──  MyStack (MyStack)
             │ Library: aws-cdk-lib.Stack
             │ Library Version: 2.50.0
             │ Location: Object.<anonymous> (/home/johndoe/tmp/cdk-tmp-app/src/main.ts:25:20)
             └──  MyCustomL3Construct (MyStack/MyCustomL3Construct)
                  │ Library: N/A - (Local Construct)
                  │ Library Version: N/A
                  │ Location: new MyStack (/home/johndoe/tmp/cdk-tmp-app/src/main.ts:15:20)
                  └──  Bucket (MyStack/MyCustomL3Construct/Bucket)
                       │ Library: aws-cdk-lib/aws-s3.Bucket
                       │ Library Version: 2.50.0
                       │ Location: new MyCustomL3Construct (/home/johndoe/tmp/cdk-tmp-app/src/main.ts:9:20)
    - Resource Name: amzn-s3-demo-bucket
    - Locations:
      > BucketEncryption/ServerSideEncryptionConfiguration/0/ServerSideEncryptionByDefault/SSEAlgorithm
  Recommendation: Missing value for key `SSEAlgorithm` - must specify `aws:kms`
  How to fix:
    > Add to construct properties for `cdk-app/MyStack/Bucket`
      `encryption: BucketEncryption.KMS`

Validation failed. See above reports for details
```

Par défaut, le rapport sera imprimé dans un format lisible par l'homme. Si vous souhaitez un rapport au format JSON, activez-le `@aws-cdk/core:validationReportJson` via la CLI ou transmettez-le directement à l'application :

```
const app = new App({
  context: { '@aws-cdk/core:validationReportJson': true },
});
```

Vous pouvez également définir cette paire clé-valeur de contexte à l'aide des `cdk.context.json` fichiers `cdk.json` or du répertoire de votre projet (voir [Valeurs de contexte et AWS CDK](context.md)).

Si vous choisissez le format JSON, le AWS CDK imprimera le rapport de validation des politiques dans un fichier appelé `policy-validation-report.json` dans le répertoire d'assemblage du cloud. Pour le format par défaut lisible par l'homme, le rapport sera imprimé sur la sortie standard.

## Pour les auteurs de plugins
<a name="plugin-authors"></a>

### Plugins
<a name="plugins"></a>

Le framework principal du AWS CDK est chargé d'enregistrer et d'appeler les plugins, puis d'afficher le rapport de validation formaté. La responsabilité du plugin est d'agir en tant que couche de traduction entre le framework AWS CDK et l'outil de validation des politiques. Un plugin peut être créé dans n'importe quelle langue prise en charge par AWS CDK. Si vous créez un plugin susceptible d'être utilisé par plusieurs langues, il est recommandé de le créer `TypeScript` afin de pouvoir utiliser JSII pour le publier dans chaque langue du AWS CDK.

### Création de plugins
<a name="creating-plugins"></a>

Le protocole de communication entre le module principal du AWS CDK et votre outil de politique est défini par l'`IPolicyValidationPluginBeta1`interface. Pour créer un nouveau plugin, vous devez écrire une classe qui implémente cette interface. Il y a deux choses que vous devez implémenter : le nom du plugin (en remplaçant la `name` propriété) et la `validate()` méthode.

Le framework appellera `validate()` en passant un `IValidationContextBeta1` objet. L'emplacement des modèles à valider est indiqué par`templatePaths`. Le plugin doit renvoyer une instance de`ValidationPluginReportBeta1`. Cet objet représente le rapport que l'utilisateur recevra à la fin de la synthèse.

```
validate(context: IPolicyValidationContextBeta1): PolicyValidationReportBeta1 {
  // First read the templates using context.templatePaths...
  // ...then perform the validation, and then compose and return the report.
  // Using hard-coded values here for better clarity:
  return {
    success: false,
    violations: [{
      ruleName: 'CKV_AWS_117',
      description: 'Ensure that AWS Lambda function is configured inside a VPC',
      fix: 'https://docs.bridgecrew.io/docs/ensure-that-aws-lambda-function-is-configured-inside-a-vpc-1',
      violatingResources: [{
        resourceName: 'MyFunction3BAA72D1',
        templatePath: '/home/johndoe/myapp/cdk.out/MyService.template.json',
        locations: 'Properties/VpcConfig',
      }],
    }],
  };
}
```

Notez que les plugins ne sont pas autorisés à modifier quoi que ce soit dans l'assemblage du cloud. Toute tentative en ce sens entraînera l'échec de la synthèse.

Si votre plugin dépend d'un outil externe, n'oubliez pas que certains développeurs n'ont peut-être pas encore installé cet outil sur leur poste de travail. Pour minimiser les frictions, nous vous recommandons vivement de fournir un script d'installation avec votre package de plugin, afin d'automatiser l'ensemble du processus. Mieux encore, exécutez ce script dans le cadre de l'installation de votre package. Avec`npm`, par exemple, vous pouvez l'ajouter au `postinstall` [script](https://docs.npmjs.com/cli/v9/using-npm/scripts) du `package.json` fichier.

### Gestion des exemptions
<a name="handling-exemptions"></a>

Si votre organisation dispose d'un mécanisme de gestion des exemptions, celui-ci peut être mis en œuvre dans le cadre du plug-in de validation.

Exemple de scénario illustrant un éventuel mécanisme d'exemption :
+ Une organisation applique une règle selon laquelle les compartiments publics Amazon S3 ne sont pas autorisés, *sauf* dans certains cas.
+ Un développeur crée un compartiment Amazon S3 correspondant à l'un de ces scénarios et demande une exemption (création d'un ticket par exemple).
+ Les outils de sécurité savent lire à partir du système interne qui enregistre les exemptions

Dans ce scénario, le développeur demanderait une exception dans le système interne, puis aurait besoin d'un moyen « d'enregistrer » cette exception. Pour compléter l'exemple du plugin Guard, vous pouvez créer un plugin qui gère les exemptions en filtrant les violations associées à une exemption correspondante dans un système de billetterie interne.

Consultez les plugins existants pour des exemples d'implémentations.
+  [@cdklabs/cdk-validator-cfnguard](https://github.com/cdklabs/cdk-validator-cfnguard) 

# Intégration et livraison continues (CI/CD) à l'aide de CDK Pipelines
<a name="cdk-pipeline"></a>

Utilisez le module [CDK](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.pipelines-readme.html) Pipelines de AWS la bibliothèque Construct pour configurer la livraison continue AWS des applications CDK. Lorsque vous validez le code source de votre application CDK dans AWS CodeCommit GitHub 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 en prend en charge deux APIs. 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 solutions prises en charge APIs, consultez l'API [originale de CDK Pipelines](https://github.com/aws/aws-cdk/blob/master/packages/@aws-cdk/pipelines/ORIGINAL_API.md) dans *le référentiel GitHub aws-cdk*.

## Bootstrap vos environnements AWS
<a name="cdk-pipeline-bootstrap"></a>

Avant de pouvoir utiliser CDK Pipelines, vous devez démarrer AWS [l'environnement dans](environments.md) 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 bootstrapping](bootstrapping.md) pour plus d'informations sur les types de ressources créées par le bootstrap et sur la façon de personnaliser la pile de 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 pipeline AWS CDK, invoquez-le `cdk bootstrap` comme indiqué dans l'exemple suivant. L'appel du kit d'outils AWS CDK 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-policies`spé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 application AWS CDK.

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 et la AWS région nécessaires.

**Example**  

```
npx cdk bootstrap aws://<ACCOUNT-NUMBER>/<REGION> --profile <ADMIN-PROFILE> \
    --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess
```

```
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 les applications AWS CDK seront déployées par le pipeline, utilisez plutôt les commandes suivantes. L'`--trust`option indique quel autre compte doit être autorisé à déployer des applications AWS CDK 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 et la AWS région nécessaires.

**Example**  

```
npx cdk bootstrap aws://<ACCOUNT-NUMBER>/<REGION> --profile <ADMIN-PROFILE> \
    --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess \
    --trust <PIPELINE-ACCOUNT-NUMBER>
```

```
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
<a name="cdk-pipeline-protect"></a>

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-protection`option 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 AWS CLI ou CloudFormation la console pour vérifier.

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
   ```

1. Utilisez la AWS CLI ou CloudFormation la console pour vérifier. Voici un exemple d'utilisation de la 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
<a name="cdk-pipeline-init"></a>

Créez un nouveau GitHub projet vide et clonez-le sur votre poste de travail dans le `my-pipeline` répertoire. (Nos 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 kit d'outils AWS CDK 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.

**Example**  

```
$ cdk init app --language typescript
```

```
$ cdk init app --language javascript
```

```
$ 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 principales du AWS CDK.  

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

```
$ 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).

```
$ cdk init app --language csharp
```
Si vous utilisez Visual Studio, ouvrez le fichier de solution dans le `src` répertoire.

```
$ 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 la section [Valeurs de contexte et AWS CDK.](context.md)

## Définition d'un pipeline
<a name="cdk-pipeline-define"></a>

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 ` [CodePipeline](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.pipelines.CodePipeline.html) ` est 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 nom`github-token`.

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

**Example**  
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();
```
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();
```
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()
```
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();
    }
}
```
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();
        }
    }
}
```

```
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
<a name="cdk-pipeline-stages"></a>

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](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stage.html) ` (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 appelant`stack1.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()](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.pipelines.CodePipeline.html#addwbrstagestage-optionss) ` avec des instances de [Stage](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stage.html). 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.

**Example**  
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" }
    }));
  }
}
```
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 }
```
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")))
```
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()));
    }
}
```
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 ` [StageDeployment](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.pipelines.StageDeployment.html) ` instance renvoyée par l'`addStage()`appel. Vous pouvez ajouter des actions avant ou après le déploiement à la phase en appelant sa méthode `addPre()` or`addPost()`.

**Example**  

```
// 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'));
```

```
// 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'));
```

```
# 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'))
```

```
// 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"));
```

```
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 à un ` [Wave](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.pipelines.Wave.html) ` pour les déployer en parallèle, par exemple lorsque vous déployez une étape sur plusieurs comptes ou régions.

**Example**  

```
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' }
}));
```

```
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' }
}));
```

```
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")))
```

```
// 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()));
```

```
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
<a name="cdk-pipeline-validation"></a>

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](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.pipelines.ShellStep.html) ` 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 commande AWS CLI

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

**Example**  

```
// stage was returned by pipeline.addStage

stage.addPost(new ShellStep("validate", {
  commands: ['../tests/validate.sh'],
}));
```

```
// stage was returned by pipeline.addStage

stage.addPost(new ShellStep("validate", {
  commands: ['../tests/validate.sh'],
}));
```

```
# stage was returned by pipeline.add_stage

stage.add_post(ShellStep("validate",
  commands=[''../tests/validate.sh'']
))
```

```
// stage was returned by pipeline.addStage

stage.addPost(ShellStep.Builder.create("validate")
        .commands(Arrays.asList("'../tests/validate.sh'"))
        .build());
```

```
// 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'`CfnOutput`objet 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.

**Example**  

```
// 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']
}));
```

```
// 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']
}));
```

```
# 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"]))
```

```
// 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());
```

```
// 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 le`ShellStep`, 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 autre`ShellStep`.

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.

**Example**  

```
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']
}));
```

```
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']
}));
```

```
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"],
))
```

```
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());
```

```
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.

**Example**  

```
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']
}));
```

```
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']
}));
```

```
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"],
))
```

```
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());
```

```
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é
<a name="cdk-pipeline-security"></a>

Toute forme de livraison continue comporte des risques de sécurité inhérents. Dans le cadre du [modèle de responsabilité AWS partagée](https://aws.amazon.com/compliance/shared-responsibility-model/), 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](https://aws.amazon.com/blogs/mt/proactively-keep-resources-secure-and-compliant-with-aws-cloudformation-hooks/) (préventif) ou [AWS Config](https://aws.amazon.com/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
<a name="cdk-pipeline-troubleshooting"></a>

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\$1COMPLETE et ne peut pas être mise à jour**   

```
Stack <STACK_NAME> is in ROLLBACK_COMPLETE state and cannot 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.

# Créez et déployez des ressources d'images de conteneurs dans les applications CDK
<a name="build-containers"></a>

Lorsque vous créez des actifs d'image de conteneur avec le AWS Cloud Development Kit (AWS CDK), Docker est utilisé par défaut pour effectuer ces actions. Si vous souhaitez utiliser un autre outil de gestion de conteneurs, vous pouvez remplacer Docker via la variable d'`CDK_DOCKER`environnement.

## Exemple : création et publication d'une ressource d'image de conteneur avec le AWS CDK
<a name="build-containers-intro-example"></a>

Voici un exemple simple d'application AWS CDK qui crée et publie un actif de conteneur sur Amazon Elastic Container Registry (Amazon ECR) en utilisant Docker par défaut :

 **Structure du projet**   

```
my-cdk-app/
├── lib/
│   ├── my-stack.ts
│   └── docker/
│       ├── Dockerfile
│       └── app/
│           └── index.js
├── bin/
│   └── my-cdk-app.ts
├── package.json
├── tsconfig.json
└── cdk.json
```

 **Dockerfile**   

```
FROM public.ecr.aws/lambda/nodejs:16

# Copy application code
COPY app/ /var/task/

# (Optional) Install dependencies
# RUN npm install

# The Lambda Node.js base image looks for index.handler by default
```

 **Code d'application**   
Dans `lib/docker/app/index.js`:  

```
console.log("Hello from inside the container!");
```

 **pile de CDK**   

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ecr_assets from 'aws-cdk-lib/aws-ecr-assets';

export class MyStack extends cdk.Stack {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    // Define a Docker image asset
    const dockerImageAsset = new ecr_assets.DockerImageAsset(this, 'MyDockerImage', {
      directory: 'lib/docker', // Path to the directory containing the Dockerfile
    });

    // Output the ECR URI
    new cdk.CfnOutput(this, 'ECRImageUri', {
      value: dockerImageAsset.imageUri,
    });
  }
}
```

 **Application CDK**   

```
#!/usr/bin/env node
import * as cdk from 'aws-cdk-lib';
import { MyStack } from '../lib/my-stack';

const app = new cdk.App();
new MyStack(app, 'MyStack');
```

Lors de l'exécution`cdk deploy`, l'interface de ligne de commande (CLI) du AWS Cloud Development Kit (AWS CDK) effectue les opérations suivantes :

1.  **Créez l'image Docker** — `docker build` Exécutez-la localement `Dockerfile` en fonction du répertoire spécifié (`lib/docker`).

1.  **Marquer l'image** : exécutez cette `docker tag` option pour étiqueter l'image créée avec un hachage unique, en fonction du contenu de l'image.

1.  **Publier sur Amazon ECR** — Exécutez `docker push` pour publier l'image du conteneur dans un référentiel Amazon ECR. Ce dépôt doit déjà exister. Il est créé pendant le processus d'amorçage par défaut.

1.  **Afficher l'URI de l'image** — Après un déploiement réussi, l'URI Amazon ECR de l'image du conteneur publiée est affiché dans votre invite de commande. Il s'agit de l'URI de notre image Docker dans Amazon ECR.

## Comment remplacer Docker par un autre outil de gestion de conteneurs
<a name="build-container-replace"></a>

Utilisez la variable d'`CDK_DOCKER`environnement pour spécifier le chemin d'accès au binaire de votre outil de gestion des conteneurs de remplacement. Voici un exemple de remplacement de Docker par Finch:

```
$ which finch
/usr/local/bin/finch # Locate the path to the binary

$ export CDK_DOCKER='/usr/local/bin/finch' # Set the environment variable

$ cdk deploy # Deploy using the replacement
```

L'aliasing ou les liens ne sont pas pris en charge. Pour remplacer Docker, vous devez utiliser la variable d'`CDK_DOCKER`environnement.

## Moteurs de remplacement intégrés Docker pris en charge
<a name="build-container-supported"></a>

 Finch est pris en charge, bien que certaines fonctionnalités de Docker puissent ne pas être disponibles ou fonctionner différemment au fur et à mesure de l'évolution de l'outil. Pour plus d'informations sur Finch, voir [Ready for Flight : Annancing Finch 1.0 GA \$1](https://aws.amazon.com/blogs/opensource/ready-for-flight-announcing-finch-1-0-ga/) dans le *blog AWS Open Source*.

D'autres outils de gestion des conteneurs peuvent fonctionner. Le CDK ne vérifie pas quel remplacement de Docker vous utilisez pour déterminer s'il est pris en charge. Si l'outil possède des commandes Docker équivalentes et se comporte de la même manière, il devrait fonctionner.

# Résoudre les problèmes liés aux déploiements de AWS CDK
<a name="deploy-troubleshoot"></a>

Résolvez les problèmes courants lors du déploiement d'applications AWS Cloud Development Kit (AWS CDK).

## Des principes de service incorrects sont créés lors du déploiement
<a name="deploy-troubleshoot-sp"></a>

Lorsque vous déployez des applications CDK contenant des rôles AWS Identity and Access Management (IAM) avec des principaux de service, vous constatez que des domaines incorrects pour les principaux de service sont créés.

Voici un exemple de base de création d'un rôle IAM qui peut être assumé par Amazon CloudWatch Logs à l'aide de son principal de service :

```
import * as cdk from 'aws-cdk-lib';
import * as iam from 'aws-cdk-lib/aws-iam';
import { Construct } from 'constructs';

export class MyCdkProjectStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Create an IAM role for CloudWatch Logs to assume
    const cloudWatchLogsRole = new iam.Role(this, 'CloudWatchLogsRole', {
      assumedBy: new iam.ServicePrincipal('logs.amazonaws.com'), // This is for CloudWatch Logs
      managedPolicies: [
        iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSCloudWatchLogsFullAccess')
      ]
    });

    // You can then use this role in other constructs or configurations where CloudWatch Logs needs to assume a role
  }
}
```

Lorsque vous déployez cette pile, un principal de service nommé `logs.amazonaws.com` doit être créé. Dans la plupart des cas, AWS les services utilisent le nom suivant pour les principaux de service :`<service>.amazonaws.com`.

### Causes courantes
<a name="deploy-troubleshoot-sp-causes"></a>

Si vous utilisez une version du AWS CDK antérieure à la version 2.150.0, il se peut que vous rencontriez ce bogue. Dans les anciennes versions du AWS CDK, la dénomination des principaux de service n'était pas normalisée, ce qui pouvait entraîner la création de principaux de service avec des domaines incorrects.

Dans AWS CDK v2.51.0, un correctif a été mis en œuvre en normalisant tous les principes de service créés automatiquement à utiliser dans la mesure du possible. `<service>.amazonaws.com` Ce correctif était disponible en autorisant l'indicateur de `@aws-cdk/aws-iam:standardizedServicePrincipals` fonctionnalité.

À partir de AWS CDK v2.150.0, ce comportement est devenu le comportement par défaut.

### Résolution
<a name="deploy-troubleshoot-sp-resolution"></a>

Effectuez une mise à niveau vers AWS CDK v2.150.0 ou version ultérieure.

Si vous ne parvenez pas à effectuer la mise à niveau vers AWS CDK v2.150.0 ou version ultérieure, vous devez effectuer la mise à niveau vers au moins la version 2.5.1.0 ou une version plus récente. Ensuite, autorisez l'indicateur de fonctionnalité suivant dans votre `cdk.json` fichier :`@aws-cdk/aws-iam:standardizedServicePrincipals`.