

Questa è la AWS CDK v2 Developer Guide. Il vecchio CDK v1 è entrato in manutenzione il 1° giugno 2022 e ha terminato il supporto il 1° giugno 2023.

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Implementazione di applicazioni AWS CDK
<a name="deploy"></a>

L'implementazione del AWS Cloud Development Kit (AWS CDK) è il processo di provisioning dell'infrastruttura. AWS

## Come funzionano le implementazioni AWS CDK
<a name="deploy-how"></a>

Il AWS CDK utilizza il servizio per eseguire le AWS CloudFormation distribuzioni. Prima della distribuzione, sintetizzate gli stack CDK. Questo crea un CloudFormation modello e implementa gli artefatti per ogni stack CDK nell'app. Le implementazioni vengono avviate da una macchina di sviluppo locale o da un ambiente di *integrazione e distribuzione continue* (CI/CD). Durante la distribuzione, le risorse vengono caricate sulle risorse avviate e il CloudFormation modello viene inviato per il provisioning delle risorse. CloudFormation AWS 

Affinché una distribuzione abbia successo, è necessario quanto segue:
+ L'interfaccia a riga di comando AWS CDK (AWS CDK CLI) deve essere dotata di autorizzazioni valide.
+ L' AWS ambiente deve essere avviato.
+ Il AWS CDK deve conoscere le risorse avviate in cui caricare le risorse.

## Prerequisiti per le implementazioni CDK
<a name="deploy-prerequisites"></a>

Prima di poter distribuire un'applicazione AWS CDK, è necessario completare quanto segue:
+ Configura le credenziali di sicurezza per la CLI CDK.
+ Avvia il tuo ambiente. AWS 
+ Configura un AWS ambiente per ciascuno dei tuoi stack CDK.
+ Sviluppa la tua app CDK.<a name="deploy-prerequisites-creds"></a>

 **Configura le credenziali di sicurezza**   
Per utilizzare la CLI CDK AWS con cui interagire, è necessario configurare le credenziali di sicurezza sul computer locale. Per istruzioni, consulta [Configurare le credenziali di sicurezza per la AWS CLI CDK](configure-access.md).<a name="deploy-prerequisites-bootstrap"></a>

 **Avvia il tuo ambiente AWS **   
Una distribuzione è sempre associata a uno o più AWS [ambienti.](environments.md) Prima di poter eseguire la distribuzione, è necessario [avviare](bootstrapping.md) l'ambiente. Il bootstrap fornisce le risorse dell'ambiente utilizzate dal CDK per eseguire e gestire le distribuzioni. [Queste risorse includono un bucket Amazon Simple Storage Service (Amazon S3) e un repository Amazon Elastic Container Registry (Amazon ECR) Elastic Container ECR) per archiviare e gestire gli asset.](assets.md) Queste risorse includono anche i ruoli AWS Identity and Access Management (IAM) utilizzati per fornire autorizzazioni durante lo sviluppo e la distribuzione.  
Ti consigliamo di utilizzare il comando AWS CDK Command Line Interface (AWS CDK CLI) per avviare `cdk bootstrap` il tuo ambiente. È possibile personalizzare il bootstrap o creare manualmente queste risorse nel proprio ambiente, se necessario. Per istruzioni, consulta [Bootstrap your environment for use with](bootstrapping-env.md) the CDK. AWS <a name="deploy-prerequisites-env"></a>

 **Configura gli ambienti AWS **   
Ogni stack CDK deve essere associato a un ambiente per determinare dove viene distribuito lo stack. Per istruzioni, consulta [Configurare gli ambienti da utilizzare](configure-env.md) con il CDK. AWS <a name="deploy-prerequisites-develop"></a>

 **Sviluppa la tua app CDK**   
All'interno di un [progetto](projects.md) CDK, crei e sviluppi la tua app CDK. [All'interno della tua app, crei uno o più stack CDK.](stacks.md) All'interno degli stack, è possibile importare e utilizzare [costrutti](constructs.md) dalla AWS Construct Library per definire l'infrastruttura. Prima di poter eseguire la distribuzione, l'app CDK deve contenere almeno uno stack.

## Sintesi dell'app CDK
<a name="deploy-how-synth"></a>

Per eseguire la sintesi, si consiglia di utilizzare il comando CDK `cdk synth` CLI. Il `cdk deploy` comando eseguirà anche la sintesi prima di iniziare la distribuzione. Tuttavia, utilizzando`cdk synth`, è possibile convalidare l'app CDK e catturare gli errori prima di iniziare la distribuzione.

Il comportamento di sintesi è determinato dal [sintetizzatore di stack configurato](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib-readme.html#stack-synthesizers) per lo stack CDK. Se non configuri un sintetizzatore, verrà utilizzato. ` [DefaultStackSynthesizer](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.DefaultStackSynthesizer.html) ` Puoi anche configurare e personalizzare la sintesi per soddisfare le tue esigenze. Per istruzioni, consulta [Configurare ed eseguire la sintesi dello stack CDK](configure-synth.md).

Affinché il CloudFormation modello sintetizzato possa essere distribuito correttamente nell'ambiente, deve essere compatibile con il modo in cui è stato avviato l'ambiente. Ad esempio, il CloudFormation modello deve specificare il bucket Amazon S3 corretto in cui distribuire gli asset. Se utilizzi il metodo predefinito di bootstrap del tuo ambiente, il sintetizzatore di stack predefinito funzionerà. Se personalizzi il comportamento CDK, ad esempio personalizzando il bootstrap o la sintesi, il comportamento di implementazione di CDK può variare.<a name="deploy-how-synth-app"></a>

 **Il ciclo di vita dell'app**   
*Quando si esegue la sintesi, l'app CDK attraversa le seguenti fasi, note come ciclo di vita dell'app:*    
 **Costruzione (o inizializzazione)**   
Il codice crea un'istanza di tutti i costrutti definiti e poi li collega tra loro. In questa fase, tutti i costrutti (app, stacks e i relativi costrutti secondari) vengono istanziati e viene eseguita la catena di costruttori. La maggior parte del codice dell'app viene eseguita in questa fase.  
 **Preparazione**   
Tutti i costrutti che hanno implementato il `prepare` metodo partecipano a un ciclo finale di modifiche, per impostare il loro stato finale. La fase di preparazione avviene automaticamente. Come utente, non ricevi alcun feedback da questa fase. È raro che sia necessario utilizzare il gancio «prepare» e generalmente non è consigliato. Fate molta attenzione quando modificate l'albero di costruzione durante questa fase, perché l'ordine delle operazioni potrebbe influire sul comportamento.  
Durante questa fase, una volta creato l'albero di costruzione, vengono applicati anche tutti [gli aspetti](aspects.md) configurati.  
 **Validazione**   
Tutti i costrutti che hanno implementato il `validate` metodo possono convalidarsi per garantire che si trovino in uno stato che venga distribuito correttamente. Riceverai una notifica di eventuali errori di convalida che si verificano durante questa fase. In genere, consigliamo di eseguire la convalida il prima possibile (di solito non appena si riceve un input) e di generare le eccezioni il prima possibile. L'esecuzione precoce della convalida migliora l'affidabilità poiché le tracce dello stack saranno più accurate e garantisce che il codice possa continuare a essere eseguito in modo sicuro.  
 **Sintesi**   
Questa è la fase finale dell'esecuzione dell'app CDK. Viene attivato da una chiamata a`app.synth()`, attraversa l'albero dei costrutti e richiama il metodo su tutti i costrutti. `synthesize` I costrutti che implementano `synthesize` possono partecipare alla sintesi e produrre artefatti di distribuzione nell'assemblaggio cloud risultante. Questi artefatti includono CloudFormation modelli, bundle di applicazioni AWS Lambda, risorse di file e immagini Docker e altri elementi di distribuzione. Nella maggior parte dei casi, non sarà necessario implementare il metodo. `synthesize`<a name="deploy-how-synth-run"></a>

 **Esecuzione dell'app**   
La CLI CDK deve sapere come eseguire l'app CDK. Se hai creato il progetto da un modello utilizzando il `cdk init` comando, il `cdk.json` file dell'app include una chiave. `app` Questa chiave specifica il comando necessario per la lingua in cui è scritta l'app. Se la lingua richiede la compilazione, la riga di comando esegue questo passaggio prima di eseguire automaticamente l'app.  

**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"
}
```
Se non hai creato il tuo progetto utilizzando la CLI CDK o se desideri sovrascrivere la riga di comando fornita `cdk.json` in, puoi fornire ` --app ` l'opzione durante l'esecuzione del comando. `cdk`

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

La `<executable>` parte del comando indica il comando da eseguire per eseguire l'applicazione CDK. Utilizzate le virgolette come illustrato, poiché tali comandi contengono spazi. `<cdk-command>`È un sottocomando simile a `synth` o `deploy` che indica alla CLI CDK cosa vuoi fare con la tua app. Segui questa operazione con tutte le opzioni aggiuntive necessarie per quel sottocomando.

La CLI CDK può anche interagire direttamente con un assemblaggio cloud già sintetizzato. Per farlo, passa la directory in cui è archiviato l'assembly cloud. `--app` L'esempio seguente elenca gli stack definiti nell'assembly cloud archiviato in`./my-cloud-assembly`.

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

 **Assemblaggi cloud**   
La chiamata a `app.synth()` è ciò che dice al AWS CDK di sintetizzare un assemblaggio cloud da un'app. In genere non si interagisce direttamente con gli assembly cloud. Sono file che includono tutto il necessario per distribuire l'app in un ambiente cloud. Ad esempio, include un AWS CloudFormation modello per ogni stack dell'app. Include anche una copia di qualsiasi file, risorsa o immagine Docker a cui fai riferimento nell'app.  
Consulta le [specifiche degli assemblaggi cloud](https://github.com/aws/aws-cdk/blob/master/design/cloud-assembly.md) per i dettagli sulla formattazione degli assembly cloud.  
Per interagire con l'assembly cloud creato dall'app AWS CDK, in genere si utilizza la AWS CLI CDK. Tuttavia, qualsiasi strumento in grado di leggere il formato di assemblaggio cloud può essere utilizzato per distribuire l'app.

## Distribuzione dell'applicazione
<a name="deploy-how-deploy"></a>

Per distribuire la tua applicazione, ti consigliamo di utilizzare il `cdk deploy` comando CDK CLI per avviare le distribuzioni o configurare le distribuzioni automatizzate.

Quando si esegue`cdk deploy`, la CLI CDK `cdk synth` avvia la preparazione per la distribuzione. Il diagramma seguente illustra il ciclo di vita dell'app nel contesto di una distribuzione:

![\[Diagramma di flusso del ciclo di vita dell'app <shared id="AWS"/> CDK.\]](http://docs.aws.amazon.com/it_it/cdk/v2/guide/images/app-lifecycle_cdk-flowchart.png)


Durante l'implementazione, la CLI CDK prende l'assemblaggio cloud prodotto dalla sintesi e lo distribuisce in un ambiente. AWS Le risorse vengono caricate su Amazon S3 e Amazon ECR e il CloudFormation modello viene inviato per AWS CloudFormation la distribuzione.

Quando inizia la fase di AWS CloudFormation distribuzione, l'app CDK ha già terminato l'esecuzione e l'uscita. Ciò comporta quanto segue:
+ L'app CDK non è in grado di rispondere agli eventi che si verificano durante la distribuzione, come la creazione di una risorsa o il completamento dell'intera distribuzione. Per eseguire il codice durante la fase di distribuzione, è necessario inserirlo nel AWS CloudFormation modello come risorsa [personalizzata](cfn-layer.md#develop-customize-custom). Per ulteriori informazioni sull'aggiunta di una risorsa personalizzata all'app, consulta il [AWS CloudFormation modulo](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_cloudformation-readme.html) o l'esempio di risorsa [personalizzata](https://github.com/aws-samples/aws-cdk-examples/tree/master/typescript/custom-resource/). Puoi anche configurare il modulo [Triggers](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.triggers-readme.html) per eseguire il codice durante le distribuzioni.
+ L'app CDK potrebbe dover funzionare con valori che non possono essere conosciuti al momento dell'esecuzione. Ad esempio, se l'app AWS CDK definisce un bucket Amazon S3 con un nome generato automaticamente e recuperi `bucket.bucketName` l'attributo (`bucket_name`Python:), quel valore non è il nome del bucket distribuito. Invece, ottieni un valore. `Token` Per determinare se un particolare valore è disponibile, chiama `cdk.isUnresolved(value)` (Python:`is_unresolved`). Vedi [Tokens and the AWS CDK per i dettagli.](tokens.md)<a name="deploy-how-deploy-permissions"></a>

 **Autorizzazioni di distribuzione**   
Prima di poter eseguire la distribuzione, è necessario stabilire le autorizzazioni. Il diagramma seguente illustra le autorizzazioni utilizzate durante una distribuzione predefinita, quando si utilizza il processo di bootstrap e il sintetizzatore di stack predefiniti:  

![\[Diagramma di flusso del processo di distribuzione <shared id="AWS"/> CDK predefinito.\]](http://docs.aws.amazon.com/it_it/cdk/v2/guide/images/default-deploy-process_cdk_flowchart.png)
  
 **L'attore avvia la distribuzione**   
Le distribuzioni vengono avviate da un *attore*, utilizzando la CLI CDK. Un attore può essere una persona o un servizio come. AWS CodePipeline  
Se necessario, la CLI CDK `cdk synth` viene eseguita quando si esegue. `cdk deploy` Durante la sintesi, l' AWS identità presuppone l'esecuzione `LookupRole` di ricerche contestuali nell'ambiente. AWS   
 **Le autorizzazioni sono stabilite**   
Innanzitutto, le credenziali di sicurezza dell'attore vengono utilizzate per autenticarsi AWS e ottenere la prima identità IAM durante il processo. Per gli attori umani, il modo in cui le credenziali di sicurezza vengono configurate e ottenute dipende dal modo in cui l'utente o la sua organizzazione gestiscono gli utenti. Per ulteriori informazioni, consulta [Configurare le credenziali di sicurezza per la AWS CLI CDK](configure-access.md). Per gli attori del servizio, ad esempio CodePipeline, viene assunto e utilizzato un ruolo di esecuzione IAM.  
Successivamente, i ruoli IAM creati nell' AWS ambiente durante il bootstrap vengono utilizzati per stabilire le autorizzazioni necessarie per eseguire le azioni necessarie per la distribuzione. Per ulteriori informazioni su questi ruoli e su cosa concedono le autorizzazioni, consulta [Ruoli IAM](bootstrapping-env.md#bootstrapping-env-roles) creati durante il bootstrap. Questo processo include quanto segue:  
+ L' AWS identità assume il `DeploymentActionRole` ruolo e lo `CloudFormationExecutionRole` passa a lui CloudFormation, assicurandosi che CloudFormation assuma il ruolo quando esegue qualsiasi azione nell'ambiente dell'utente AWS . `DeploymentActionRole`concede l'autorizzazione a eseguire distribuzioni nell'ambiente e `CloudFormationExecutionRole` determina quali azioni possono essere eseguite. CloudFormation 
+ L' AWS identità presuppone il`FilePublishingRole`, che determina le azioni che possono essere eseguite sul bucket Amazon S3 creato durante il bootstrap.
+ L' AWS identità presuppone il`ImagePublishingRole`, che determina le azioni che possono essere eseguite sul repository Amazon ECR creato durante il bootstrap.
+ Se necessario, l' AWS identità presuppone l'esecuzione di ricerche contestuali nell'`LookupRole`ambiente. AWS Questa azione può essere eseguita anche durante la sintesi del modello.  
 **La distribuzione viene eseguita**   
Durante la distribuzione, la CLI CDK legge il parametro della versione bootstrap per confermare il numero di versione bootstrap. AWS CloudFormation legge questo parametro anche al momento della distribuzione per confermare. Se le autorizzazioni per tutto il flusso di lavoro di distribuzione sono valide, viene eseguita la distribuzione. Le risorse vengono caricate nelle risorse avviate e il CloudFormation modello prodotto in fase di sintesi viene distribuito utilizzando il CloudFormation servizio come CloudFormation stack per fornire le risorse.

# AWS Convalida della politica CDK al momento della sintesi
<a name="policy-validation-synthesis"></a>

## Convalida delle politiche al momento della sintesi
<a name="policy-validation"></a>

Se tu o la tua organizzazione utilizzate uno strumento di convalida delle politiche, come [AWS CloudFormation Guard](https://docs.aws.amazon.com/cfn-guard/latest/ug/what-is-guard.html) o [OPA](https://www.openpolicyagent.org/), per definire i vincoli sul AWS CloudFormation modello, potete integrarli con il CDK al momento della AWS sintesi. Utilizzando il plug-in di convalida delle politiche appropriato, potete fare in modo che l'applicazione AWS CDK verifichi il AWS CloudFormation modello generato rispetto alle vostre politiche subito dopo la sintesi. In caso di violazioni, la sintesi avrà esito negativo e un rapporto verrà stampato sulla console.

La convalida eseguita dal AWS CDK al momento della sintesi convalida i controlli a un certo punto del ciclo di vita dell'implementazione, ma non può influire sulle azioni che avvengono al di fuori della sintesi. Gli esempi includono le azioni intraprese direttamente nella console o tramite il servizio. APIs Non resistono all'alterazione dei AWS CloudFormation modelli dopo la sintesi. [Qualche altro meccanismo per convalidare lo stesso set di regole in modo più autorevole dovrebbe essere impostato indipendentemente, come [AWS CloudFormation hooks o](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/hooks.html) Config.AWS](https://docs.aws.amazon.com/config/latest/developerguide/WhatIsConfig.html) Tuttavia, la capacità del AWS CDK di valutare il set di regole durante lo sviluppo è ancora utile in quanto migliorerà la velocità di rilevamento e la produttività degli sviluppatori.

L'obiettivo della convalida delle policy AWS CDK è ridurre al minimo la quantità di impostazioni necessarie durante lo sviluppo e renderlo il più semplice possibile.

**Nota**  
Questa funzionalità è considerata sperimentale e sia l'API del plug-in che il formato del rapporto di convalida sono soggetti a modifiche in futuro.

## Per gli sviluppatori di applicazioni
<a name="for-application-developers"></a>

Per utilizzare uno o più plugin di convalida nell'applicazione, utilizzate la `policyValidationBeta1` proprietà di: `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: [...],
});
```

Immediatamente dopo la sintesi, tutti i plugin registrati in questo modo verranno richiamati per convalidare tutti i modelli generati nell'ambito definito. In particolare, se si registrano i modelli nell'`App`oggetto, tutti i modelli saranno soggetti a convalida.

**avvertimento**  
Oltre a modificare l'assembly cloud, i plugin possono fare tutto ciò che può fare l'applicazione AWS CDK. Possono leggere i dati dal filesystem, accedere alla rete ecc. È tua responsabilità, in qualità di consumatore di un plug-in, verificare che sia sicuro da usare.

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

L'utilizzo del [https://github.com/cdklabs/cdk-validator-cfnguard](https://github.com/cdklabs/cdk-validator-cfnguard)plug-in consente di utilizzare [AWS CloudFormation Guard](https://github.com/aws-cloudformation/cloudformation-guard) per eseguire convalide delle politiche. Il `CfnGuardValidator` plug-in viene fornito con un set selezionato di [controlli proattivi AWS Control Tower](https://docs.aws.amazon.com/controltower/latest/userguide/proactive-controls.html) integrati. L'attuale set di regole è disponibile nella [documentazione del progetto](https://github.com/cdklabs/cdk-validator-cfnguard/blob/main/README.md). [Come menzionato in [La convalida delle politiche al momento della sintesi](#policy-validation), raccomandiamo alle organizzazioni di impostare un metodo di convalida più autorevole utilizzando gli hook.AWS CloudFormation ](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/hooks.html)

Per i clienti [AWS Control Tower](https://docs.aws.amazon.com/controltower/latest/userguide/what-is-control-tower.html), questi stessi controlli proattivi possono essere implementati in tutta l'organizzazione. Quando abiliti i controlli proattivi AWS Control Tower nel tuo ambiente AWS Control Tower, i controlli possono interrompere l'implementazione di risorse non conformi distribuite tramite. AWS CloudFormation Per ulteriori informazioni sui controlli proattivi gestiti e sul loro funzionamento, consulta la [documentazione AWS Control Tower](https://docs.aws.amazon.com/controltower/latest/userguide/proactive-controls.html).

Questi controlli in bundle AWS CDK e i controlli proattivi AWS Control Tower gestiti sono utilizzati al meglio insieme. In questo scenario puoi configurare questo plug-in di convalida con gli stessi controlli proattivi attivi nell'ambiente cloud AWS Control Tower. È quindi possibile acquisire rapidamente la certezza che l'applicazione AWS CDK supererà i controlli della AWS Control Tower eseguendo `cdk synth` localmente.

### Rapporto di convalida
<a name="validation-report"></a>

Quando sintetizzi l'app AWS CDK, verranno richiamati i plugin di convalida e i risultati verranno stampati. Di seguito è riportato un esempio di report.

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

Per impostazione predefinita, il rapporto verrà stampato in un formato leggibile dall'uomo. Se desideri un report in formato JSON, abilitalo `@aws-cdk/core:validationReportJson` utilizzando la CLI o passandolo direttamente all'applicazione:

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

In alternativa, puoi impostare questa coppia chiave-valore di contesto utilizzando `cdk.context.json` i file `cdk.json` o nella directory del tuo progetto (vedi [Valori di contesto e](context.md) CDK). AWS 

Se scegli il formato JSON, il AWS CDK stamperà il rapporto di convalida delle politiche in un file chiamato `policy-validation-report.json` nella directory di assemblaggio cloud. Per il formato predefinito, leggibile dall'uomo, il report verrà stampato sullo standard output.

## Per gli autori di plugin
<a name="plugin-authors"></a>

### Plug-in
<a name="plugins"></a>

Il framework di base AWS CDK è responsabile della registrazione e dell'invocazione dei plugin e della successiva visualizzazione del rapporto di convalida formattato. La responsabilità del plugin è quella di fungere da livello di traduzione tra il framework AWS CDK e lo strumento di convalida delle politiche. Un plugin può essere creato in qualsiasi lingua supportata da AWS CDK. Se stai creando un plug-in che potrebbe essere utilizzato da più lingue, ti consigliamo di crearlo in `TypeScript` modo da poter utilizzare JSII per pubblicare il plug-in in ogni AWS lingua CDK.

### Creazione di plugin
<a name="creating-plugins"></a>

Il protocollo di comunicazione tra il modulo principale AWS CDK e lo strumento di policy è definito dall'`IPolicyValidationPluginBeta1`interfaccia. Per creare un nuovo plugin è necessario scrivere una classe che implementi questa interfaccia. Ci sono due cose che devi implementare: il nome del plugin (sovrascrivendo la `name` proprietà) e il `validate()` metodo.

Il framework chiamerà`validate()`, passando un `IValidationContextBeta1` oggetto. La posizione dei modelli da convalidare è data da`templatePaths`. Il plugin dovrebbe restituire un'istanza di. `ValidationPluginReportBeta1` Questo oggetto rappresenta il rapporto che l'utente riceverà alla fine della sintesi.

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

Nota che i plugin non sono autorizzati a modificare nulla nell'assembly cloud. Qualsiasi tentativo in tal senso comporterà un errore di sintesi.

Se il tuo plugin dipende da uno strumento esterno, tieni presente che alcuni sviluppatori potrebbero non avere ancora installato questo strumento nelle loro workstation. Per ridurre al minimo l'attrito, ti consigliamo vivamente di fornire uno script di installazione insieme al pacchetto del plugin, per automatizzare l'intero processo. Meglio ancora, esegui lo script come parte dell'installazione del pacchetto. Con`npm`, ad esempio, puoi aggiungerlo allo `postinstall` [script](https://docs.npmjs.com/cli/v9/using-npm/scripts) nel `package.json` file.

### Gestione delle esenzioni
<a name="handling-exemptions"></a>

Se l'organizzazione dispone di un meccanismo per la gestione delle esenzioni, può essere implementato come parte del plugin di convalida.

Uno scenario di esempio per illustrare un possibile meccanismo di esenzione:
+ Un'organizzazione ha una regola secondo cui i bucket Amazon S3 pubblici non sono consentiti, *tranne* in determinati scenari.
+ Uno sviluppatore sta creando un bucket Amazon S3 che rientra in uno di questi scenari e richiede un'esenzione (ad esempio, crea un ticket).
+ Gli strumenti di sicurezza sanno leggere dal sistema interno che registra le esenzioni

In questo scenario lo sviluppatore richiederebbe un'eccezione nel sistema interno e quindi avrà bisogno di un modo per «registrare» tale eccezione. Oltre all'esempio del plugin guard, potresti creare un plug-in che gestisca le esenzioni filtrando le violazioni che hanno un'esenzione corrispondente in un sistema di ticketing interno.

Vedi i plugin esistenti per esempio per le implementazioni.
+  [@cdklabs/cdk-validator-cfnguard](https://github.com/cdklabs/cdk-validator-cfnguard) 

# Integrazione e distribuzione continue (CI/CD) con CDK Pipelines
<a name="cdk-pipeline"></a>

Utilizzate il modulo [CDK](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.pipelines-readme.html) Pipelines AWS della Construct Library per configurare la distribuzione continua delle applicazioni CDK. AWS Quando esegui il commit del codice sorgente della tua app CDK in AWS CodeCommit, o GitHub AWS CodeStar, CDK Pipelines può creare, testare e distribuire automaticamente la tua nuova versione.

Le CDK Pipelines si aggiornano automaticamente. Se aggiungi stadi o stack di applicazioni, la pipeline si riconfigura automaticamente per distribuire quei nuovi stadi o stack.

**Nota**  
CDK Pipelines ne supporta due. APIs Una è l'API originale resa disponibile nella CDK Pipelines Developer Preview. L'altra è un'API moderna che incorpora il feedback dei clienti CDK ricevuto durante la fase di anteprima. Gli esempi in questo argomento utilizzano l'API moderna. *Per i dettagli sulle differenze tra le due supportate APIs, consulta l'API [originale di CDK Pipelines](https://github.com/aws/aws-cdk/blob/master/packages/@aws-cdk/pipelines/ORIGINAL_API.md) nel repository aws-cdk. GitHub *

## AWS Avvia i tuoi ambienti
<a name="cdk-pipeline-bootstrap"></a>

Prima di poter utilizzare CDK Pipelines, è necessario avviare AWS [l'ambiente in cui verranno distribuiti gli](environments.md) stack.

Una CDK Pipeline coinvolge almeno due ambienti. Il primo ambiente è quello in cui viene effettuato il provisioning della pipeline. Il secondo ambiente è quello in cui si desidera distribuire gli stack o le fasi dell'applicazione (le fasi sono gruppi di stack correlati). Questi ambienti possono essere uguali, ma una buona pratica è quella di isolare le fasi l'una dall'altra in ambienti diversi.

**Nota**  
Vedi [AWS CDK bootstrap](bootstrapping.md) per ulteriori informazioni sui tipi di risorse create dal bootstrap e su come personalizzare lo stack bootstrap.

L'implementazione continua con CDK Pipelines richiede l'inclusione di quanto segue nello stack CDK Toolkit:
+ Un bucket Amazon Simple Storage Service (Amazon S3).
+ Un repository Amazon ECR.
+ Ruoli IAM per fornire alle varie parti di una pipeline le autorizzazioni di cui hanno bisogno.

Il CDK Toolkit aggiornerà lo stack di bootstrap esistente o ne creerà uno nuovo, se necessario.

Per avviare un ambiente in grado di effettuare il provisioning di una pipeline AWS CDK, `cdk bootstrap` richiamate come mostrato nell'esempio seguente. L'invocazione del AWS CDK Toolkit tramite il comando lo installa `npx` temporaneamente, se necessario. Utilizzerà anche la versione del Toolkit installata nel progetto corrente, se ne esiste una.

 `--cloudformation-execution-policies`specifica l'ARN di una policy in base alla quale verranno eseguite le future implementazioni di CDK Pipelines. La `AdministratorAccess` politica predefinita assicura che la pipeline possa distribuire ogni tipo di risorsa. AWS Se utilizzi questa politica, assicurati di considerare attendibile tutto il codice e le dipendenze che compongono la tua AWS app CDK.

La maggior parte delle organizzazioni impone controlli più rigorosi sui tipi di risorse che possono essere distribuite mediante l'automazione. Rivolgiti al reparto competente all'interno dell'organizzazione per determinare la politica da utilizzare nella tua pipeline.

Puoi omettere l'`--profile`opzione se il tuo AWS profilo predefinito contiene la configurazione di autenticazione e AWS la regione necessarie.

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

Per avviare ambienti aggiuntivi in cui le applicazioni AWS CDK verranno distribuite dalla pipeline, utilizzate invece i seguenti comandi. L'`--trust`opzione indica quale altro account deve disporre delle autorizzazioni per distribuire le applicazioni CDK in questo ambiente. AWS Per questa opzione, specifica l'ID dell'account della pipeline. AWS 

Ancora una volta, puoi omettere l'`--profile`opzione se il tuo AWS profilo predefinito contiene la configurazione di autenticazione e AWS la regione necessarie.

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

**Suggerimento**  
Utilizzate le credenziali amministrative solo per il bootstrap e per il provisioning della pipeline iniziale. In seguito, utilizzate la pipeline stessa, non il computer locale, per distribuire le modifiche.

Se stai aggiornando un ambiente con bootstrap legacy, il bucket Amazon S3 precedente rimane orfano quando viene creato il nuovo bucket. Eliminalo manualmente utilizzando la console Amazon S3.

### Proteggere lo stack di bootstrap dall'eliminazione
<a name="cdk-pipeline-protect"></a>

Se uno stack di bootstrap viene eliminato, verranno eliminate anche le AWS risorse originariamente fornite nell'ambiente per supportare le distribuzioni CDK. Ciò causerà l'interruzione del funzionamento della pipeline. Se ciò accade, non esiste una soluzione generale per il ripristino.

Dopo aver avviato l'ambiente, non eliminate e ricreate lo stack di bootstrap dell'ambiente. Prova invece ad aggiornare lo stack di bootstrap a una nuova versione eseguendo nuovamente il comando. `cdk bootstrap`

Per evitare l'eliminazione accidentale dello stack di bootstrap, ti consigliamo di fornire l'`--termination-protection`opzione con il `cdk bootstrap` comando per abilitare la protezione dalla terminazione. È possibile abilitare la protezione dalla terminazione su stack di bootstrap nuovi o esistenti. Per ulteriori informazioni su questa opzione, consulta. ` --termination-protection `

Dopo aver abilitato la protezione dalla terminazione, puoi utilizzare la AWS CLI CloudFormation o la console per la verifica.

1. Esegui il comando seguente per abilitare la protezione dalla terminazione su uno stack di bootstrap nuovo o esistente:

   ```
   $ cdk bootstrap --termination-protection
   ```

1. Utilizza la AWS CLI o la CloudFormation console per verificare. Di seguito è riportato un esempio di utilizzo della AWS CLI. Se hai modificato il nome dello stack di bootstrap, sostituiscilo `CDKToolkit` con il nome dello stack:

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

## Inizializza un progetto
<a name="cdk-pipeline-init"></a>

Crea un nuovo GitHub progetto vuoto e clonalo sulla tua workstation nella directory. `my-pipeline` (I nostri esempi di codice in questo argomento utilizzano. GitHub Puoi anche usare AWS CodeStar o AWS CodeCommit.)

```
git clone <GITHUB-CLONE-URL> my-pipeline
cd my-pipeline
```

**Nota**  
Puoi usare un nome diverso `my-pipeline` da quello della directory principale dell'app. Tuttavia, in tal caso, sarà necessario modificare i nomi dei file e delle classi più avanti in questo argomento. Questo perché AWS CDK Toolkit basa alcuni nomi di file e classi sul nome della directory principale.

Dopo la clonazione, inizializza il progetto come al solito.

**Example**  

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

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

```
$ cdk init app --language python
```
Dopo aver creato l'app, inserisci anche i due comandi seguenti. Questi attivano l'ambiente virtuale Python dell'app e installano le dipendenze principali del 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
```
Se utilizzi un IDE, ora puoi aprire o importare il progetto. In Eclipse, ad esempio, scegli **File** > **Importa** > Maven > **Progetti Maven** **esistenti**. Assicuratevi che le impostazioni del progetto siano impostate per utilizzare Java 8 (1.8).

```
$ cdk init app --language csharp
```
Se utilizzi Visual Studio, apri il file della soluzione nella `src` directory.

```
$ cdk init app --language go
```
Dopo aver creato l'app, inserisci anche il seguente comando per installare i moduli AWS Construct Library richiesti dall'app.  

```
$ go get
```

**Importante**  
Assicurati di affidare i tuoi `cdk.context.json` file `cdk.json` e i tuoi file al controllo del codice sorgente. Le informazioni di contesto (come i flag delle funzionalità e i valori memorizzati nella cache recuperati dal tuo AWS account) fanno parte dello stato del progetto. I valori possono essere diversi in un altro ambiente, il che può causare cambiamenti imprevisti nei risultati. Per ulteriori informazioni, consulta [Valori di contesto e AWS CDK.](context.md)

## Definire una pipeline
<a name="cdk-pipeline-define"></a>

L'applicazione CDK Pipelines includerà almeno due stack: uno che rappresenta la pipeline stessa e uno o più stack che rappresentano l'applicazione distribuita attraverso di essa. Gli stack possono anche essere raggruppati in *fasi*, che è possibile utilizzare per distribuire copie degli stack di infrastruttura in ambienti diversi. Per ora, prenderemo in considerazione la pipeline e in seguito approfondiremo l'applicazione che verrà implementata.

Il costrutto ` [CodePipeline](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.pipelines.CodePipeline.html) ` è il costrutto che rappresenta una CDK Pipeline che utilizza come motore di distribuzione. AWS CodePipeline Quando si crea un'istanza `CodePipeline` in uno stack, si definisce la posizione di origine della pipeline (ad esempio un repository). GitHub Definisci anche i comandi per creare l'app.

Ad esempio, quanto segue definisce una pipeline la cui origine è archiviata in un GitHub repository. Include anche una fase di compilazione per un'applicazione TypeScript CDK. Inserisci le informazioni sul tuo GitHub repo dove indicato.

**Nota**  
Per impostazione predefinita, la pipeline si autentica GitHub utilizzando un token di accesso personale memorizzato in Secrets Manager sotto il nome. `github-token`

Dovrai anche aggiornare l'istanza dello stack di pipeline per specificare l'account e la regione. AWS 

**Example**  
In `lib/my-pipeline-stack.ts` (può variare se la cartella del progetto non ha un nome): `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']
      })
    });
  }
}
```
In `bin/my-pipeline.ts` (può variare se la cartella del progetto non ha un nome`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();
```
In `lib/my-pipeline-stack.js` (può variare se la cartella del progetto non ha un nome`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 }
```
In `bin/my-pipeline.js` (può variare se la cartella del progetto non ha un nome`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();
```
In `my-pipeline/my-pipeline-stack.py` (può variare se la cartella del progetto non ha un nome`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"]
                        )
                    )
```
In `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()
```
In `src/main/java/com/myorg/MyPipelineStack.java` (può variare se la cartella del progetto non ha un nome`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();
    }
}
```
In `src/main/java/com/myorg/MyPipelineApp.java` (può variare se la cartella del progetto non ha un nome`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();
    }
}
```
In `src/MyPipeline/MyPipelineStack.cs` (può variare se la cartella del progetto non ha un nome`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" }
                })
            });
        }
    }
}
```
In `src/MyPipeline/Program.cs` (può variare se la cartella del progetto non ha un nome`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")),
	}
}
```

È necessario distribuire una pipeline manualmente una volta. Dopodiché, la pipeline si aggiorna dal repository del codice sorgente. Quindi assicurati che il codice nel repository sia il codice che desideri distribuire. Controlla le modifiche e invia a GitHub, quindi distribuisci:

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

**Suggerimento**  
Ora che hai completato la distribuzione iniziale, il tuo AWS account locale non necessita più dell'accesso amministrativo. Questo perché tutte le modifiche all'app verranno distribuite tramite la pipeline. Tutto quello che devi fare è premere su. GitHub

## Fasi della candidatura
<a name="cdk-pipeline-stages"></a>

Per definire un' AWS applicazione multi-stack che può essere aggiunta alla pipeline tutta in una volta, definite una sottoclasse di. ` [Stage](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stage.html) ` (Questo è diverso dal modulo `CdkStage` CDK Pipelines.)

Lo stage contiene gli stack che compongono l'applicazione. Se esistono dipendenze tra gli stack, gli stack vengono aggiunti automaticamente alla pipeline nell'ordine corretto. Gli stack che non dipendono l'uno dall'altro vengono distribuiti in parallelo. Puoi aggiungere una relazione di dipendenza tra gli stack chiamando. `stack1.addDependency(stack2)`

Gli stadi accettano un `env` argomento predefinito, che diventa l'ambiente predefinito per gli stack al suo interno. (Gli stack possono comunque avere il proprio ambiente specificato.).

[Un'applicazione viene aggiunta alla pipeline chiamando ` [addStage()](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.pipelines.CodePipeline.html#addwbrstagestage-optionss) ` con istanze di Stage.](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stage.html) Una fase può essere istanziata e aggiunta alla pipeline più volte per definire fasi diverse della pipeline di applicazioni DTAP o multiregione.

Creeremo uno stack contenente una semplice funzione Lambda e lo posizioneremo in uno stage. Quindi aggiungeremo lo stage alla pipeline in modo che possa essere distribuito.

**Example**  
Crea il nuovo file `lib/my-pipeline-lambda-stack.ts` per contenere il nostro stack di applicazioni contenente una funzione 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";')
      });
    }
}
```
Crea il nuovo file `lib/my-pipeline-app-stage.ts` per ospitare il nostro palco.  

```
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');
    }
}
```
Modifica `lib/my-pipeline-stack.ts` per aggiungere lo stage alla nostra 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" }
    }));
  }
}
```
Crea il nuovo file `lib/my-pipeline-lambda-stack.js` per contenere il nostro stack di applicazioni contenente una funzione 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 }
```
Crea il nuovo file `lib/my-pipeline-app-stage.js` per ospitare il nostro palco.  

```
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 };
```
Modifica `lib/my-pipeline-stack.ts` per aggiungere lo stage alla nostra 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 }
```
Crea il nuovo file `my_pipeline/my_pipeline_lambda_stack.py` per contenere il nostro stack di applicazioni contenente una funzione 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';")
        )
```
Crea il nuovo file `my_pipeline/my_pipeline_app_stage.py` per ospitare il nostro palco.  

```
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")
```
Modifica `my_pipeline/my-pipeline-stack.py` per aggiungere lo stage alla nostra 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")))
```
Crea il nuovo file `src/main/java/com.myorg/MyPipelineLambdaStack.java` per contenere il nostro stack di applicazioni contenente una funzione 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();

    }

}
```
Crea il nuovo file `src/main/java/com.myorg/MyPipelineAppStage.java` per ospitare il nostro palco.  

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

}
```
Modifica `src/main/java/com.myorg/MyPipelineStack.java` per aggiungere lo stage alla nostra 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()));
    }
}
```
Crea il nuovo file `src/MyPipeline/MyPipelineLambdaStack.cs` per contenere il nostro stack di applicazioni contenente una funzione 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';")
            });
        }
    }
}
```
Crea il nuovo file `src/MyPipeline/MyPipelineAppStage.cs` per ospitare il nostro palco.  

```
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");
        }
    }
}
```
Modifica `src/MyPipeline/MyPipelineStack.cs` per aggiungere lo stage alla nostra 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"
                }
            }));
        }
    }
}
```

Ogni fase dell'applicazione aggiunta da `addStage()` comporta l'aggiunta di una fase della pipeline corrispondente, rappresentata da un'` [StageDeployment](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.pipelines.StageDeployment.html) `istanza restituita dalla `addStage()` chiamata. È possibile aggiungere azioni di pre-distribuzione o post-distribuzione alla fase chiamandone `addPre()` il metodo 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"));
```

È possibile aggiungere fasi a ` [Wave](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.pipelines.Wave.html) ` a per distribuirle in parallelo, ad esempio quando si distribuisce una fase su più account o regioni.

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

## Test delle implementazioni
<a name="cdk-pipeline-validation"></a>

Puoi aggiungere passaggi a una pipeline CDK per convalidare le distribuzioni che stai eseguendo. Ad esempio, puoi utilizzare le librerie CDK Pipeline per eseguire attività come ` [ShellStep](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.pipelines.ShellStep.html) ` le seguenti:
+ Tentativo di accesso a un Amazon API Gateway appena distribuito supportato da una funzione Lambda
+ Verifica dell'impostazione di una risorsa distribuita mediante l'emissione di un comando CLI AWS 

Nella sua forma più semplice, l'aggiunta di azioni di convalida è la seguente:

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

Molte AWS CloudFormation implementazioni comportano la generazione di risorse con nomi imprevedibili. Per questo motivo, CDK Pipelines fornisce un modo per AWS CloudFormation leggere gli output dopo una distribuzione. In questo modo è possibile passare (ad esempio) l'URL generato di un sistema di bilanciamento del carico a un'azione di test.

Per utilizzare gli output, esponi l'`CfnOutput`oggetto che ti interessa. Quindi, passalo nella `envFromCfnOutputs` proprietà di un passaggio per renderlo disponibile come variabile di ambiente all'interno di quel passaggio.

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

Puoi scrivere semplici test di convalida direttamente in`ShellStep`, ma questo approccio diventa complicato quando il test dura più di poche righe. Per test più complessi, potete inserire file aggiuntivi (come script di shell completi o programmi in altri linguaggi) nella proprietà tramite the. `ShellStep` `inputs` Gli input possono essere qualsiasi passaggio che abbia un output, inclusa una fonte (come un GitHub repository) o un'altra. `ShellStep`

L'inserimento di file dal repository dei sorgenti è appropriato se i file sono direttamente utilizzabili nel test (ad esempio, se sono essi stessi eseguibili). In questo esempio, dichiariamo il nostro GitHub repository come `source` (anziché istanziarlo in linea come parte di). `CodePipeline` Quindi, passiamo questo set di file sia alla pipeline che al test di convalida.

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

Ottenere i file aggiuntivi dalla fase di sintetizzazione è appropriato se i test devono essere compilati, operazione che viene eseguita come parte della sintesi.

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

## Note sulla sicurezza
<a name="cdk-pipeline-security"></a>

Qualsiasi forma di distribuzione continua presenta rischi intrinseci per la sicurezza. In base al [modello di responsabilità AWS condivisa](https://aws.amazon.com/compliance/shared-responsibility-model/), sei responsabile della sicurezza delle tue informazioni nel AWS cloud. La libreria CDK Pipelines ti offre un vantaggio iniziale incorporando impostazioni predefinite sicure e best practice di modellazione.

Tuttavia, per sua stessa natura, una libreria che necessita di un elevato livello di accesso per soddisfare lo scopo previsto non può garantire una sicurezza completa. Esistono molti vettori di attacco esterni AWS all'organizzazione.

In particolare, tenete presente quanto segue:
+ Fai attenzione al software da cui dipendi. Controlla tutti i software di terze parti che utilizzi nella tua pipeline, perché possono modificare l'infrastruttura che viene implementata.
+ Utilizza il blocco delle dipendenze per evitare aggiornamenti accidentali. CDK Pipelines `package-lock.json` rispetta `yarn.lock` e si assicura che le vostre dipendenze siano quelle che vi aspettate.
+ CDK Pipelines funziona con risorse create nel tuo account e la configurazione di tali risorse è controllata dagli sviluppatori che inviano il codice tramite la pipeline. Pertanto, CDK Pipelines da solo non può proteggere da sviluppatori malintenzionati che cercano di aggirare i controlli di conformità. Se il tuo modello di minaccia include sviluppatori che scrivono codice CDK, dovresti disporre di meccanismi di conformità esterni come [AWS CloudFormation Hooks](https://aws.amazon.com/blogs/mt/proactively-keep-resources-secure-and-compliant-with-aws-cloudformation-hooks/) (preventivo) o [AWS Config](https://aws.amazon.com/config/) (reattivo) che l' AWS CloudFormation Execution Role non dispone delle autorizzazioni per disabilitare.
+ Le credenziali per gli ambienti di produzione dovrebbero avere vita breve. Dopo il bootstrap e il provisioning iniziale, non è affatto necessario che gli sviluppatori dispongano delle credenziali dell'account. Le modifiche possono essere implementate tramite la pipeline. Riduci la possibilità di perdita delle credenziali evitando innanzitutto di averne bisogno.

## Risoluzione dei problemi
<a name="cdk-pipeline-troubleshooting"></a>

I seguenti problemi si riscontrano comunemente quando si inizia a usare CDK Pipelines.

 **Pipeline: errore interno**   

```
CREATE_FAILED  | {aws}::CodePipeline::Pipeline | Pipeline/Pipeline
Internal Failure
```
Controlla il tuo token di GitHub accesso. Potrebbe mancare o potrebbe non disporre delle autorizzazioni per accedere al repository.

 **Chiave: La policy contiene una dichiarazione con uno o più principi non validi**   

```
CREATE_FAILED | {aws}::KMS::Key | Pipeline/Pipeline/ArtifactsBucketEncryptionKey
Policy contains a statement with one or more invalid principals.
```
Uno degli ambienti di destinazione non è stato avviato con il nuovo stack bootstrap. Assicurati che tutti gli ambienti di destinazione siano avviati.

 **Lo stack è nello stato ROLLBACK\$1COMPLETE e non può essere aggiornato**   

```
Stack <STACK_NAME> is in ROLLBACK_COMPLETE state and cannot be updated. (Service:
AmazonCloudFormation; Status Code: 400; Error Code: ValidationError; Request
ID: ...)
```
Lo stack non è riuscito nella distribuzione precedente ed è in uno stato non riutilizzabile. Elimina lo stack dalla AWS CloudFormation console e riprova la distribuzione.

# Crea e distribuisci risorse di immagini dei container nelle app CDK
<a name="build-containers"></a>

Quando crei risorse di immagini dei container con il AWS Cloud Development Kit (AWS CDK), Docker viene utilizzato di default per eseguire queste azioni. Se desideri utilizzare uno strumento di gestione dei container diverso, puoi sostituire Docker tramite la variabile di ambiente. `CDK_DOCKER`

## Esempio: crea e pubblica una risorsa di immagine del contenitore con CDK AWS
<a name="build-containers-intro-example"></a>

Di seguito è riportato un semplice esempio di app AWS CDK che crea e pubblica una risorsa contenitore su Amazon Elastic Container Registry (Amazon ECR) utilizzando Docker per impostazione predefinita:

 **Struttura del progetto**   

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

 **File Docker**   

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

 **Codice dell'applicazione**   
In `lib/docker/app/index.js`:  

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

 **stack 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,
    });
  }
}
```

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

Quando eseguiamo`cdk deploy`, l'interfaccia a riga di comando (CLI) del AWS Cloud Development Kit (AWS CDK) esegue le seguenti operazioni:

1.  **Crea l'immagine Docker**: esegui `docker build` localmente `Dockerfile` in base alla directory specificata (). `lib/docker`

1.  **Etichetta l'immagine**: esegui `docker tag` per etichettare l'immagine creata con un hash univoco, in base al contenuto dell'immagine.

1.  **Pubblica su Amazon ECR**: esegui `docker push` per pubblicare l'immagine del contenitore in un repository Amazon ECR. Questo repository deve già esistere. Viene creato durante il processo di bootstrap predefinito.

1.  **Esporta l'URI dell'immagine**: dopo una distribuzione corretta, l'URI Amazon ECR dell'immagine del contenitore pubblicata viene emesso nel prompt dei comandi. Questo è l'URI della nostra immagine Docker in Amazon ECR.

## Come sostituire Docker con un altro strumento di gestione dei container
<a name="build-container-replace"></a>

Utilizza la variabile di `CDK_DOCKER` ambiente per specificare il percorso del file binario dello strumento di gestione dei container sostitutivo. Di seguito è riportato un esempio di sostituzione di Docker con 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 o il collegamento non sono supportati. Per sostituire Docker, è necessario utilizzare la `CDK_DOCKER` variabile di ambiente.

## Motori sostitutivi Docker drop-in supportati
<a name="build-container-supported"></a>

 Finch è supportato, anche se alcune funzionalità di Docker potrebbero non essere disponibili o funzionare in modo diverso man mano che lo strumento si evolve. Per ulteriori informazioni su Finch, vedi [Ready for Flight: Announcing Finch 1.0](https://aws.amazon.com/blogs/opensource/ready-for-flight-announcing-finch-1-0-ga/) GA\$1 nel blog * AWS Open Source*.

Altri strumenti di gestione dei container potrebbero funzionare. Il CDK non verifica quale sostituto di Docker stai utilizzando per determinare se è supportato. Se lo strumento ha comandi Docker equivalenti e si comporta in modo simile, dovrebbe funzionare.

# Risoluzione dei problemi relativi AWS alle implementazioni CDK
<a name="deploy-troubleshoot"></a>

Risolvi i problemi più comuni durante la distribuzione di applicazioni AWS Cloud Development Kit (AWS CDK).

## Al momento dell'implementazione vengono creati principi di servizio errati
<a name="deploy-troubleshoot-sp"></a>

Quando si distribuiscono applicazioni CDK che contengono ruoli AWS Identity and Access Management (IAM) con service principal, si riscontra che vengono creati domini errati per i service principal.

Di seguito è riportato un esempio di base di creazione di un ruolo IAM che può essere assunto da Amazon CloudWatch Logs utilizzando il relativo service principal:

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

Quando si distribuisce questo stack, è `logs.amazonaws.com` necessario creare un service principal denominato. Nella maggior parte dei casi, AWS i servizi utilizzano la seguente denominazione per i principali di servizio:. `<service>.amazonaws.com`

### Cause comuni
<a name="deploy-troubleshoot-sp-causes"></a>

Se utilizzi una versione del AWS CDK precedente alla v2.150.0, potresti riscontrare questo bug. Nelle versioni AWS CDK precedenti, la denominazione dei principali di servizio non era standardizzata, il che poteva portare alla creazione di principali di servizio con domini errati.

In AWS CDK v2.51.0, è stata implementata una correzione standardizzando tutti i principali di servizio creati automaticamente da utilizzare quando possibile. `<service>.amazonaws.com` Questa correzione era disponibile abilitando il flag della funzionalità. `@aws-cdk/aws-iam:standardizedServicePrincipals`

A partire da AWS CDK v2.150.0, questo è diventato il comportamento predefinito.

### Risoluzione
<a name="deploy-troubleshoot-sp-resolution"></a>

Aggiornamento a CDK v2.150.0 o AWS versione successiva.

Se non è possibile eseguire l'aggiornamento a AWS CDK v2.150.0 o versione successiva, è necessario eseguire l'aggiornamento almeno alla versione 2.51.0 o successiva. Quindi, consenti il seguente contrassegno di funzionalità nel tuo file:. `cdk.json` `@aws-cdk/aws-iam:standardizedServicePrincipals`