

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

# Scopri i AWS concetti fondamentali di CDK
<a name="core-concepts"></a>

Scopri i concetti fondamentali alla base del AWS Cloud Development Kit (AWS CDK).

## AWS CDK e IaC
<a name="concepts-iac"></a>

Il AWS CDK è un framework open source che puoi utilizzare per gestire l' AWS infrastruttura tramite codice. Questo approccio è noto come *infrastructure as code (IaC).* Gestendo e fornendo l'infrastruttura come codice, trattate l'infrastruttura nello stesso modo in cui gli sviluppatori trattano il codice. Ciò offre molti vantaggi, come il controllo delle versioni e la scalabilità. Per ulteriori informazioni su IaC, consulta [What is Infrastructure as Code](https://aws.amazon.com/what-is/iac/)? 

## AWS CDK e AWS CloudFormation
<a name="concepts-cfn"></a>

Il AWS CDK è strettamente integrato con. AWS CloudFormation AWS CloudFormation è un servizio completamente gestito che puoi utilizzare per gestire e fornire la tua infrastruttura. AWS Con AWS CloudFormation, definisci la tua infrastruttura in modelli e li distribuisci su AWS CloudFormation. Il AWS CloudFormation servizio effettua quindi il provisioning dell'infrastruttura in base alla configurazione definita nei modelli.

 AWS CloudFormation i modelli sono *dichiarativi*, ossia dichiarano lo stato o il risultato desiderato dell'infrastruttura. **Utilizzando JSON o YAML, dichiarate la vostra AWS infrastruttura definendo risorse e proprietà. AWS ** Le risorse rappresentano i numerosi servizi disponibili AWS e le proprietà rappresentano la configurazione desiderata di tali servizi. Quando si distribuisce il modello su AWS CloudFormation, le risorse e le relative proprietà configurate vengono fornite come descritto nel modello.

Con il AWS CDK, è possibile gestire l'infrastruttura in *modo imperativo*, utilizzando linguaggi di programmazione generici. Invece di limitarsi a definire lo stato desiderato in modo dichiarativo, è possibile definire la logica o la sequenza necessaria per raggiungere lo stato desiderato. Ad esempio, è possibile utilizzare `if` istruzioni o loop condizionali che determinano come raggiungere lo stato finale desiderato per l'infrastruttura.

L'infrastruttura creata con il AWS CDK viene infine tradotta o *sintetizzata* in AWS CloudFormation modelli e distribuita utilizzando il servizio. AWS CloudFormation Quindi, sebbene il AWS CDK offra un approccio diverso alla creazione dell'infrastruttura, ne usufruirete comunque dei vantaggi AWS CloudFormation, come un ampio supporto per la configurazione delle AWS risorse e solidi processi di implementazione.

Per ulteriori informazioni AWS CloudFormation, consulta [What is AWS CloudFormation?](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html) nella *Guida AWS CloudFormation per l'utente*.

## AWS CDK e astrazioni
<a name="concepts-abstractions"></a>

Con AWS CloudFormation, è necessario definire ogni dettaglio della configurazione delle risorse. Ciò offre il vantaggio di avere il controllo completo sull'infrastruttura. Tuttavia, ciò richiede l'apprendimento, la comprensione e la creazione di modelli affidabili che contengano dettagli sulla configurazione delle risorse e le relazioni tra le risorse, come le autorizzazioni e le interazioni basate sugli eventi.

Con il AWS CDK, puoi avere lo stesso controllo sulle configurazioni delle risorse. Tuttavia, il AWS CDK offre anche potenti astrazioni, che possono accelerare e semplificare il processo di sviluppo dell'infrastruttura. Ad esempio, il AWS CDK include costrutti che forniscono configurazioni predefinite ragionevoli e metodi di supporto che generano codice standard per l'utente. Il AWS CDK offre anche strumenti, come l'interfaccia a riga di comando AWS CDK (AWS CDK CLI), che eseguono azioni di gestione dell'infrastruttura per te.

## Scopri di più sui concetti fondamentali di CDK AWS
<a name="concepts-learn"></a><a name="concepts-learn-interact"></a>

 **Interagire con il CDK AWS **   
Quando si utilizza con AWS CDK, si interagirà principalmente con la AWS Construct Library e la AWS CDK CLI.<a name="concepts-learn-develop"></a>

 **Sviluppo con il CDK AWS **   
Il AWS CDK può essere scritto in qualsiasi linguaggio di [programmazione supportato](languages.md). [Si inizia con un [progetto CDK](projects.md), che contiene una struttura di cartelle e file, comprese le risorse.](assets.md) All'interno del progetto, create un'applicazione [CDK.](apps.md) All'interno dell'app, definisci uno [stack](stacks.md), che rappresenta direttamente uno CloudFormation stack. [All'interno dello stack, definisci AWS le tue risorse e proprietà utilizzando costrutti.](constructs.md)<a name="concepts-learn-deploy"></a>

 **Implementazione con CDK AWS **   
[Implementate le app CDK in un ambiente. AWS](environments.md) Prima della distribuzione, è necessario eseguire un [bootstrap](bootstrapping.md) una tantum per preparare l'ambiente.<a name="concepts-learn-more"></a>

 **Ulteriori informazioni**   
Per ulteriori informazioni sui concetti fondamentali di AWS CDK, consultate gli argomenti di questa sezione.

# Linguaggi di programmazione supportati per il AWS CDK
<a name="languages"></a>

Il AWS Cloud Development Kit (AWS CDK) offre un supporto di prima classe per i seguenti linguaggi di programmazione generici:
+ TypeScript
+ JavaScript
+ Python
+ Java
+ C\$1
+  Go 

Altro JVM e .NET CLR i linguaggi possono essere utilizzati anche in teoria, ma al momento non offriamo supporto ufficiale.

Il AWS CDK è sviluppato in una sola lingua, TypeScript. Per supportare le altre lingue, il AWS CDK utilizza uno strumento chiamato [JSII](https://github.com/aws/jsii) per generare associazioni linguistiche.

Cerchiamo di offrire le consuete convenzioni di ogni lingua per rendere lo sviluppo con il AWS CDK il più naturale e intuitivo possibile. Ad esempio, distribuiamo i moduli di AWS Construct Library utilizzando l'archivio standard della lingua preferita e voi li installate utilizzando il gestore di pacchetti standard del linguaggio. I metodi e le proprietà vengono inoltre denominati utilizzando gli schemi di denominazione consigliati nella lingua in uso.

Di seguito sono riportati alcuni esempi di codice:

**Example**  

```
const bucket = new s3.Bucket(this, 'amzn-s3-demo-bucket', {
  bucketName: 'amzn-s3-demo-bucket',
  versioned: true,
  websiteRedirect: {hostName: 'aws.amazon.com'}});
```

```
const bucket = new s3.Bucket(this, 'amzn-s3-demo-bucket', {
  bucketName: 'amzn-s3-demo-bucket',
  versioned: true,
  websiteRedirect: {hostName: 'aws.amazon.com'}});
```

```
bucket = s3.Bucket("amzn-s3-demo-bucket", bucket_name="amzn-s3-demo-bucket", versioned=True,
            website_redirect=s3.RedirectTarget(host_name="aws.amazon.com"))
```

```
Bucket bucket = Bucket.Builder.create(self, "amzn-s3-demo-bucket")
                      .bucketName("amzn-s3-demo-bucket")
                      .versioned(true)
                      .websiteRedirect(new RedirectTarget.Builder()
                          .hostName("aws.amazon.com").build())
                      .build();
```

```
var bucket = new Bucket(this, "amzn-s3-demo-bucket", new BucketProps {
                      BucketName = "amzn-s3-demo-bucket",
                      Versioned  = true,
                      WebsiteRedirect = new RedirectTarget {
                              HostName = "aws.amazon.com"
                      }});
```

```
bucket := awss3.NewBucket(scope, jsii.String("amzn-s3-demo-bucket"), &awss3.BucketProps {
	BucketName: jsii.String("amzn-s3-demo-bucket"),
	Versioned: jsii.Bool(true),
	WebsiteRedirect: &awss3.RedirectTarget {
		HostName: jsii.String("aws.amazon.com"),
	},
})
```

**Nota**  
Questi frammenti di codice sono solo a scopo illustrativo. Sono incompleti e non funzioneranno così come sono.

La AWS Construct Library è distribuita utilizzando gli strumenti di gestione dei pacchetti standard di ogni lingua, tra cui NPM, PyPi, Mavene NuGet. Forniamo anche una versione del [AWS CDK API Reference](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-construct-library.html) per ogni lingua.

Per aiutarti a usare il AWS CDK nella tua lingua preferita, questa guida include i seguenti argomenti per le lingue supportate:
+  [Lavorare con il AWS CDK in TypeScript](work-with-cdk-typescript.md) 
+  [Lavorare con il AWS CDK in JavaScript](work-with-cdk-javascript.md) 
+  [Lavorare con il AWS CDK in Python](work-with-cdk-python.md) 
+  [Lavorare con il AWS CDK in Java](work-with-cdk-java.md) 
+  [Lavorare con il AWS CDK in C\$1](work-with-cdk-csharp.md) 
+  [Lavorare con il AWS CDK in Go](work-with-cdk-go.md) 

TypeScript è stata la prima lingua supportata dal AWS CDK e gran parte del codice di esempio AWS CDK è scritto in. TypeScript Questa guida include un argomento specifico per mostrare come adattare il codice TypeScript AWS CDK per utilizzarlo con gli altri linguaggi supportati. Per ulteriori informazioni, consulta [Confronto tra AWS CDK e altre TypeScript lingue](work-with.md#work-with-cdk-compare).

# Le AWS librerie CDK
<a name="libraries"></a>

Scopri le librerie principali che utilizzerai con il AWS Cloud Development Kit (AWS CDK).

## La libreria AWS CDK
<a name="libraries-cdk"></a>

La libreria AWS CDK, nota anche come`aws-cdk-lib`, è la libreria principale che verrà utilizzata per sviluppare applicazioni con il AWS CDK. È sviluppata e gestita da. AWS Questa libreria contiene classi base, come [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html)e [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html). Contiene anche le librerie che utilizzerai per definire la tua infrastruttura tramite costrutti.

## La libreria AWS Construct
<a name="libraries-construct"></a>

La libreria AWS Construct fa parte della libreria AWS CDK. Contiene una raccolta di [costrutti](constructs.md) sviluppati e gestiti da. AWSÈ organizzato in vari moduli per ogni AWS servizio. Ogni modulo include costrutti che è possibile utilizzare per definire AWS risorse e proprietà.

## La libreria Constructs
<a name="libraries-constructs"></a>

La libreria Constructs, comunemente denominata`constructs`, è una libreria per la definizione e la composizione dei componenti dell'infrastruttura cloud. Contiene la [https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html)classe core, che rappresenta l'elemento costitutivo del construct. Questa classe è la classe base fondamentale di tutti i costrutti della Construct Library. AWS *La libreria Constructs è una libreria generica separata che viene utilizzata da altri strumenti basati su costrutti come *CDK for Terraform e CDK* for Kubernetes.*

## AWS Il riferimento all'API CDK
<a name="libraries-reference"></a>

Il [riferimento all'API AWS CDK](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-construct-library.html) contiene la documentazione di riferimento ufficiale per la libreria AWS CDK, tra cui la libreria AWS Construct Library e la libreria Constructs. Viene fornita una versione del riferimento API per ogni linguaggio di programmazione supportato.
+ Per la documentazione di AWS CDK Library (`aws-cdk-lib`), vedete [aws-cdk-lib module](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib-readme.html).
+ La documentazione per i costrutti nella AWS Construct Library è organizzata per AWS servizio nel seguente formato:. `aws-cdk-lib.<service>` [Ad esempio, la documentazione di costruzione per Amazon Simple Storage Service (Amazon S3) è disponibile nel modulo .aws\$1s3. aws-cdk-lib](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3-readme.html)
+ [Per la documentazione della libreria Constructs (constructs), consulta il modulo constructs.](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs-readme.html)

### Contribuisci al riferimento all'API CDK AWS
<a name="libraries-reference-contribute"></a>

Il AWS CDK è open source e ti invitiamo a contribuire. I contributi della community hanno un impatto positivo e migliorano il CDK. AWS [Per istruzioni su come contribuire in modo specifico alla documentazione di riferimento dell'API AWS CDK, consulta la documentazione in aws-cdk](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md#documentation) * GitHub repository. *

## Ulteriori informazioni
<a name="libraries-learn"></a>

Per istruzioni sull'importazione e l'uso della libreria CDK, consultate [Lavorare con la](work-with.md) libreria CDK.

# AWS Progetti CDK
<a name="projects"></a>

Un progetto AWS Cloud Development Kit (AWS CDK) rappresenta i file e le cartelle che contengono il codice CDK. I contenuti varieranno in base al linguaggio di programmazione.

È possibile creare il progetto AWS CDK manualmente o con il comando AWS CDK Command Line Interface (AWS CDK CLI). `cdk init` In questo argomento, faremo riferimento alla struttura del progetto e alle convenzioni di denominazione di file e cartelle create dalla CLI AWS CDK. Puoi personalizzare e organizzare i tuoi progetti CDK in base alle tue esigenze.

**Nota**  
La struttura del progetto creata dalla CLI AWS CDK può variare tra le versioni nel tempo.

## File e cartelle universali
<a name="projects-universal"></a><a name="projects-universal-git"></a>

 `.git`   
Se è `git` stato installato, la CLI AWS CDK inizializza automaticamente un Git repository per il tuo progetto. La `.git` directory contiene informazioni sul repository.<a name="projects-universal-gitignore"></a>

 `.gitignore`   
File di testo utilizzato da Git per specificare file e cartelle da ignorare.<a name="projects-universal-readme"></a>

 `README.md`   
File di testo che fornisce linee guida di base e informazioni importanti per la gestione del progetto AWS CDK. Modificate questo file se necessario per documentare informazioni importanti relative al progetto CDK.<a name="projects-universal-cdk"></a>

 `cdk.json`   
File di configurazione per il AWS CDK. Questo file fornisce istruzioni alla CLI AWS CDK su come eseguire l'app.

## File e cartelle specifici della lingua
<a name="projects-specific"></a>

I file e le cartelle seguenti sono unici per ogni linguaggio di programmazione supportato.

**Example**  
Di seguito è riportato un esempio di progetto creato nella `my-cdk-ts-project` directory utilizzando il `cdk init --language typescript` comando:  

```
my-cdk-ts-project
├── .git
├── .gitignore
├── .npmignore
├── README.md
├── bin
│   └── my-cdk-ts-project.ts
├── cdk.json
├── jest.config.js
├── lib
│   └── my-cdk-ts-project-stack.ts
├── node_modules
├── package-lock.json
├── package.json
├── test
│   └── my-cdk-ts-project.test.ts
└── tsconfig.json
```  
 `.npmignore`   
File che specifica quali file e cartelle ignorare durante la pubblicazione di un pacchetto nel `npm` registro. Questo file è simile a`.gitignore`, ma è specifico per `npm` i pacchetti.  
 `bin/my-cdk-ts-project.ts`   
Il *file dell'applicazione* definisce l'app CDK. I progetti CDK possono contenere uno o più file di applicazione. I file dell'applicazione vengono memorizzati nella `bin` cartella.  
Di seguito è riportato un esempio di file applicativo di base che definisce un'app CDK:  

```
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { MyCdkTsProjectStack } from '../lib/my-cdk-ts-project-stack';

const app = new cdk.App();
new MyCdkTsProjectStack(app, 'MyCdkTsProjectStack');
```  
 `jest.config.js`   
File di configurazione per Jest. *Jest* è un popolare framework JavaScript di test.  
 `lib/my-cdk-ts-project-stack.ts`   
Il *file stack* definisce lo stack CDK. All'interno dello stack, definisci AWS risorse e proprietà utilizzando costrutti.  
Di seguito è riportato un esempio di file stack di base che definisce uno stack CDK:  

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

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

  // code that defines your resources and properties go here
 }
}
```  
 `node_modules`   
Cartella comune in Node.js progetti che contengono dipendenze per il tuo progetto.  
 `package-lock.json`   
File di metadati che funziona con il `package.json` file per gestire le versioni delle dipendenze.  
 `package.json`   
File di metadati comunemente utilizzato in Node.js progetti. Questo file contiene informazioni sul progetto CDK come il nome del progetto, le definizioni degli script, le dipendenze e altre informazioni a livello di progetto di importazione.  
 `test/my-cdk-ts-project.test.ts`   
Viene creata una cartella di test per organizzare i test per il progetto CDK. Viene inoltre creato un file di test di esempio.  
È possibile scrivere test TypeScript e utilizzarli Jest per compilare il TypeScript codice prima di eseguire i test.  
 `tsconfig.json`   
File di configurazione utilizzato nei TypeScript progetti che specifica le opzioni del compilatore e le impostazioni del progetto.
Di seguito è riportato un esempio di progetto creato nella `my-cdk-js-project` directory utilizzando il `cdk init --language javascript` comando:  

```
my-cdk-js-project
├── .git
├── .gitignore
├── .npmignore
├── README.md
├── bin
│   └── my-cdk-js-project.js
├── cdk.json
├── jest.config.js
├── lib
│   └── my-cdk-js-project-stack.js
├── node_modules
├── package-lock.json
├── package.json
└── test
    └── my-cdk-js-project.test.js
```  
 `.npmignore`   
File che specifica quali file e cartelle ignorare durante la pubblicazione di un pacchetto nel `npm` registro. Questo file è simile a`.gitignore`, ma è specifico per `npm` i pacchetti.  
 `bin/my-cdk-js-project.js`   
Il *file dell'applicazione* definisce l'app CDK. I progetti CDK possono contenere uno o più file di applicazione. I file dell'applicazione vengono memorizzati nella `bin` cartella.  
Di seguito è riportato un esempio di file applicativo di base che definisce un'app CDK:  

```
#!/usr/bin/env node

const cdk = require('aws-cdk-lib');
const { MyCdkJsProjectStack } = require('../lib/my-cdk-js-project-stack');

const app = new cdk.App();
new MyCdkJsProjectStack(app, 'MyCdkJsProjectStack');
```  
 `jest.config.js`   
File di configurazione per Jest. *Jest* è un popolare framework JavaScript di test.  
 `lib/my-cdk-js-project-stack.js`   
Il *file stack* definisce lo stack CDK. All'interno dello stack, definisci AWS risorse e proprietà utilizzando costrutti.  
Di seguito è riportato un esempio di file stack di base che definisce uno stack CDK:  

```
const { Stack, Duration } = require('aws-cdk-lib');

class MyCdkJsProjectStack extends Stack {
 constructor(scope, id, props) {
  super(scope, id, props);

  // code that defines your resources and properties go here
 }
}

module.exports = { MyCdkJsProjectStack }
```  
 `node_modules`   
Cartella comune in Node.js progetti che contengono dipendenze per il tuo progetto.  
 `package-lock.json`   
File di metadati che funziona con il `package.json` file per gestire le versioni delle dipendenze.  
 `package.json`   
File di metadati comunemente utilizzato in Node.js progetti. Questo file contiene informazioni sul progetto CDK come il nome del progetto, le definizioni degli script, le dipendenze e altre informazioni a livello di progetto di importazione.  
 `test/my-cdk-js-project.test.js`   
Viene creata una cartella di test per organizzare i test per il progetto CDK. Viene inoltre creato un file di test di esempio.  
È possibile scrivere test JavaScript e utilizzarli Jest per compilare il JavaScript codice prima di eseguire i test.
Di seguito è riportato un esempio di progetto creato nella `my-cdk-py-project` directory utilizzando il `cdk init --language python` comando:  

```
my-cdk-py-project
├── .git
├── .gitignore
├── .venv
├── README.md
├── app.py
├── cdk.json
├── my_cdk_py_project
│   ├── __init__.py
│   └── my_cdk_py_project_stack.py
├── requirements-dev.txt
├── requirements.txt
├── source.bat
└── tests
    ├── __init__.py
    └── unit
```  
 `.venv`   
La CLI CDK crea automaticamente un ambiente virtuale per il tuo progetto. La `.venv` directory si riferisce a questo ambiente virtuale.  
 `app.py`   
Il *file dell'applicazione* definisce l'app CDK. I progetti CDK possono contenere uno o più file di applicazione.  
Di seguito è riportato un esempio di file applicativo di base che definisce un'app CDK:  

```
#!/usr/bin/env python3
import os

import aws_cdk as cdk

from my_cdk_py_project.my_cdk_py_project_stack import MyCdkPyProjectStack

app = cdk.App()
MyCdkPyProjectStack(app, "MyCdkPyProjectStack")

app.synth()
```  
 `my_cdk_py_project`   
Directory che contiene i file *dello stack*. La CLI CDK crea quanto segue qui:  
+ \$1\$1init\$1\$1.py — Un file di definizione del pacchetto Python vuoto.
+  `my_cdk_py_project`— File che definisce lo stack CDK. Quindi definisci AWS le risorse e le proprietà all'interno dello stack utilizzando i costrutti.
Di seguito è riportato un esempio di file stack:  

```
from aws_cdk import Stack

from constructs import Construct

class MyCdkPyProjectStack(Stack):
 def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
  super().__init__(scope, construct_id, **kwargs)

  # code that defines your resources and properties go here
```  
 `requirements-dev.txt`   
File simile a`requirements.txt`, ma utilizzato per gestire le dipendenze specificamente per scopi di sviluppo piuttosto che di produzione.  
 `requirements.txt`   
File comune utilizzato nei progetti Python per specificare e gestire le dipendenze del progetto.  
 `source.bat`   
File Batch per Windows che viene utilizzato per configurare l'ambiente virtuale Python.  
 `tests`   
Directory che contiene i test per il progetto CDK.  
Di seguito è riportato un esempio di test unitario:  

```
import aws_cdk as core
import aws_cdk.assertions as assertions

from my_cdk_py_project.my_cdk_py_project_stack import MyCdkPyProjectStack

def test_sqs_queue_created():
 app = core.App()
 stack = MyCdkPyProjectStack(app, "my-cdk-py-project")
 template = assertions.Template.from_stack(stack)

 template.has_resource_properties("AWS::SQS::Queue", {
  "VisibilityTimeout": 300
 })
```
Di seguito è riportato un esempio di progetto creato nella `my-cdk-java-project` directory utilizzando il `cdk init --language java` comando:  

```
my-cdk-java-project
├── .git
├── .gitignore
├── README.md
├── cdk.json
├── pom.xml
└── src
    ├── main
    └── test
```  
 `pom.xml`   
File che contiene informazioni di configurazione e metadati relativi al progetto CDK. Questo file fa parte di Maven.  
 `src/main`   
Directory contenente i file *dell'applicazione* e *dello stack*.  
Di seguito è riportato un esempio di file di applicazione:  

```
package com.myorg;

import software.amazon.awscdk.App;
import software.amazon.awscdk.Environment;
import software.amazon.awscdk.StackProps;

import java.util.Arrays;

public class MyCdkJavaProjectApp {
 public static void main(final String[] args) {
  App app = new App();

  new MyCdkJavaProjectStack(app, "MyCdkJavaProjectStack", StackProps.builder()
   .build());

  app.synth();
 }
}
```
Di seguito è riportato un esempio di file stack:  

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;

public class MyCdkJavaProjectStack extends Stack {
 public MyCdkJavaProjectStack(final Construct scope, final String id) {
  this(scope, id, null);
 }

 public MyCdkJavaProjectStack(final Construct scope, final String id, final StackProps props) {
  super(scope, id, props);

  // code that defines your resources and properties go here
 }
}
```  
 `src/test`   
Directory contenente i file di test. Di seguito è riportato un esempio:  

```
package com.myorg;

import software.amazon.awscdk.App;
import software.amazon.awscdk.assertions.Template;
import java.io.IOException;

import java.util.HashMap;

import org.junit.jupiter.api.Test;

public class MyCdkJavaProjectTest {

 @Test
 public void testStack() throws IOException {
  App app = new App();
  MyCdkJavaProjectStack stack = new MyCdkJavaProjectStack(app, "test");

  Template template = Template.fromStack(stack);

  template.hasResourceProperties("AWS::SQS::Queue", new HashMap<String, Number>() {{
   put("VisibilityTimeout", 300);
  }});
 }
}
```
Di seguito è riportato un esempio di progetto creato nella `my-cdk-csharp-project` directory utilizzando il `cdk init --language csharp` comando:  

```
my-cdk-csharp-project
├── .git
├── .gitignore
├── README.md
├── cdk.json
└── src
    ├── MyCdkCsharpProject
    └── MyCdkCsharpProject.sln
```  
 `src/MyCdkCsharpProject`   
Directory contenente i file *dell'applicazione* e *dello stack*.  
Di seguito è riportato un esempio di file di applicazione:  

```
using Amazon.CDK;
using System;
using System.Collections.Generic;
using System.Linq;

namespace MyCdkCsharpProject
{
 sealed class Program
 {
  public static void Main(string[] args)
  {
   var app = new App();
   new MyCdkCsharpProjectStack(app, "MyCdkCsharpProjectStack", new StackProps{});
   app.Synth();
  }
 }
}
```
Di seguito è riportato un esempio di file stack:  

```
using Amazon.CDK;
using Constructs;

namespace MyCdkCsharpProject
{
 public class MyCdkCsharpProjectStack : Stack
 {
  internal MyCdkCsharpProjectStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
  {
   // code that defines your resources and properties go here
  }
 }
}
```
Questa directory contiene anche quanto segue:  
  
+  `GlobalSuppressions.cs`— File utilizzato per sopprimere avvisi o errori specifici del compilatore in tutto il progetto.
+  `.csproj`— File basato su XML utilizzato per definire le impostazioni del progetto, le dipendenze e creare configurazioni. ---  
 `src/MyCdkCsharpProject.sln`   
 Microsoft Visual Studio Solution File utilizzato per organizzare e gestire progetti correlati.
Di seguito è riportato un esempio di progetto creato nella `my-cdk-go-project` directory utilizzando il `cdk init --language go` comando:  

```
my-cdk-go-project
├── .git
├── .gitignore
├── README.md
├── cdk.json
├── go.mod
├── my-cdk-go-project.go
└── my-cdk-go-project_test.go
```  
 `go.mod`   
File che contiene informazioni sul modulo e viene utilizzato per gestire le dipendenze e il controllo delle versioni per Go progetto.  
 `my-cdk-go-project.go`   
File che definisce l'applicazione e gli stack CDK.  
Di seguito è riportato un esempio:  

```
package main
import (
 "github.com/aws/aws-cdk-go/awscdk/v2"
 "github.com/aws/constructs-go/constructs/v10"
 "github.com/aws/jsii-runtime-go"
)

type MyCdkGoProjectStackProps struct {
 awscdk.StackProps
}

func NewMyCdkGoProjectStack(scope constructs.Construct, id string, props *MyCdkGoProjectStackProps) awscdk.Stack {
 var sprops awscdk.StackProps
 if props != nil {
  sprops = props.StackProps
 }
 stack := awscdk.NewStack(scope, &id, &sprops)
 // The code that defines your resources and properties go here

  return stack
}

func main() {
 defer jsii.Close()
 app := awscdk.NewApp(nil)
 NewMyCdkGoProjectStack(app, "MyCdkGoProjectStack", &MyCdkGoProjectStackProps{
  awscdk.StackProps{
   Env: env(),
  },
 })
 app.Synth(nil)
}

func env() *awscdk.Environment {

 return nil
}
```  
 `my-cdk-go-project_test.go`   
File che definisce un test di esempio.  
Di seguito è riportato un esempio:  

```
package main

import (
 "testing"

 "github.com/aws/aws-cdk-go/awscdk/v2"
 "github.com/aws/aws-cdk-go/awscdk/v2/assertions"
 "github.com/aws/jsii-runtime-go"
)

func TestMyCdkGoProjectStack(t *testing.T) {

 // GIVEN
 app := awscdk.NewApp(nil)

 // WHEN
 stack := NewMyCdkGoProjectStack(app, "MyStack", nil)

 // THEN
 template := assertions.Template_FromStack(stack, nil)
 template.HasResourceProperties(jsii.String("AWS::SQS::Queue"), map[string]interface{}{
  "VisibilityTimeout": 300,
 })
}
```

# AWS App CDK
<a name="apps"></a>

[L'applicazione o l'*app AWS * Cloud Development Kit (AWS CDK) è una raccolta di uno o più stack CDK.](stacks.md) Gli stack sono una raccolta di uno o più [costrutti](constructs.md), che definiscono risorse e proprietà. AWS Pertanto, il raggruppamento complessivo degli stack e dei costrutti è noto come app CDK.

## Come creare un'app CDK
<a name="apps-define"></a>

Crei un'app definendo un'istanza dell'app nel file dell'applicazione del tuo [progetto](projects.md). A tale scopo, importate e utilizzate il costrutto [App](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html) dalla AWS Construct Library. Il `App` costrutto non richiede alcun argomento di inizializzazione. È l'unico costrutto che può essere usato come radice.

Le ` [Stack](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html) ` classi ` [App](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html) ` e della AWS Construct Library sono costrutti unici. Rispetto ad altri costrutti, non configurano AWS le risorse da soli. Vengono invece utilizzati per fornire un contesto agli altri costrutti. Tutti i costrutti che rappresentano AWS risorse devono essere definiti, direttamente o indirettamente, nell'ambito di un costrutto. `Stack` `Stack`i costrutti sono definiti nell'ambito di un costrutto. `App`

Le app vengono quindi sintetizzate per creare AWS CloudFormation modelli per gli stack. Di seguito è riportato un esempio:

**Example**  

```
const app = new App();
new MyFirstStack(app, 'hello-cdk');
app.synth();
```

```
const app = new App();
new MyFirstStack(app, 'hello-cdk');
app.synth();
```

```
app = App()
MyFirstStack(app, "hello-cdk")
app.synth()
```

```
App app = new App();
new MyFirstStack(app, "hello-cdk");
app.synth();
```

```
var app = new App();
new MyFirstStack(app, "hello-cdk");
app.Synth();
```

```
app := awscdk.NewApp(nil)

MyFirstStack(app, "MyFirstStack", &MyFirstStackProps{
  awscdk.StackProps{
    Env: env(),
  },
})

app.Synth(nil)
```

Gli stack all'interno di una singola app possono facilmente fare riferimento alle risorse e alle proprietà reciproche. Il AWS CDK deduce le dipendenze tra gli stack in modo che possano essere distribuiti nell'ordine corretto. Puoi distribuire uno o tutti gli stack all'interno di un'app con un solo comando. `cdk deploy`

## L'albero di costruzione
<a name="apps-tree"></a>

I costrutti vengono definiti all'interno di altri costrutti utilizzando l'`scope`argomento passato a ogni costrutto, con la `App` classe come radice. *In questo modo, un'app AWS CDK definisce una gerarchia di costrutti nota come albero dei costrutti.*

La radice di questo albero è la tua app, che è un'istanza della classe. `App` All'interno dell'app, crei un'istanza di uno o più stack. All'interno degli stack, si creano delle istanze di costrutti, che possono a loro volta creare istanze di risorse o altri costrutti, e così via lungo l'albero.

I costrutti sono *sempre* definiti esplicitamente nell'ambito di un altro costrutto, che crea relazioni tra i costrutti. Quasi sempre, dovresti passare `this` (in Python,`self`) come ambito, indicando che il nuovo costrutto è figlio del costrutto corrente. Lo schema previsto è quello da cui si ricava il costrutto [https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html), quindi si istanziano i costrutti che utilizza nel suo costruttore.

[Il passaggio esplicito dell'ambito consente a ciascun costrutto di aggiungersi all'albero, con questo comportamento interamente contenuto nella classe base. `Construct`](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html) Funziona allo stesso modo in tutte le lingue supportate dal AWS CDK e non richiede personalizzazioni aggiuntive.

**Importante**  
Tecnicamente, è possibile passare a un ambito diverso da `this` quando si istanzia un costrutto. Puoi aggiungere costrutti ovunque nell'albero o anche in un altro stack nella stessa app. Ad esempio, potete scrivere una funzione in stile mixin che aggiunga costrutti a un ambito passato come argomento. La difficoltà pratica qui è che non potete facilmente assicurarvi che i costrutti che IDs scegliete per i vostri costrutti siano unici nell'ambito di qualcun altro. Questa pratica rende inoltre il codice più difficile da comprendere, gestire e riutilizzare. Pertanto, si consiglia di utilizzare la struttura generale dell'albero di costruzione.

Il AWS CDK utilizza tutti i costrutti presenti nel percorso dalla radice dell'albero a ogni costrutto figlio per generare l'univoco richiesto da. IDs IDs AWS CloudFormation Questo approccio significa che i costrutti devono essere unici IDs solo all'interno del loro ambito, anziché all'interno dell'intero stack come in nativo. AWS CloudFormation Tuttavia, se spostate un costrutto in un ambito diverso, l'ID univoco dello stack generato cambia e AWS CloudFormation non lo considererà la stessa risorsa.

L'albero di costruzione è separato dai costrutti definiti nel codice CDK. AWS Tuttavia, è accessibile tramite l'`node`attributo di qualsiasi costrutto, che è un riferimento al nodo che rappresenta quel costrutto nell'albero. Ogni nodo è un'[https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Node.html](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Node.html)istanza, i cui attributi forniscono l'accesso alla radice dell'albero e agli ambiti principali e secondari del nodo.

1.  `node.children`— I figli diretti del costrutto.

1.  `node.id`— L'identificatore del costrutto all'interno del suo ambito.

1.  `node.path`— Il percorso completo del costrutto, compresi quelli IDs di tutti i suoi genitori.

1.  `node.root`— La radice dell'albero di costruzione (l'app).

1.  `node.scope`— L'ambito (genitore) del costrutto o non definito se il nodo è la radice.

1.  `node.scopes`— Tutti i genitori del costrutto, fino alla radice.

1.  `node.uniqueId`— L'identificatore alfanumerico univoco per questo costrutto all'interno dell'albero (per impostazione predefinita, generato da `node.path` e un hash).

L'albero dei costrutti definisce un ordine implicito in cui i costrutti vengono sintetizzati nelle risorse del modello finale. AWS CloudFormation Dove una risorsa deve essere creata prima di un'altra, AWS CloudFormation oppure la AWS Construct Library generalmente deduce la dipendenza. Quindi si assicurano che le risorse vengano create nell'ordine giusto.

È inoltre possibile aggiungere una dipendenza esplicita tra due nodi utilizzando. `node.addDependency()` Per ulteriori informazioni, consulta [Dipendenze](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib-readme.html#dependencies) nel * AWS CDK* API Reference.

Il AWS CDK offre un modo semplice per visitare ogni nodo dell'albero di costruzione ed eseguire un'operazione su ciascuno di essi. Per ulteriori informazioni, consulta [Aspects and the AWS CDK](aspects.md).

# Introduzione agli stack AWS CDK
<a name="stacks"></a>

Uno stack AWS CDK è la singola unità di distribuzione più piccola. Rappresenta una raccolta di AWS risorse che definisci utilizzando costrutti CDK. Quando si distribuiscono app CDK, le risorse all'interno di uno stack CDK vengono distribuite insieme come uno stack. AWS CloudFormation *Per ulteriori informazioni sugli AWS CloudFormation stack, consulta [Gestire AWS le risorse come una singola unità](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacks.html) con gli stack nella Guida per l'utente. AWS CloudFormation AWS CloudFormation *

È possibile definire uno stack estendendo o ereditando dal costrutto. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html) *L'esempio seguente è un modello comune per definire uno stack CDK su un file separato, noto come file stack.* Qui, estendiamo o ereditiamo la `Stack` classe e definiamo un costruttore che accetta, e. `scope` `id` `props` Quindi, invochiamo il costruttore della `Stack` classe base utilizzando `super` con il file ricevuto`scope`, e: `id` `props`

**Example**  

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

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

    // Define your constructs here

  }
}
```

```
const { Stack } = require('aws-cdk-lib');

class MyCdkStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define your constructs here

  }
}

module.exports = { MyCdkStack }
```

```
from aws_cdk import (
  Stack,
)
from constructs import Construct

class MyCdkStack(Stack):

  def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
    super().__init__(scope, construct_id, **kwargs)

    # Define your constructs here
```

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;

public class MyCdkStack extends Stack {
  public MyCdkStack(final Construct scope, final String id) {
    this(scope, id, null);
  }

  public MyCdkStack(final Construct scope, final String id, final StackProps props) {
    super(scope, id, props);

    // Define your constructs here
  }
}
```

```
using Amazon.CDK;
using Constructs;

namespace MyCdk
{
  public class MyCdkStack : Stack
  {
    internal MyCdkStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
    {
      // Define your constructs here
    }
  }
}
```

```
package main

import (
	"github.com/aws/aws-cdk-go/awscdk/v2"
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
)

type CdkDemoAppStackProps struct {
	awscdk.StackProps
}

func NewCdkDemoAppStack(scope constructs.Construct, id string, props *CdkDemoAppStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	// The code that defines your stack goes here

	return stack
}

func main() {
	defer jsii.Close()

	app := awscdk.NewApp(nil)

	NewCdkDemoAppStack(app, "CdkDemoAppStack", &CdkDemoAppStackProps{
		awscdk.StackProps{
			Env: env(),
		},
	})

	app.Synth(nil)
}

//...
```

L'esempio precedente ha definito solo uno stack. Per creare lo stack, è necessario crearne un'istanza nel contesto dell'app CDK. *Uno schema comune consiste nel definire l'app CDK e inizializzare lo stack su un file separato, noto come file dell'applicazione.*

Di seguito è riportato un esempio che crea uno stack CDK denominato. `MyCdkStack` Qui, l'app CDK viene creata e `MyCdkStack` viene istanziata nel contesto dell'app:

**Example**  

```
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { MyCdkStack } from '../lib/my-cdk-stack';

const app = new cdk.App();
new MyCdkStack(app, 'MyCdkStack', {
});
```

```
#!/usr/bin/env node

const cdk = require('aws-cdk-lib');
const { MyCdkStack } = require('../lib/my-cdk-stack');

const app = new cdk.App();
new MyCdkStack(app, 'MyCdkStack', {
});
```
Situata in: `app.py`  

```
#!/usr/bin/env python3
import os

import aws_cdk as cdk

from my_cdk.my_cdk_stack import MyCdkStack


app = cdk.App()
MyCdkStack(app, "MyCdkStack",)

app.synth()
```

```
package com.myorg;

import software.amazon.awscdk.App;
import software.amazon.awscdk.Environment;
import software.amazon.awscdk.StackProps;

import java.util.Arrays;

public class MyCdkApp {
  public static void main(final String[] args) {
    App app = new App();

    new MyCdkStack(app, "MyCdkStack", StackProps.builder()
      .build());

    app.synth();
  }
}
```

```
using Amazon.CDK;
using System;
using System.Collections.Generic;
using System.Linq;

namespace MyCdk
{
  sealed class Program
  {
    public static void Main(string[] args)
    {
      var app = new App();
      new MyCdkStack(app, "MyCdkStack", new StackProps
      {});
      app.Synth();
    }
  }
}
```

```
package main

import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/constructs-go/constructs/v10"
  "github.com/aws/jsii-runtime-go"
)

// ...

func main() {
  defer jsii.Close()

  app := awscdk.NewApp(nil)

  NewMyCdkStack(app, "MyCdkStack", &MyCdkStackProps{
    awscdk.StackProps{
      Env: env(),
    },
  })

  app.Synth(nil)
}

// ...
```

L'esempio seguente crea un'app CDK che contiene due stack:

**Example**  

```
const app = new App();

new MyFirstStack(app, 'stack1');
new MySecondStack(app, 'stack2');

app.synth();
```

```
const app = new App();

new MyFirstStack(app, 'stack1');
new MySecondStack(app, 'stack2');

app.synth();
```

```
app = App()

MyFirstStack(app, 'stack1')
MySecondStack(app, 'stack2')

app.synth()
```

```
App app = new App();

new MyFirstStack(app, "stack1");
new MySecondStack(app, "stack2");

app.synth();
```

```
var app = new App();

new MyFirstStack(app, "stack1");
new MySecondStack(app, "stack2");

app.Synth();
```

```
package main

import (
	"github.com/aws/aws-cdk-go/awscdk/v2"
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
)

type MyFirstStackProps struct {
	awscdk.StackProps
}

func NewMyFirstStack(scope constructs.Construct, id string, props *MyFirstStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	myFirstStack := awscdk.NewStack(scope, &id, &sprops)

	// The code that defines your stack goes here

	return myFirstStack
}

type MySecondStackProps struct {
	awscdk.StackProps
}

func NewMySecondStack(scope constructs.Construct, id string, props *MySecondStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	mySecondStack := awscdk.NewStack(scope, &id, &sprops)

	// The code that defines your stack goes here

	return mySecondStack
}

func main() {
	defer jsii.Close()

	app := awscdk.NewApp(nil)

	NewMyFirstStack(app, "MyFirstStack", &MyFirstStackProps{
		awscdk.StackProps{
			Env: env(),
		},
	})

	NewMySecondStack(app, "MySecondStack", &MySecondStackProps{
		awscdk.StackProps{
			Env: env(),
		},
	})

	app.Synth(nil)
}

// ...
```

## Informazioni sull'API dello stack
<a name="stack-api"></a>

L'[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html)oggetto fornisce un'API ricca, che include quanto segue:
+  `Stack.of(construct)`— Un metodo statico che restituisce lo **Stack** in cui è definito un costrutto. Ciò è utile se è necessario interagire con uno stack dall'interno di un costrutto riutilizzabile. La chiamata fallisce se non è possibile trovare uno stack nell'ambito.
+  `stack.stackName`(Python:`stack_name`) — Restituisce il nome fisico dello stack. Come accennato in precedenza, tutti gli stack AWS CDK hanno un nome fisico che il AWS CDK può risolvere durante la sintesi.
+  `stack.region`e `stack.account` — Restituisce rispettivamente la AWS regione e l'account in cui verrà distribuito questo stack. Queste proprietà restituiscono una delle seguenti:
  + L'account o la regione specificati esplicitamente al momento della definizione dello stack
  + Un token con codifica a stringa che si risolve negli AWS CloudFormation pseudo parametri per account e regione per indicare che questo stack è indipendente dall'ambiente

    [Per informazioni su come vengono determinati gli ambienti per gli stack, consulta Environments for the CDK. AWS](environments.md)
+  `stack.addDependency(stack)`(Python:`stack.add_dependency(stack)`) — Può essere usato per definire in modo esplicito l'ordine di dipendenza tra due pile. Questo ordine viene rispettato dal `cdk deploy` comando quando si distribuiscono più stack contemporaneamente.
+  `stack.tags`— Restituisce un tag [TagManager](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.TagManager.html)che è possibile utilizzare per aggiungere o rimuovere tag a livello di stack. Questo gestore di tag tagga tutte le risorse all'interno dello stack e tagga anche lo stack stesso quando viene creato. AWS CloudFormation
+  `stack.partition`, `stack.urlSuffix` (Python:`url_suffix`), (`stack.stackId`Python:) e (`stack.notificationArn`Python: `stack_id``notification_arn`) — Restituiscono token che si risolvono nei rispettivi pseudo parametri, ad esempio. AWS CloudFormation `{ "Ref": "AWS::Partition" }` Questi token sono associati all'oggetto stack specifico in modo che il framework CDK possa identificare i riferimenti cross-stack. AWS 
+  `stack.availabilityZones`(Python:`availability_zones`) — Restituisce l'insieme di zone di disponibilità disponibili nell'ambiente in cui viene distribuito questo stack. Per gli stack indipendenti dall'ambiente, questo restituisce sempre un array con due zone di disponibilità. Per gli stack specifici dell'ambiente, il AWS CDK interroga l'ambiente e restituisce l'esatto set di zone di disponibilità disponibili nella regione specificata.
+  `stack.parseArn(arn)`and `stack.formatArn(comps)` (Python:`parse_arn`,`format_arn`) — Può essere usato per lavorare con Amazon Resource Names ()ARNs.
+  `stack.toJsonString(obj)`(Python:`to_json_string`) — Può essere usato per formattare un oggetto arbitrario come stringa JSON che può essere incorporata in un modello. AWS CloudFormation L'oggetto può includere token, attributi e riferimenti, che vengono risolti solo durante la distribuzione.
+  `stack.templateOptions`(Python:`template_options`) — Utilizzalo per specificare le opzioni del AWS CloudFormation modello, come Transform, Description e Metadata, per il tuo stack.

## Utilizzo degli stack di
<a name="stacks-work"></a>

[Gli stack vengono distribuiti come stack in un AWS CloudFormation ambiente. AWS](environments.md) L'ambiente copre un AWS account e una regione specifici. AWS 

Quando si esegue il `cdk synth` comando per un'app con più stack, l'assembly cloud include un modello separato per ogni istanza dello stack. Anche se i due stack sono istanze della stessa classe, il AWS CDK li emette come due modelli singoli.

È possibile sintetizzare ogni modello specificando il nome dello stack nel comando. `cdk synth` L'esempio seguente sintetizza il modello per: `stack1`

```
$ cdk synth <stack1>
```

[Questo approccio è concettualmente diverso dal modo in cui vengono normalmente utilizzati i AWS CloudFormation modelli, in cui un modello può essere distribuito più volte e parametrizzato tramite parametri.AWS CloudFormation ](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html) Sebbene AWS CloudFormation i parametri possano essere definiti nel AWS CDK, in genere sono sconsigliati perché i parametri vengono risolti solo durante la distribuzione. AWS CloudFormation Ciò significa che non è possibile determinarne il valore nel codice.

Ad esempio, per includere in modo condizionale una risorsa nell'app in base al valore di un parametro, è necessario impostare una [AWS CloudFormation condizione](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/conditions-section-structure.html) e contrassegnare la risorsa con essa. Il AWS CDK adotta un approccio in cui i modelli concreti vengono risolti in fase di sintesi. Pertanto, è possibile utilizzare un'`if`istruzione per verificare il valore e determinare se è necessario definire una risorsa o applicare un comportamento.

**Nota**  
Il AWS CDK fornisce la massima risoluzione possibile durante il periodo di sintesi per consentire l'uso idiomatico e naturale del linguaggio di programmazione.

Come qualsiasi altro costrutto, gli stack possono essere composti insieme in gruppi. Il codice seguente mostra un esempio di servizio composto da tre stack: un piano di controllo, un piano dati e stack di monitoraggio. Il costrutto del servizio viene definito due volte: una volta per l'ambiente beta e una volta per l'ambiente di produzione.

**Example**  

```
import { App, Stack } from 'aws-cdk-lib';
import { Construct } from 'constructs';

interface EnvProps {
  prod: boolean;
}

// imagine these stacks declare a bunch of related resources
class ControlPlane extends Stack {}
class DataPlane extends Stack {}
class Monitoring extends Stack {}

class MyService extends Construct {

  constructor(scope: Construct, id: string, props?: EnvProps) {

    super(scope, id);

    // we might use the prod argument to change how the service is configured
    new ControlPlane(this, "cp");
    new DataPlane(this, "data");
    new Monitoring(this, "mon");  }
}

const app = new App();
new MyService(app, "beta");
new MyService(app, "prod", { prod: true });

app.synth();
```

```
const { App, Stack } = require('aws-cdk-lib');
const { Construct } = require('constructs');

// imagine these stacks declare a bunch of related resources
class ControlPlane extends Stack {}
class DataPlane extends Stack {}
class Monitoring extends Stack {}

class MyService extends Construct {

  constructor(scope, id, props) {

    super(scope, id);

    // we might use the prod argument to change how the service is configured
    new ControlPlane(this, "cp");
    new DataPlane(this, "data");
    new Monitoring(this, "mon");
  }
}

const app = new App();
new MyService(app, "beta");
new MyService(app, "prod", { prod: true });

app.synth();
```

```
from aws_cdk import App, Stack
from constructs import Construct

# imagine these stacks declare a bunch of related resources
class ControlPlane(Stack): pass
class DataPlane(Stack): pass
class Monitoring(Stack): pass

class MyService(Construct):

  def __init__(self, scope: Construct, id: str, *, prod=False):

    super().__init__(scope, id)

    # we might use the prod argument to change how the service is configured
    ControlPlane(self, "cp")
    DataPlane(self, "data")
    Monitoring(self, "mon")

app = App();
MyService(app, "beta")
MyService(app, "prod", prod=True)

app.synth()
```

```
package com.myorg;

import software.amazon.awscdk.App;
import software.amazon.awscdk.Stack;
import software.constructs.Construct;

public class MyApp {

    // imagine these stacks declare a bunch of related resources
    static class ControlPlane extends Stack {
        ControlPlane(Construct scope, String id) {
            super(scope, id);
        }
    }

    static class DataPlane extends Stack {
        DataPlane(Construct scope, String id) {
            super(scope, id);
        }
    }

    static class Monitoring extends Stack {
        Monitoring(Construct scope, String id) {
            super(scope, id);
        }
    }

    static class MyService extends Construct {
        MyService(Construct scope, String id) {
            this(scope, id, false);
        }

        MyService(Construct scope, String id, boolean prod) {
            super(scope, id);

            // we might use the prod argument to change how the service is configured
            new ControlPlane(this, "cp");
            new DataPlane(this, "data");
            new Monitoring(this, "mon");
        }
    }

    public static void main(final String argv[]) {
        App app = new App();

        new MyService(app, "beta");
        new MyService(app, "prod", true);

        app.synth();
    }
}
```

```
using Amazon.CDK;
using Constructs;

// imagine these stacks declare a bunch of related resources
public class ControlPlane : Stack {
    public ControlPlane(Construct scope, string id=null) : base(scope, id) { }
}

public class DataPlane : Stack {
    public DataPlane(Construct scope, string id=null) : base(scope, id) { }
}

public class Monitoring : Stack
{
    public Monitoring(Construct scope, string id=null) : base(scope, id) { }
}

public class MyService : Construct
{
    public MyService(Construct scope, string id, Boolean prod=false) : base(scope, id)
    {
        // we might use the prod argument to change how the service is configured
        new ControlPlane(this, "cp");
        new DataPlane(this, "data");
        new Monitoring(this, "mon");
    }
}

class Program
{
    static void Main(string[] args)
    {

        var app = new App();
        new MyService(app, "beta");
        new MyService(app, "prod", prod: true);
        app.Synth();
    }
}
```

```
package main

import (
	"github.com/aws/aws-cdk-go/awscdk/v2"
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
)

type ControlPlaneStackProps struct {
	awscdk.StackProps
}

func NewControlPlaneStack(scope constructs.Construct, id string, props *ControlPlaneStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	ControlPlaneStack := awscdk.NewStack(scope, jsii.String(id), &sprops)

	// The code that defines your stack goes here

	return ControlPlaneStack
}

type DataPlaneStackProps struct {
	awscdk.StackProps
}

func NewDataPlaneStack(scope constructs.Construct, id string, props *DataPlaneStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	DataPlaneStack := awscdk.NewStack(scope, jsii.String(id), &sprops)

	// The code that defines your stack goes here

	return DataPlaneStack
}

type MonitoringStackProps struct {
	awscdk.StackProps
}

func NewMonitoringStack(scope constructs.Construct, id string, props *MonitoringStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	MonitoringStack := awscdk.NewStack(scope, jsii.String(id), &sprops)

	// The code that defines your stack goes here

	return MonitoringStack
}

type MyServiceStackProps struct {
	awscdk.StackProps
	Prod bool
}

func NewMyServiceStack(scope constructs.Construct, id string, props *MyServiceStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	MyServiceStack := awscdk.NewStack(scope, jsii.String(id), &sprops)

	NewControlPlaneStack(MyServiceStack, "cp", &ControlPlaneStackProps{
		StackProps: sprops,
	})
	NewDataPlaneStack(MyServiceStack, "data", &DataPlaneStackProps{
		StackProps: sprops,
	})
	NewMonitoringStack(MyServiceStack, "mon", &MonitoringStackProps{
		StackProps: sprops,
	})

	return MyServiceStack
}

func main() {
	defer jsii.Close()

	app := awscdk.NewApp(nil)

	betaProps := MyServiceStackProps{
		StackProps: awscdk.StackProps{
			Env: env(),
		},
		Prod: false,
	}

	NewMyServiceStack(app, "beta", &betaProps)

	prodProps := MyServiceStackProps{
		StackProps: awscdk.StackProps{
			Env: env(),
		},
		Prod: true,
	}

	NewMyServiceStack(app, "prod", &prodProps)

	app.Synth(nil)
}

// ...
```
Questa app AWS CDK alla fine è composta da sei stack, tre per ogni ambiente:  

```
$ cdk ls

betacpDA8372D3
betadataE23DB2BA
betamon632BD457
prodcp187264CE
proddataF7378CE5
prodmon631A1083
```

I nomi fisici degli AWS CloudFormation stack vengono determinati automaticamente dal AWS CDK in base al percorso di costruzione dello stack nell'albero. Per impostazione predefinita, il nome di uno stack deriva dall'ID del costrutto dell'oggetto. `Stack` Tuttavia, puoi specificare un nome esplicito usando il `stackName` prop (in Python,`stack_name`), come segue.

**Example**  

```
new MyStack(this, 'not:a:stack:name', { stackName: 'this-is-stack-name' });
```

```
new MyStack(this, 'not:a:stack:name', { stackName: 'this-is-stack-name' });
```

```
MyStack(self, "not:a:stack:name", stack_name="this-is-stack-name")
```

```
new MyStack(this, "not:a:stack:name", StackProps.builder()
    .StackName("this-is-stack-name").build());
```

```
new MyStack(this, "not:a:stack:name", new StackProps
{
    StackName = "this-is-stack-name"
});
```

### Utilizzo di stack nidificati
<a name="stack-nesting"></a>

Uno stack *annidato è uno stack* CDK creato all'interno di un altro stack, noto come stack principale. È possibile creare pile annidate utilizzando il costrutto. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.NestedStack.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.NestedStack.html)

Utilizzando gli stack annidati, è possibile organizzare le risorse su più stack. Gli stack annidati offrono anche un modo per aggirare il limite di 500 risorse per gli AWS CloudFormation stack. Uno stack nidificato conta come una sola risorsa nello stack che lo contiene. Tuttavia, può contenere fino a 500 risorse, inclusi stack annidati aggiuntivi.

L'ambito di uno stack nidificato deve essere un costrutto or. `Stack` `NestedStack` Lo stack nidificato non deve essere dichiarato lessicalmente all'interno dello stack principale. È necessario solo passare lo stack principale come primo parametro (`scope`) quando si istanzia lo stack nidificato. A parte questa restrizione, la definizione dei costrutti in uno stack annidato funziona esattamente come in uno stack ordinario.

Al momento della sintesi, lo stack annidato viene sintetizzato in un proprio AWS CloudFormation modello, che viene caricato nel bucket di staging CDK al momento della distribuzione. AWS Gli stack annidati sono legati allo stack principale e non vengono trattati come artefatti di distribuzione indipendenti. Non sono elencati da `cdk list` e non possono essere distribuiti da. `cdk deploy`

[I riferimenti tra gli stack principali e gli stack annidati vengono tradotti automaticamente in parametri e output dello stack nei AWS CloudFormation modelli generati, come con qualsiasi riferimento cross-stack.](resources.md#resource-stack)

**avvertimento**  
Le modifiche al livello di sicurezza non vengono visualizzate prima della distribuzione degli stack annidati. Queste informazioni vengono visualizzate solo per gli stack di primo livello.

# Introduzione agli AWS stadi CDK
<a name="stages"></a>

Una *fase AWS * Cloud Development Kit (AWS CDK) rappresenta un gruppo di uno o più stack CDK configurati per essere distribuiti insieme. Utilizza le fasi per distribuire lo stesso raggruppamento di stack in più ambienti, come sviluppo, test e produzione.

Per configurare una fase CDK, importate e utilizzate il costrutto. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stage.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stage.html)

Di seguito è riportato un esempio di base che definisce uno stadio CDK denominato. `MyAppStage` Aggiungiamo due stack CDK, denominati `AppStack` e, `DatabaseStack` al nostro stage. Per questo esempio, `AppStack` contiene risorse applicative e `DatabaseStack` contiene risorse di database. Quindi creiamo due istanze di`MyAppStage`, per ambienti di sviluppo e produzione:

**Example**  
In `cdk-demo-app/lib/app-stack.ts`:  

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

// Define the app stack
export class AppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    // The code that defines your application goes here
  }
}
```
In `cdk-demo-app/lib/database-stack.ts`:  

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

// Define the database stack
export class DatabaseStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    // The code that defines your database goes here
  }
}
```
In `cdk-demo-app/lib/my-stage.ts`:  

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { Stage } from 'aws-cdk-lib';
import { AppStack } from './app-stack';
import { DatabaseStack } from './database-stack';

// Define the stage
export class MyAppStage extends Stage {
  constructor(scope: Construct, id: string, props?: cdk.StageProps) {
    super(scope, id, props);

    // Add both stacks to the stage
    new AppStack(this, 'AppStack');
    new DatabaseStack(this, 'DatabaseStack');
  }
}
```
In `cdk-demo-app/bin/cdk-demo-app.ts`:  

```
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { MyAppStage } from '../lib/my-stage';

// Create a CDK app
const app = new cdk.App();

// Create the development stage
new MyAppStage(app, 'Dev', {
  env: {
    account: '123456789012',
    region: 'us-east-1'
  }
});

// Create the production stage
new MyAppStage(app, 'Prod', {
  env: {
    account: '098765432109',
    region: 'us-east-1'
  }
});
```
In `cdk-demo-app/lib/app-stack.js`:  

```
const { Stack } = require('aws-cdk-lib');

class AppStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // The code that defines your application goes here
  }
}

module.exports = { AppStack }
```
In `cdk-demo-app/lib/database-stack.js`:  

```
const { Stack } = require('aws-cdk-lib');

class DatabaseStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // The code that defines your database goes here
  }
}

module.exports = { DatabaseStack }
```
In `cdk-demo-app/lib/my-stage.js`:  

```
const { Stage } = require('aws-cdk-lib');
const { AppStack } = require('./app-stack');
const { DatabaseStack } = require('./database-stack');

// Define the stage
class MyAppStage extends Stage {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Add both stacks to the stage
    new AppStack(this, 'AppStack');
    new DatabaseStack(this, 'DatabaseStack');
  }
}

module.exports = { MyAppStage };
```
In `cdk-demo-app/bin/cdk-demo-app.js`:  

```
#!/usr/bin/env node

const cdk = require('aws-cdk-lib');
const { MyAppStage } = require('../lib/my-stage');

// Create the CDK app
const app = new cdk.App();

// Create the development stage
new MyAppStage(app, 'Dev', {
  env: {
    account: '123456789012',
    region: 'us-east-1',
  },
});

// Create the production stage
new MyAppStage(app, 'Prod', {
  env: {
    account: '098765432109',
    region: 'us-east-1',
  },
});
```
In `cdk-demo-app/cdk_demo_app/app_stack.py`:  

```
from aws_cdk import Stack
from constructs import Construct

# Define the app stack
class AppStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # The code that defines your application goes here
```
In `cdk-demo-app/cdk_demo_app/database_stack.py`:  

```
from aws_cdk import Stack
from constructs import Construct

# Define the database stack
class DatabaseStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # The code that defines your database goes here
```
In `cdk-demo-app/cdk_demo_app/my_stage.py`:  

```
from aws_cdk import Stage
from constructs import Construct
from .app_stack import AppStack
from .database_stack import DatabaseStack

# Define the stage
class MyAppStage(Stage):
    def __init__(self, scope: Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        # Add both stacks to the stage
        AppStack(self, "AppStack")
        DatabaseStack(self, "DatabaseStack")
```
In `cdk-demo-app/app.py`:  

```
#!/usr/bin/env python3
import os

import aws_cdk as cdk

from cdk_demo_app.my_stage import MyAppStage

#  Create a CDK app
app = cdk.App()

# Create the development stage
MyAppStage(app, 'Dev',
           env=cdk.Environment(account='123456789012', region='us-east-1'),
           )

# Create the production stage
MyAppStage(app, 'Prod',
           env=cdk.Environment(account='098765432109', region='us-east-1'),
           )

app.synth()
```
In `cdk-demo-app/src/main/java/com/myorg/AppStack.java`:  

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;

public class AppStack extends Stack {
    public AppStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public AppStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // The code that defines your application goes here
    }
}
```
In `cdk-demo-app/src/main/java/com/myorg/DatabaseStack.java`:  

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;

public class DatabaseStack extends Stack {
    public DatabaseStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public DatabaseStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // The code that defines your database goes here
    }
}
```
In `cdk-demo-app/src/main/java/com/myorg/MyAppStage.java`:  

```
package com.myorg;

import software.amazon.awscdk.Stage;
import software.amazon.awscdk.StageProps;
import software.constructs.Construct;

// Define the stage
public class MyAppStage extends Stage {
    public MyAppStage(final Construct scope, final String id, final software.amazon.awscdk.Environment env) {
        super(scope, id, StageProps.builder().env(env).build());

        // Add both stacks to the stage
        new AppStack(this, "AppStack");
        new DatabaseStack(this, "DatabaseStack");
    }
}
```
In `cdk-demo-app/src/main/java/com/myorg/CdkDemoAppApp.java`:  

```
package com.myorg;

import software.amazon.awscdk.App;
import software.amazon.awscdk.Environment;
import software.amazon.awscdk.StackProps;

import java.util.Arrays;

public class CdkDemoAppApp {
    public static void main(final String[] args) {

        // Create a CDK app
        App app = new App();

        // Create the development stage
        new MyAppStage(app, "Dev", Environment.builder()
                .account("123456789012")
                .region("us-east-1")
                .build());

        // Create the production stage
        new MyAppStage(app, "Prod", Environment.builder()
        .account("098765432109")
        .region("us-east-1")
        .build());

        app.synth();
    }
}
```
In `cdk-demo-app/src/CdkDemoApp/AppStack.cs`:  

```
using Amazon.CDK;
using Constructs;

namespace CdkDemoApp
{
    public class AppStack : Stack
    {
        internal AppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // The code that defines your application goes here
        }
    }
}
```
In `cdk-demo-app/src/CdkDemoApp/DatabaseStack.cs`:  

```
using Amazon.CDK;
using Constructs;

namespace CdkDemoApp
{
    public class DatabaseStack : Stack
    {
        internal DatabaseStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // The code that defines your database goes here
        }
    }
}
```
In `cdk-demo-app/src/CdkDemoApp/MyAppStage.cs`:  

```
using Amazon.CDK;
using Constructs;

namespace CdkDemoApp
{
    // Define the stage
    public class MyAppStage : Stage
    {
        internal MyAppStage(Construct scope, string id, Environment env) : base(scope, id, new StageProps { Env = env })
        {
            // Add both stacks to the stage
            new AppStack(this, "AppStack");
            new DatabaseStack(this, "DatabaseStack");
        }
    }
}
```
In `cdk-demo-app/src/CdkDemoApp/program.cs`:  

```
using Amazon.CDK;
using System;
using System.Collections.Generic;
using System.Linq;

namespace CdkDemoApp
{
    sealed class Program
    {
        public static void Main(string[] args)
        {
            // Create a CDK app
            var app = new App();

            // Create the development stage
            new MyAppStage(app, "Dev", new Amazon.CDK.Environment
            {
                Account = "123456789012",
                Region = "us-east-1"
            });

            // Create the production stage
            new MyAppStage(app, "Prod", new Amazon.CDK.Environment
            {
                Account = "098765432109",
                Region = "us-east-1"
            });

            app.Synth();
        }
    }
}
```
In `cdk-demo-app/cdk-demo-app.go`:  

```
package main

import (
	"github.com/aws/aws-cdk-go/awscdk/v2"
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
)

// Define the app stack
type AppStackProps struct {
	awscdk.StackProps
}

func NewAppStack(scope constructs.Construct, id string, props *AppStackProps) awscdk.Stack {
	stack := awscdk.NewStack(scope, &id, &props.StackProps)

	// The code that defines your application goes here

	return stack
}

// Define the database stack
type DatabaseStackProps struct {
	awscdk.StackProps
}

func NewDatabaseStack(scope constructs.Construct, id string, props *DatabaseStackProps) awscdk.Stack {
	stack := awscdk.NewStack(scope, &id, &props.StackProps)

	// The code that defines your database goes here

	return stack
}

// Define the stage
type MyAppStageProps struct {
	awscdk.StageProps
}

func NewMyAppStage(scope constructs.Construct, id string, props *MyAppStageProps) awscdk.Stage {
	stage := awscdk.NewStage(scope, &id, &props.StageProps)

	// Add both stacks to the stage
	NewAppStack(stage, "AppStack", &AppStackProps{
		StackProps: awscdk.StackProps{
			Env: props.Env,
		},
	})

	NewDatabaseStack(stage, "DatabaseStack", &DatabaseStackProps{
		StackProps: awscdk.StackProps{
			Env: props.Env,
		},
	})

	return stage
}

func main() {
	defer jsii.Close()

	// Create a CDK app
	app := awscdk.NewApp(nil)

	// Create the development stage
	NewMyAppStage(app, "Dev", &MyAppStageProps{
		StageProps: awscdk.StageProps{
			Env: &awscdk.Environment{
				Account: jsii.String("123456789012"),
				Region:  jsii.String("us-east-1"),
			},
		},
	})

	// Create the production stage
	NewMyAppStage(app, "Prod", &MyAppStageProps{
		StageProps: awscdk.StageProps{
			Env: &awscdk.Environment{
				Account: jsii.String("098765432109"),
				Region:  jsii.String("us-east-1"),
			},
		},
	})

	app.Synth(nil)
}

func env() *awscdk.Environment {
	return nil
}
```

Quando eseguiamo`cdk synth`, vengono creati due assemblaggi cloud. `cdk.out` Questi due cloud assembly contengono il AWS CloudFormation modello e le risorse sintetizzati per ogni fase. Quello che segue è un frammento della nostra directory di progetto:

**Example**  

```
cdk-demo-app
├── bin
│   └── cdk-demo-app.ts
├── cdk.out
│   ├── assembly-Dev
│   │   ├── DevAppStack<unique-hash>.assets.json
│   │   ├── DevAppStack<unique-hash>.template.json
│   │   ├── DevDatabaseStack<unique-hash>.assets.json
│   │   ├── DevDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── assembly-Prod
│   │   ├── ProdAppStack<unique-hash>.assets.json
│   │   ├── ProdAppStack<unique-hash>.template.json
│   │   ├── ProdDatabaseStack<unique-hash>.assets.json
│   │   ├── ProdDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
└── lib
    ├── app-stack.ts
    ├── database-stack.ts
    └── my-stage.ts
```

```
cdk-demo-app
├── bin
│   └── cdk-demo-app.js
├── cdk.out
│   ├── assembly-Dev
│   │   ├── DevAppStack<unique-hash>.assets.json
│   │   ├── DevAppStack<unique-hash>.template.json
│   │   ├── DevDatabaseStack<unique-hash>.assets.json
│   │   ├── DevDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── assembly-Prod
│   │   ├── ProdAppStack<unique-hash>.assets.json
│   │   ├── ProdAppStack<unique-hash>.template.json
│   │   ├── ProdDatabaseStack<unique-hash>.assets.json
│   │   ├── ProdDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
└── lib
    ├── app-stack.js
    ├── database-stack.js
    └── my-stage.js
```

```
cdk-demo-app
├── app.py
├── cdk.out
│   ├── assembly-Dev
│   │   ├── DevAppStack<unique-hash>.assets.json
│   │   ├── DevAppStack<unique-hash>.template.json
│   │   ├── DevDatabaseStack<unique-hash>.assets.json
│   │   ├── DevDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── assembly-Prod
│   │   ├── ProdAppStack<unique-hash>.assets.json
│   │   ├── ProdAppStack<unique-hash>.template.json
│   │   ├── ProdDatabaseStack<unique-hash>.assets.json
│   │   ├── ProdDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── cdk.out
│   ├── manifest.json
│   └── tree.json
└── cdk_demo_app
    ├── __init__.py
    ├── app_stack.py
    ├── database_stack.py
    └── my_stage.py
```

```
cdk-demo-app
├── cdk.out
│   ├── assembly-Dev
│   │   ├── DevAppStack<unique-hash>.assets.json
│   │   ├── DevAppStack<unique-hash>.template.json
│   │   ├── DevDatabaseStack<unique-hash>.assets.json
│   │   ├── DevDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── assembly-Prod
│   │   ├── ProdAppStack<unique-hash>.assets.json
│   │   ├── ProdAppStack<unique-hash>.template.json
│   │   ├── ProdDatabaseStack<unique-hash>.assets.json
│   │   ├── ProdDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── cdk.out
│   ├── manifest.json
│   └── tree.json
└── src
    └── main
        └── java
            └── com
                └── myorg
                    ├── AppStack.java
                    ├── CdkDemoAppApp.java
                    ├── DatabaseStack.java
                    └── MyAppStage.java
```

```
cdk-demo-app
├── cdk.out
│   ├── assembly-Dev
│   │   ├── DevAppStack<unique-hash>.assets.json
│   │   ├── DevAppStack<unique-hash>.template.json
│   │   ├── DevDatabaseStack<unique-hash>.assets.json
│   │   ├── DevDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── assembly-Prod
│   │   ├── ProdAppStack<unique-hash>.assets.json
│   │   ├── ProdAppStack<unique-hash>.template.json
│   │   ├── ProdDatabaseStack<unique-hash>.assets.json
│   │   ├── ProdDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── cdk.out
│   ├── manifest.json
│   └── tree.json
└── src
    └── CdkDemoApp
        ├── AppStack.cs
        ├── DatabaseStack.cs
        ├── MyAppStage.cs
        └── Program.cs
```

```
cdk-demo-app
├── cdk-demo-app.go
└── cdk.out
    ├── assembly-Dev
    │   ├── DevAppStack<unique-hash>.assets.json
    │   ├── DevAppStack<unique-hash>.template.json
    │   ├── DevDatabaseStack<unique-hash>.assets.json
    │   ├── DevDatabaseStack<unique-hash>.template.json
    │   ├── cdk.out
    │   └── manifest.json
    ├── assembly-Prod
    │   ├── ProdAppStack<unique-hash>.assets.json
    │   ├── ProdAppStack<unique-hash>.template.json
    │   ├── ProdDatabaseStack<unique-hash>.assets.json
    │   ├── ProdDatabaseStack<unique-hash>.template.json
    │   ├── cdk.out
    │   └── manifest.json
    ├── cdk.out
    ├── manifest.json
    └── tree.json
```
Quando elenchiamo i nostri stack con`cdk list`, vediamo un totale di quattro pile:  

```
$ cdk list
Dev/AppStack (Dev-AppStack)
Dev/DatabaseStack (Dev-DatabaseStack)
Prod/AppStack (Prod-AppStack)
Prod/DatabaseStack (Prod-DatabaseStack)
```
Per implementare una fase specifica, eseguiamo `cdk deploy` e forniamo gli stack da distribuire. Di seguito è riportato un esempio che utilizza la `/*` jolly per distribuire entrambi gli stack nella nostra fase: `Dev`  

```
$ cdk deploy <"Dev/*">

✨  Synthesis time: 3.18s

Dev/AppStack (Dev-AppStack)
Dev/AppStack (Dev-AppStack): deploying... [1/2]

 ✅  Dev/AppStack (Dev-AppStack)

✨  Deployment time: 1.11s

Stack ARN:
...

✨  Total time: 4.29s

Dev/DatabaseStack (Dev-DatabaseStack)
Dev/DatabaseStack (Dev-DatabaseStack): deploying... [2/2]

 ✅  Dev/DatabaseStack (Dev-DatabaseStack)

✨  Deployment time: 1.09s

Stack ARN:
...

✨  Total time: 4.27s
```

# AWS Costrutti CDK
<a name="constructs"></a>

I costrutti sono gli elementi costitutivi di base delle applicazioni AWS Cloud Development Kit (AWS CDK). Un costrutto è un componente all'interno dell'applicazione che rappresenta una o più AWS CloudFormation risorse e la loro configurazione. Puoi creare la tua applicazione, pezzo per pezzo, importando e configurando costrutti.

## Importa e usa i costrutti
<a name="constructs-import"></a>

[I costrutti sono classi che importate nelle applicazioni CDK dalla Construct Library.AWS](libraries.md#libraries-construct) Potete anche creare e distribuire costrutti personalizzati o utilizzare costrutti creati da sviluppatori di terze parti.

I costrutti fanno parte del Construct Programming Model (CPM). Sono disponibili per l'uso con altri strumenti come CDK for Terraform (CDKtf), CDK for Kubernetes () e. CDK8s Projen

Numerose terze parti hanno inoltre pubblicato costrutti compatibili con il CDK. AWS Visita [Construct Hub per esplorare l'ecosistema](https://constructs.dev/search?q=&cdk=aws-cdk&cdkver=2&offset=0) di partner di AWS CDK construct.

## Costruisci livelli
<a name="constructs-lib-levels"></a>

I costrutti della AWS Construct Library sono suddivisi in tre livelli. Ogni livello offre un livello crescente di astrazione. Maggiore è l'astrazione, più facile è la configurazione e richiede meno esperienza. Più bassa è l'astrazione, maggiore è la personalizzazione disponibile, che richiede maggiore esperienza.<a name="constructs-lib-levels-one"></a>

 **Costrutti di livello 1 (L1)**   
I costrutti L1, noti anche come *risorse CFN*, sono i costrutti di livello più basso e non offrono alcuna astrazione. Ogni costrutto L1 è mappato direttamente su una singola risorsa. AWS CloudFormation Con i costrutti L1, si importa un costrutto che rappresenta una risorsa specifica. AWS CloudFormation Definite quindi le proprietà della risorsa all'interno dell'istanza del costrutto.  
I costrutti L1 sono ottimi da usare quando si ha familiarità AWS CloudFormation e si ha bisogno del controllo completo sulla definizione delle proprietà delle risorse. AWS   
Nella AWS Construct Library, i costrutti L1 sono denominati a partire da`Cfn`, seguiti da un identificatore per la risorsa che rappresentano. AWS CloudFormation Ad esempio, il [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.CfnBucket.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.CfnBucket.html)costrutto è un costrutto L1 che rappresenta una risorsa. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html) AWS CloudFormation   
[I costrutti L1 vengono generati dalla specifica della risorsa.AWS CloudFormation ](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html) Se una risorsa esiste in AWS CloudFormation, sarà disponibile nel AWS CDK come costrutto L1. La disponibilità di nuove risorse o proprietà nella Construct Library può richiedere fino a una settimana. AWS Per ulteriori informazioni, consultate il [riferimento ai tipi di AWS risorse e proprietà](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html) nella *Guida per l' AWS CloudFormation utente*.<a name="constructs-lib-levels-two"></a>

 **Costrutti di livello 2 (L2)**   
I costrutti L2, noti anche come costrutti *curati*, sono sviluppati con cura dal team CDK e di solito sono il tipo di costrutto più utilizzato. I costrutti L2 vengono mappati direttamente su singole risorse, in modo simile ai costrutti L1. AWS CloudFormation Rispetto ai costrutti L1, i costrutti L2 forniscono un'astrazione di livello superiore tramite un'API intuitiva basata sugli intenti. I costrutti L2 includono configurazioni sensate delle proprietà predefinite, politiche di sicurezza basate sulle migliori pratiche e generano automaticamente gran parte del codice standard e della logica di incollaggio.  
I costrutti L2 forniscono anche metodi di supporto per la maggior parte delle risorse che semplificano e velocizzano la definizione di proprietà, autorizzazioni, interazioni basate su eventi tra le risorse e altro ancora. Molte di queste funzionalità sono disponibili anche come elementi costitutivi indipendenti chiamati [Mixins](mixins.md), che possono essere applicati sia ai costrutti L1 che L2 utilizzando il metodo. `.with()`  
La [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html)classe è un esempio di costrutto L2 per una risorsa bucket Amazon Simple Storage Service (Amazon S3).  
La AWS Construct Library contiene costrutti L2 designati stabili e pronti per l'uso in produzione. Per i costrutti L2 in fase di sviluppo, sono designati come sperimentali e offerti in un modulo separato.<a name="constructs-lib-levels-three"></a>

 **Costrutti di livello 3 (L3)**   
I costrutti L3, noti anche come *pattern*, rappresentano il livello di astrazione più elevato. Ogni costrutto L3 può contenere una raccolta di risorse configurate per funzionare insieme per eseguire un'attività o un servizio specifico all'interno dell'applicazione. I costrutti L3 vengono utilizzati per creare intere AWS architetture per casi d'uso particolari nell'applicazione.  
Per fornire progetti di sistema completi o parti sostanziali di un sistema più grande, i costrutti L3 offrono configurazioni di proprietà predefinite ponderate. Sono costruiti attorno a un approccio particolare per risolvere un problema e fornire una soluzione. Con i costrutti L3, puoi creare e configurare più risorse rapidamente, con il minor numero di input e codice.  
La [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs_patterns.ApplicationLoadBalancedFargateService.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs_patterns.ApplicationLoadBalancedFargateService.html)classe è un esempio di costrutto L3 che rappresenta un servizio AWS Fargate in esecuzione su un cluster Amazon Elastic Container Service (Amazon ECS) Elastic Container Service (Amazon ECS) e gestito da un sistema di bilanciamento del carico delle applicazioni.  
Analogamente ai costrutti L2, i costrutti L3 pronti per l'uso in produzione sono inclusi nella Construct Library. AWS Quelli in fase di sviluppo sono offerti in moduli separati.

## Definizione dei costrutti
<a name="constructs-define"></a>

### Composizione
<a name="constructs-composition"></a>

 *La composizione* è il modello chiave per definire astrazioni di livello superiore attraverso costrutti. Un costrutto di alto livello può essere composto da un numero qualsiasi di costrutti di livello inferiore. Da una prospettiva dal basso verso l'alto, si utilizzano i costrutti per organizzare le singole risorse che si desidera distribuire. AWS Utilizzi tutte le astrazioni che ritieni più convenienti per il tuo scopo, con tutti i livelli di cui hai bisogno.

Con la composizione, definisci i componenti riutilizzabili e li condividi come qualsiasi altro codice. Ad esempio, un team può definire un costrutto che implementa le best practice aziendali per una tabella Amazon DynamoDB, tra cui backup, replica globale, scalabilità automatica e monitoraggio. Il team può condividere il costrutto internamente con altri team o pubblicamente.

I team possono utilizzare i costrutti come qualsiasi altro pacchetto di libreria. Quando la libreria viene aggiornata, gli sviluppatori hanno accesso ai miglioramenti e alle correzioni di bug della nuova versione, in modo simile a qualsiasi altra libreria di codici.

### Inizializzazione
<a name="constructs-init"></a>

I costrutti sono implementati in classi che estendono la classe di base [https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html). Definite un costrutto istanziando la classe. Tutti i costrutti accettano tre parametri al momento dell'inizializzazione:
+  **scope**: il genitore o il proprietario del costrutto. Può trattarsi di una pila o di un altro costrutto. [L'ambito determina la posizione del costrutto nell'albero del costrutto.](apps.md#apps-tree) Di solito dovresti passare `this` (`self`in Python), che rappresenta l'oggetto corrente, per l'ambito.
+  **id** — Un [identificatore](identifiers.md) che deve essere univoco all'interno dell'ambito. L'identificatore funge da namespace per tutto ciò che è definito all'interno del costrutto. [Viene utilizzato per generare identificatori univoci, come nomi di risorse e dati logici.](resources.md#resources-physical-names) AWS CloudFormation IDs

  Gli identificatori devono essere unici solo all'interno di un ambito. Ciò consente di creare istanze e riutilizzare i costrutti senza preoccuparsi dei costrutti e degli identificatori che potrebbero contenere e consente di comporre i costrutti in astrazioni di livello superiore. Inoltre, gli ambiti consentono di fare riferimento a gruppi di costrutti contemporaneamente. Gli esempi includono l'[etichettatura](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tag.html) o la specificazione di dove verranno distribuiti i costrutti.
+  **props**: un insieme di proprietà o argomenti di parole chiave, a seconda della lingua, che definiscono la configurazione iniziale del costrutto. I costrutti di livello superiore forniscono più impostazioni predefinite e, se tutti gli elementi prop sono opzionali, potete omettere completamente il parametro props.

### Configurazione
<a name="constructs-config"></a>

La maggior parte dei costrutti accetta `props` come terzo argomento (o in Python, argomenti di parole chiave), name/value una raccolta che definisce la configurazione del costrutto. L'esempio seguente definisce un bucket con crittografia AWS Key Management Service (AWS KMS) e hosting statico di siti Web abilitati. Poiché non specifica esplicitamente una chiave di crittografia, il `Bucket` costrutto ne definisce una nuova `kms.Key` e la associa al bucket.

**Example**  

```
new s3.Bucket(this, 'MyEncryptedBucket', {
  encryption: s3.BucketEncryption.KMS,
  websiteIndexDocument: 'index.html'
});
```

```
new s3.Bucket(this, 'MyEncryptedBucket', {
  encryption: s3.BucketEncryption.KMS,
  websiteIndexDocument: 'index.html'
});
```

```
s3.Bucket(self, "MyEncryptedBucket", encryption=s3.BucketEncryption.KMS,
    website_index_document="index.html")
```

```
Bucket.Builder.create(this, "MyEncryptedBucket")
        .encryption(BucketEncryption.KMS_MANAGED)
        .websiteIndexDocument("index.html").build();
```

```
new Bucket(this, "MyEncryptedBucket", new BucketProps
{
    Encryption = BucketEncryption.KMS_MANAGED,
    WebsiteIndexDocument = "index.html"
});
```

```
	awss3.NewBucket(stack, jsii.String("MyEncryptedBucket"), &awss3.BucketProps{
		Encryption: awss3.BucketEncryption_KMS,
		WebsiteIndexDocument: jsii.String("index.html"),
	})
```

### Interazione con i costrutti
<a name="constructs-interact"></a>

[I costrutti sono classi che estendono la classe Construct di base.](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html) Dopo aver creato un'istanza di un costrutto, l'oggetto construct espone un insieme di metodi e proprietà che consentono di interagire con il costrutto e di passarlo come riferimento ad altre parti del sistema.

Il framework AWS CDK non impone alcuna restrizione ai costrutti. APIs Gli autori possono definire qualsiasi API desiderino. Tuttavia, AWS i costrutti inclusi nella AWS Construct Library, ad esempio`s3.Bucket`, seguono linee guida e modelli comuni. Ciò fornisce un'esperienza coerente su tutte le AWS risorse.

La maggior parte dei AWS costrutti dispone di una serie di metodi di [concessione](permissions.md#permissions-grants) che è possibile utilizzare per concedere le autorizzazioni di AWS Identity and Access Management (IAM) su quel costrutto a un principale. L'esempio seguente concede al gruppo IAM l'`data-science`autorizzazione alla lettura dal bucket Amazon `raw-data` S3.

**Example**  

```
const rawData = new s3.Bucket(this, 'raw-data');
const dataScience = new iam.Group(this, 'data-science');
rawData.grants.read(dataScience);
```

```
const rawData = new s3.Bucket(this, 'raw-data');
const dataScience = new iam.Group(this, 'data-science');
rawData.grants.read(dataScience);
```

```
raw_data = s3.Bucket(self, 'raw-data')
data_science = iam.Group(self, 'data-science')
raw_data.grants.read(data_science)
```

```
Bucket rawData = new Bucket(this, "raw-data");
Group dataScience = new Group(this, "data-science");
rawData.getGrants().read(dataScience);
```

```
var rawData = new Bucket(this, "raw-data");
var dataScience = new Group(this, "data-science");
rawData.Grants.Read(dataScience);
```

```
	rawData := awss3.NewBucket(stack, jsii.String("raw-data"), nil)
	dataScience := awsiam.NewGroup(stack, jsii.String("data-science"), nil)
	rawData.Grants().Read(dataScience, nil)
```

Un altro schema comune prevede che AWS i costrutti impostino uno degli attributi della risorsa a partire dai dati forniti altrove. Gli attributi possono includere Amazon Resource Names (ARNs), nomi o URLs.

Il codice seguente definisce una funzione AWS Lambda e la associa a una coda Amazon Simple Queue Service (Amazon SQS) tramite l'URL della coda in una variabile di ambiente.

**Example**  

```
const jobsQueue = new sqs.Queue(this, 'jobs');
const createJobLambda = new lambda.Function(this, 'create-job', {
  runtime: lambda.Runtime.NODEJS_18_X,
  handler: 'index.handler',
  code: lambda.Code.fromAsset('./create-job-lambda-code'),
  environment: {
    QUEUE_URL: jobsQueue.queueUrl
  }
});
```

```
const jobsQueue = new sqs.Queue(this, 'jobs');
const createJobLambda = new lambda.Function(this, 'create-job', {
  runtime: lambda.Runtime.NODEJS_18_X,
  handler: 'index.handler',
  code: lambda.Code.fromAsset('./create-job-lambda-code'),
  environment: {
    QUEUE_URL: jobsQueue.queueUrl
  }
});
```

```
jobs_queue = sqs.Queue(self, "jobs")
create_job_lambda = lambda_.Function(self, "create-job",
    runtime=lambda_.Runtime.NODEJS_18_X,
    handler="index.handler",
    code=lambda_.Code.from_asset("./create-job-lambda-code"),
    environment=dict(
        QUEUE_URL=jobs_queue.queue_url
    )
)
```

```
final Queue jobsQueue = new Queue(this, "jobs");
Function createJobLambda = Function.Builder.create(this, "create-job")
                .handler("index.handler")
                .code(Code.fromAsset("./create-job-lambda-code"))
                .environment(java.util.Map.of(   // Map.of is Java 9 or later
                    "QUEUE_URL", jobsQueue.getQueueUrl()))
                .build();
```

```
var jobsQueue = new Queue(this, "jobs");
var createJobLambda = new Function(this, "create-job", new FunctionProps
{
    Runtime = Runtime.NODEJS_18_X,
    Handler = "index.handler",
    Code = Code.FromAsset(@".\create-job-lambda-code"),
    Environment = new Dictionary<string, string>
    {
        ["QUEUE_URL"] = jobsQueue.QueueUrl
    }
});
```

```
	createJobLambda := awslambda.NewFunction(stack, jsii.String("create-job"), &awslambda.FunctionProps{
		Runtime: awslambda.Runtime_NODEJS_18_X(),
		Handler: jsii.String("index.handler"),
		Code:    awslambda.Code_FromAsset(jsii.String(".\\create-job-lambda-code"), nil),
		Environment: &map[string]*string{
			"QUEUE_URL": jsii.String(*jobsQueue.QueueUrl()),
		},
	})
```

[Per informazioni sui modelli di API più comuni nella AWS Construct Library, consulta Resources and the CDK. AWS](resources.md)

### Aggiungi funzionalità con Mixins
<a name="constructs-mixins"></a>

I mixin sono funzionalità componibili che puoi applicare a qualsiasi costrutto utilizzando il metodo. `.with()` I mixin consentono di aggiungere funzionalità ai costrutti L1 e L2 senza dover utilizzare un costrutto diverso o scrivere codice di basso livello.

Ad esempio, puoi abilitare il controllo delle versioni e bloccare l'accesso pubblico su un bucket Amazon S3, che si tratti di un L1 o di un `CfnBucket` L2: `Bucket`

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

// Apply mixins to an L1 construct
new s3.CfnBucket(this, 'MyBucket')
  .with(new s3.mixins.BucketVersioning())
  .with(new s3.mixins.BucketBlockPublicAccess());

// Apply mixins to an L2 construct
new s3.Bucket(this, 'MyL2Bucket', { removalPolicy: cdk.RemovalPolicy.DESTROY })
  .with(new s3.mixins.BucketAutoDeleteObjects());
```

```
const cdk = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');

// Apply mixins to an L1 construct
new s3.CfnBucket(this, 'MyBucket')
  .with(new s3.mixins.BucketVersioning())
  .with(new s3.mixins.BucketBlockPublicAccess());

// Apply mixins to an L2 construct
new s3.Bucket(this, 'MyL2Bucket', { removalPolicy: cdk.RemovalPolicy.DESTROY })
  .with(new s3.mixins.BucketAutoDeleteObjects());
```

```
import aws_cdk as cdk
import aws_cdk.aws_s3 as s3

# Apply mixins to an L1 construct
s3.CfnBucket(self, "MyBucket") \
    .with_(s3.mixins.BucketVersioning()) \
    .with_(s3.mixins.BucketBlockPublicAccess())

# Apply mixins to an L2 construct
s3.Bucket(self, "MyL2Bucket", removal_policy=cdk.RemovalPolicy.DESTROY) \
    .with_(s3.mixins.BucketAutoDeleteObjects())
```

```
import software.amazon.awscdk.*;
import software.amazon.awscdk.services.s3.*;

// Apply mixins to an L1 construct
CfnBucket bucket = new CfnBucket(this, "MyBucket");
bucket.with(new BucketVersioning());
bucket.with(new BucketBlockPublicAccess());

// Apply mixins to an L2 construct
Bucket l2Bucket = Bucket.Builder.create(this, "MyL2Bucket")
        .removalPolicy(RemovalPolicy.DESTROY)
        .build();
l2Bucket.with(new BucketAutoDeleteObjects());
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

// Apply mixins to an L1 construct
var bucket = new CfnBucket(this, "MyBucket");
bucket.With(new BucketVersioning());
bucket.With(new BucketBlockPublicAccess());

// Apply mixins to an L2 construct
var l2Bucket = new Bucket(this, "MyL2Bucket", new BucketProps
{
    RemovalPolicy = RemovalPolicy.DESTROY
});
l2Bucket.With(new BucketAutoDeleteObjects());
```

```
bucket := awss3.NewCfnBucket(stack, jsii.String("MyBucket"), nil)
bucket.With(awss3.NewBucketVersioning())
bucket.With(awss3.NewBucketBlockPublicAccess())

l2Bucket := awss3.NewBucket(stack, jsii.String("MyL2Bucket"), &awss3.BucketProps{
    RemovalPolicy: awscdk.RemovalPolicy_DESTROY,
})
l2Bucket.With(awss3.NewBucketAutoDeleteObjects())
```

I mixin sono disponibili tramite lo spazio dei `mixins` nomi di ciascun modulo di servizio (ad esempio,). `s3.mixins` Ogni mixin si rivolge a un tipo di risorsa specifico e prende il nome da quella risorsa. Quando applicate un mixin a un costrutto L2, si applica automaticamente alla risorsa L1 sottostante.

[Per ulteriori informazioni su Mixins, vedete Mixins.](mixins.md)

### L'app e lo stack costruiscono
<a name="constructs-apps-stacks"></a>

Le [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html)classi [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html)e della AWS Construct Library sono costrutti unici. Rispetto ad altri costrutti, non configurano AWS le risorse da soli. Vengono invece utilizzati per fornire un contesto agli altri costrutti. Tutti i costrutti che rappresentano AWS risorse devono essere definiti, direttamente o indirettamente, nell'ambito di un costrutto. `Stack` `Stack`i costrutti sono definiti nell'ambito di un costrutto. `App`

[Per ulteriori informazioni sulle app CDK, consulta AWS App CDK.](apps.md) Per ulteriori informazioni sugli stack CDK, consulta [Introduzione](stacks.md) agli stack CDK. AWS 

L'esempio seguente definisce un'app con un singolo stack. All'interno dello stack, viene utilizzato un costrutto L2 per configurare una risorsa bucket Amazon S3.

**Example**  

```
import { App, Stack, StackProps } from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

class HelloCdkStack extends Stack {
  constructor(scope: App, id: string, props?: StackProps) {
    super(scope, id, props);

    new s3.Bucket(this, 'MyFirstBucket', {
      versioned: true
    });
  }
}

const app = new App();
new HelloCdkStack(app, "HelloCdkStack");
```

```
const { App , Stack } = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');

class HelloCdkStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    new s3.Bucket(this, 'MyFirstBucket', {
      versioned: true
    });
  }
}

const app = new App();
new HelloCdkStack(app, "HelloCdkStack");
```

```
from aws_cdk import App, Stack
import aws_cdk.aws_s3 as s3
from constructs import Construct

class HelloCdkStack(Stack):

    def __init__(self, scope: Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        s3.Bucket(self, "MyFirstBucket", versioned=True)

app = App()
HelloCdkStack(app, "HelloCdkStack")
```
Stack definito nel file: `HelloCdkStack.java`  

```
import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.s3.*;

public class HelloCdkStack extends Stack {
    public HelloCdkStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public HelloCdkStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        Bucket.Builder.create(this, "MyFirstBucket")
            .versioned(true).build();
    }
}
```
App definita nel `HelloCdkApp.java` file:  

```
import software.amazon.awscdk.App;
import software.amazon.awscdk.StackProps;

public class HelloCdkApp {
    public static void main(final String[] args) {
        App app = new App();

        new HelloCdkStack(app, "HelloCdkStack", StackProps.builder()
                .build());

        app.synth();
    }
}
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

namespace HelloCdkApp
{
    internal static class Program
    {
        public static void Main(string[] args)
        {
            var app = new App();
            new HelloCdkStack(app, "HelloCdkStack");
            app.Synth();
        }
    }

    public class HelloCdkStack : Stack
    {
        public HelloCdkStack(Construct scope, string id, IStackProps props=null) : base(scope, id, props)
        {
            new Bucket(this, "MyFirstBucket", new BucketProps { Versioned = true });
        }
    }
}
```

```
func NewHelloCdkStack(scope constructs.Construct, id string, props *HelloCdkStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	awss3.NewBucket(stack, jsii.String("MyFirstBucket"), &awss3.BucketProps{
		Versioned: jsii.Bool(true),
	})

	return stack
}
```

## Lavorare con i costrutti
<a name="constructs-work"></a>

### Lavorare con i costrutti L1
<a name="constructs-l1-using"></a>

I costrutti L1 si collegano direttamente alle singole risorse. AWS CloudFormation È necessario fornire la configurazione richiesta per la risorsa.

In questo esempio, creiamo un `bucket` oggetto utilizzando il `CfnBucket` costrutto L1:

**Example**  

```
const bucket = new s3.CfnBucket(this, "amzn-s3-demo-bucket", {
  bucketName: "amzn-s3-demo-bucket"
});
```

```
const bucket = new s3.CfnBucket(this, "amzn-s3-demo-bucket", {
  bucketName: "amzn-s3-demo-bucket"
});
```

```
bucket = s3.CfnBucket(self, "amzn-s3-demo-bucket", bucket_name="amzn-s3-demo-bucket")
```

```
CfnBucket bucket = new CfnBucket.Builder().bucketName("amzn-s3-demo-bucket").build();
```

```
var bucket = new CfnBucket(this, "amzn-s3-demo-bucket", new CfnBucketProps
{
    BucketName= "amzn-s3-demo-bucket"
});
```

```
	awss3.NewCfnBucket(stack, jsii.String("amzn-s3-demo-bucket"), &awss3.CfnBucketProps{
		BucketName: jsii.String("amzn-s3-demo-bucket"),
	})
```

Le proprietà di costruzione che non sono semplici booleani, stringhe, numeri o contenitori vengono gestite in modo diverso nelle lingue supportate.

**Example**  

```
const bucket = new s3.CfnBucket(this, "amzn-s3-demo-bucket", {
  bucketName: "amzn-s3-demo-bucket",
  corsConfiguration: {
    corsRules: [{
          allowedOrigins: ["*"],
          allowedMethods: ["GET"]
    }]
  }
});
```

```
const bucket = new s3.CfnBucket(this, "amzn-s3-demo-bucket", {
  bucketName: "amzn-s3-demo-bucket",
  corsConfiguration: {
    corsRules: [{
          allowedOrigins: ["*"],
          allowedMethods: ["GET"]
    }]
  }
});
```
In Python, queste proprietà sono rappresentate da tipi definiti come classi interne del costrutto L1. Ad esempio, la proprietà opzionale `cors_configuration` di a `CfnBucket` richiede un wrapper di tipo. `CfnBucket.CorsConfigurationProperty` Qui stiamo definendo un'`cors_configuration``CfnBucket`istanza.  

```
bucket = CfnBucket(self, "amzn-s3-demo-bucket", bucket_name="amzn-s3-demo-bucket",
    cors_configuration=CfnBucket.CorsConfigurationProperty(
        cors_rules=[CfnBucket.CorsRuleProperty(
            allowed_origins=["*"],
            allowed_methods=["GET"]
        )]
    )
)
```
In Java, queste proprietà sono rappresentate da tipi definiti come classi interne del costrutto L1. Ad esempio, la proprietà opzionale `corsConfiguration` di a `CfnBucket` richiede un wrapper di tipo. `CfnBucket.CorsConfigurationProperty` Qui stiamo definendo un'`corsConfiguration``CfnBucket`istanza.  

```
CfnBucket bucket = CfnBucket.Builder.create(this, "amzn-s3-demo-bucket")
                        .bucketName("amzn-s3-demo-bucket")
                        .corsConfiguration(new CfnBucket.CorsConfigurationProperty.Builder()
                            .corsRules(Arrays.asList(new CfnBucket.CorsRuleProperty.Builder()
                                .allowedOrigins(Arrays.asList("*"))
                                .allowedMethods(Arrays.asList("GET"))
                                .build()))
                            .build())
                        .build();
```
In C\$1, queste proprietà sono rappresentate da tipi definiti come classi interne del costrutto L1. Ad esempio, la proprietà opzionale `CorsConfiguration` di a `CfnBucket` richiede un wrapper di tipo. `CfnBucket.CorsConfigurationProperty` Qui stiamo definendo un'`CorsConfiguration``CfnBucket`istanza.  

```
var bucket = new CfnBucket(this, "amzn-s3-demo-bucket", new CfnBucketProps
{
    BucketName = "amzn-s3-demo-bucket",
    CorsConfiguration = new CfnBucket.CorsConfigurationProperty
    {
        CorsRules = new object[] {
            new CfnBucket.CorsRuleProperty
            {
                AllowedOrigins = new string[] { "*" },
                AllowedMethods = new string[] { "GET" },
            }
        }
    }
});
```
In Go, questi tipi vengono denominati utilizzando il nome del costrutto L1, un carattere di sottolineatura e il nome della proprietà. Ad esempio, la proprietà opzionale `CorsConfiguration` di a `CfnBucket` richiede un wrapper di tipo. `CfnBucket_CorsConfigurationProperty` Qui stiamo definendo un'`CorsConfiguration``CfnBucket`istanza.  

```
	awss3.NewCfnBucket(stack, jsii.String("amzn-s3-demo-bucket"), &awss3.CfnBucketProps{
		BucketName: jsii.String("amzn-s3-demo-bucket"),
		CorsConfiguration: &awss3.CfnBucket_CorsConfigurationProperty{
			CorsRules: []awss3.CorsRule{
				awss3.CorsRule{
					AllowedOrigins: jsii.Strings("*"),
					AllowedMethods: &[]awss3.HttpMethods{"GET"},
				},
			},
		},
	})
```

**Importante**  
Non è possibile utilizzare i tipi di proprietà L2 con i costrutti L1 o viceversa. Quando lavorate con i costrutti L1, utilizzate sempre i tipi definiti per il costrutto L1 che state utilizzando. Non utilizzate tipi di altri costrutti L1 (alcuni possono avere lo stesso nome, ma non sono dello stesso tipo).  
Alcuni dei nostri riferimenti API specifici della lingua attualmente presentano errori nei percorsi dei tipi di proprietà L1 o non documentano affatto queste classi. Speriamo di risolvere il problema al più presto. Nel frattempo, ricorda che questi tipi sono sempre classi interne del costrutto L1 con cui vengono utilizzati.

#### Riferimento a risorse da altri costrutti
<a name="constructs-resource-references"></a>

Quando si configurano proprietà di costruzione che fanno riferimento ad altre risorse AWS, sono disponibili due opzioni equivalenti:
+  **Riferimenti a stringhe**: passano valori di stringa espliciti come nomi o ARNs altri identificatori di risorse
+  **Riferimenti agli oggetti**: passate direttamente gli oggetti di costruzione. In questo modo si evita di dover determinare il tipo di identificatore previsto da una proprietà: il CDK lo gestisce per voi.

##### Utilizzo di riferimenti a stringhe
<a name="_using_string_references"></a>

Puoi sempre passare valori di stringa espliciti come ARNs nomi o altri identificatori di risorse. Questo approccio funziona per tutte le proprietà ed è necessario per le proprietà annidate all'interno di oggetti complessi.

L'esempio seguente crea una funzione Lambda utilizzando un costrutto L1 (`CfnFunction`) con un ruolo definito utilizzando un costrutto L2 (). `Role` L'ARN del ruolo viene passato alla `role` proprietà:

**Example**  

```
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
  managedPolicies: [
    iam.ManagedPolicy.fromAwsManagedPolicyName(
      'service-role/AWSLambdaBasicExecutionRole'
    ),
  ],
});

const myFunction = new lambda.CfnFunction(this, 'HelloWorldFunction', {
  runtime: 'nodejs24.x',
  role: role.roleArn, // Pass the ARN string explicitly
  handler: 'index.handler',
  code: {
    zipFile: `
    exports.handler = async function(event) {
      return {
        statusCode: 200,
        body: JSON.stringify('Hello World!'),
      };
    };
  `}
});
```

```
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
  managedPolicies: [
    iam.ManagedPolicy.fromAwsManagedPolicyName(
      'service-role/AWSLambdaBasicExecutionRole'
    )
  ]
});

const myFunction = new lambda.CfnFunction(this, "HelloWorldFunction", {
  runtime: 'nodejs24.x',
  role: role.roleArn, // Pass the ARN string explicitly
  handler: 'index.handler',
  code: {
    zipFile: `
    exports.handler = async function(event) {
      return {
        statusCode: 200,
        body: JSON.stringify('Hello World!'),
      };
    };
  `}
});
```

```
role = iam.Role(self, "MyRole",
    assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"),
    managed_policies=[
        iam.ManagedPolicy.from_aws_managed_policy_name(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    ]
)

my_function = _lambda.CfnFunction(self, "HelloWorldFunction",
    runtime="nodejs24.x",
    role=role.role_arn,  # Pass the ARN string explicitly
    handler="index.handler",
    code=_lambda.CfnFunction.CodeProperty(
        zip_file=
        """
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
        """
    )
)
```

```
Role role = Role.Builder.create(this, "MyRole")
    .assumedBy(new ServicePrincipal("lambda.amazonaws.com"))
    .managedPolicies(Arrays.asList(
        ManagedPolicy.fromAwsManagedPolicyName(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    ))
    .build();

CfnFunction myFunction = CfnFunction.Builder.create(this, "HelloWorldFunction")
    .runtime("nodejs24.x")
    .role(role.getRoleArn())  // Pass the ARN string explicitly
    .handler("index.handler")
    .code(CfnFunction.CodeProperty.builder()
        .zipFile(
            "exports.handler = async function(event) {" +
            "  return {" +
            "    statusCode: 200," +
            "    body: JSON.stringify('Hello World!')," +
            "  };" +
            "};")
        .build())
    .build();
```

```
var role = new Role(this, "MyRole", new RoleProps
{
    AssumedBy = new ServicePrincipal("lambda.amazonaws.com"),
    ManagedPolicies = new[]
    {
        ManagedPolicy.FromAwsManagedPolicyName(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    }
});

var myFunction = new CfnFunction(this, "HelloWorldFunction", new CfnFunctionProps
{
    Runtime = "nodejs24.x",
    Role = role.RoleArn,  // Pass the ARN string explicitly
    Handler = "index.handler",
    Code = new CfnFunction.CodeProperty
    {
        ZipFile = @"
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
        "
    }
});
```

```
role := awsiam.NewRole(stack, jsii.String("MyRole"), &awsiam.RoleProps{
	AssumedBy: awsiam.NewServicePrincipal(jsii.String("lambda.amazonaws.com"), nil),
	ManagedPolicies: &[]awsiam.IManagedPolicy{
		awsiam.ManagedPolicy_FromAwsManagedPolicyName(jsii.String("service-role/AWSLambdaBasicExecutionRole")),
	},
})

myFunction := awslambda.NewCfnFunction(stack, jsii.String("HelloWorldFunction"), &awslambda.CfnFunctionProps{
	Runtime: jsii.String("nodejs24.x"),
	Role:    role.RoleArn(), // Pass the ARN string explicitly
	Handler: jsii.String("index.handler"),
	Code: &awslambda.CfnFunction_CodeProperty{
		ZipFile: jsii.String(`
		exports.handler = async function(event) {
		  return {
		    statusCode: 200,
		    body: JSON.stringify('Hello World!'),
		  };
		};
		`),
	},
})
```

##### Utilizzo dei riferimenti agli oggetti
<a name="_using_object_references"></a>

Per le proprietà selezionate, potete passare direttamente gli oggetti di costruzione invece di estrarne gli attributi manualmente. Il supporto per i riferimenti agli oggetti varia in base alla proprietà e può espandersi nel tempo man mano che vengono aggiunte nuove proprietà.

Quando passate un riferimento a un oggetto nel costrutto`props`, il CDK lo risolve nel valore di stringa appropriato (come un ARN, un nome o un altro identificatore). Se successivamente accedete alla proprietà corrispondente sull'istanza del costruct, vedrete questo valore di stringa risolto, non il riferimento all'oggetto originale.

I riferimenti agli oggetti funzionano solo per le proprietà di primo livello dei costrutti. Le proprietà annidate all'interno di oggetti complessi richiedono valori di stringa espliciti.

L'esempio seguente mostra la stessa funzione Lambda, ma utilizza l'oggetto role anziché la stringa ARN del ruolo:

**Example**  

```
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
  managedPolicies: [
    iam.ManagedPolicy.fromAwsManagedPolicyName(
      'service-role/AWSLambdaBasicExecutionRole'
    ),
  ],
});

const myFunction = new lambda.CfnFunction(this, 'HelloWorldFunction', {
  runtime: 'nodejs24.x',
  role: role, // CDK resolves to role ARN automatically
  handler: 'index.handler',
  code: {
    zipFile: `
    exports.handler = async function(event) {
      return {
        statusCode: 200,
        body: JSON.stringify('Hello World!'),
      };
    };
  `}
});

// After creation, myFunction.role contains the resolved ARN string
```

```
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
  managedPolicies: [
    iam.ManagedPolicy.fromAwsManagedPolicyName(
      'service-role/AWSLambdaBasicExecutionRole'
    )
  ]
});

const myFunction = new lambda.CfnFunction(this, "HelloWorldFunction", {
  runtime: 'nodejs24.x',
  role: role, // CDK resolves to role ARN automatically
  handler: 'index.handler',
  code: {
    zipFile: `
    exports.handler = async function(event) {
      return {
        statusCode: 200,
        body: JSON.stringify('Hello World!'),
      };
    };
  `}
});

// After creation, myFunction.role contains the resolved ARN string
```

```
role = iam.Role(self, "MyRole",
    assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"),
    managed_policies=[
        iam.ManagedPolicy.from_aws_managed_policy_name(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    ]
)

my_function = _lambda.CfnFunction(self, "HelloWorldFunction",
    runtime="nodejs24.x",
    role=role,  # CDK resolves to role ARN automatically
    handler="index.handler",
    code=_lambda.CfnFunction.CodeProperty(
        zip_file=
        """
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
        """
    )
)

# After creation, my_function.role contains the resolved ARN string
```

```
Role role = Role.Builder.create(this, "MyRole")
    .assumedBy(new ServicePrincipal("lambda.amazonaws.com"))
    .managedPolicies(Arrays.asList(
        ManagedPolicy.fromAwsManagedPolicyName(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    ))
    .build();

CfnFunction myFunction = CfnFunction.Builder.create(this, "HelloWorldFunction")
    .runtime("nodejs24.x")
    .role(role)  // CDK resolves to role ARN automatically
    .handler("index.handler")
    .code(CfnFunction.CodeProperty.builder()
        .zipFile(
            "exports.handler = async function(event) {" +
            "  return {" +
            "    statusCode: 200," +
            "    body: JSON.stringify('Hello World!')," +
            "  };" +
            "};")
        .build())
    .build();

// After creation, myFunction.getRole() contains the resolved ARN string
```

```
var role = new Role(this, "MyRole", new RoleProps
{
    AssumedBy = new ServicePrincipal("lambda.amazonaws.com"),
    ManagedPolicies = new[]
    {
        ManagedPolicy.FromAwsManagedPolicyName(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    }
});

var myFunction = new CfnFunction(this, "HelloWorldFunction", new CfnFunctionProps
{
    Runtime = "nodejs24.x",
    Role = role,  // CDK resolves to role ARN automatically
    Handler = "index.handler",
    Code = new CfnFunction.CodeProperty
    {
        ZipFile = @"
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
        "
    }
});

// After creation, myFunction.Role contains the resolved ARN string
```

```
role := awsiam.NewRole(stack, jsii.String("MyRole"), &awsiam.RoleProps{
	AssumedBy: awsiam.NewServicePrincipal(jsii.String("lambda.amazonaws.com"), nil),
	ManagedPolicies: &[]awsiam.IManagedPolicy{
		awsiam.ManagedPolicy_FromAwsManagedPolicyName(jsii.String("service-role/AWSLambdaBasicExecutionRole")),
	},
})

myFunction := awslambda.NewCfnFunction(stack, jsii.String("HelloWorldFunction"), &awslambda.CfnFunctionProps{
	Runtime: jsii.String("nodejs24.x"),
	Role:    role, // CDK resolves to role ARN automatically
	Handler: jsii.String("index.handler"),
	Code: &awslambda.CfnFunction_CodeProperty{
		ZipFile: jsii.String(`
		exports.handler = async function(event) {
		  return {
		    statusCode: 200,
		    body: JSON.stringify('Hello World!'),
		  };
		};
		`),
	},
})

// After creation, *myFunction.Role() contains the resolved ARN string
```

### Lavorare con costrutti L2
<a name="constructs-using"></a>

Nell'esempio seguente, definiamo un bucket Amazon S3 creando un oggetto dal costrutto L2: [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html)

**Example**  

```
import * as s3 from 'aws-cdk-lib/aws-s3';

// "this" is HelloCdkStack
new s3.Bucket(this, 'MyFirstBucket', {
  versioned: true
});
```

```
const s3 = require('aws-cdk-lib/aws-s3');

// "this" is HelloCdkStack
new s3.Bucket(this, 'MyFirstBucket', {
  versioned: true
});
```

```
import aws_cdk.aws_s3 as s3

# "self" is HelloCdkStack
s3.Bucket(self, "MyFirstBucket", versioned=True)
```

```
import software.amazon.awscdk.services.s3.*;

public class HelloCdkStack extends Stack {
    public HelloCdkStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public HelloCdkStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        Bucket.Builder.create(this, "MyFirstBucket")
                .versioned(true).build();
    }
}
```

```
using Amazon.CDK.AWS.S3;

// "this" is HelloCdkStack
new Bucket(this, "MyFirstBucket", new BucketProps
{
    Versioned = true
});
```

```
import (
	"github.com/aws/aws-cdk-go/awscdk/v2/awss3"
	"github.com/aws/jsii-runtime-go"
)

// stack is HelloCdkStack
awss3.NewBucket(stack, jsii.String("MyFirstBucket"), &awss3.BucketProps{
		Versioned: jsii.Bool(true),
	})
```

 `MyFirstBucket`non è il nome del bucket che crea. AWS CloudFormation È un identificatore logico assegnato al nuovo costrutto nel contesto dell'app CDK. Il valore [PhysicalName](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Resource.html#physicalname) verrà utilizzato per denominare la risorsa. AWS CloudFormation 

## Lavorare con costrutti di terze parti
<a name="constructs-work-third"></a>

 [Construct Hub](https://constructs.dev/search?q=&cdk=aws-cdk&cdkver=2&sort=downloadsDesc&offset=0) è una risorsa che consente di scoprire costrutti aggiuntivi forniti da AWS terze parti e dalla comunità CDK open source.

### Scrivere i propri costrutti
<a name="constructs-author"></a>

Oltre a utilizzare costrutti esistenti, puoi anche scrivere i tuoi costrutti e consentire a chiunque di utilizzarli nelle proprie app. Tutti i costrutti sono uguali nel CDK. AWS I costrutti della AWS Construct Library vengono trattati allo stesso modo dei costrutti di una libreria di terze parti pubblicata tramite, o. NPM Maven PyPI Anche i costrutti pubblicati nell'archivio di pacchetti interno dell'azienda vengono trattati allo stesso modo.

Per dichiarare un nuovo costrutto, create una classe che estenda la classe base [Construct](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html) nel `constructs` pacchetto, quindi seguite lo schema per gli argomenti dell'inizializzatore.

L'esempio seguente mostra come dichiarare un costrutto che rappresenta un bucket Amazon S3. Il bucket S3 invia una notifica Amazon Simple Notification Service (Amazon SNS) ogni volta che qualcuno carica un file al suo interno.

**Example**  

```
export interface NotifyingBucketProps {
  prefix?: string;
}

export class NotifyingBucket extends Construct {
  constructor(scope: Construct, id: string, props: NotifyingBucketProps = {}) {
    super(scope, id);
    const bucket = new s3.Bucket(this, 'bucket');
    const topic = new sns.Topic(this, 'topic');
    bucket.addObjectCreatedNotification(new s3notify.SnsDestination(topic),
      { prefix: props.prefix });
  }
}
```

```
class NotifyingBucket extends Construct {
  constructor(scope, id, props = {}) {
    super(scope, id);
    const bucket = new s3.Bucket(this, 'bucket');
    const topic = new sns.Topic(this, 'topic');
    bucket.addObjectCreatedNotification(new s3notify.SnsDestination(topic),
      { prefix: props.prefix });
  }
}

module.exports = { NotifyingBucket }
```

```
class NotifyingBucket(Construct):

    def __init__(self, scope: Construct, id: str, *, prefix=None):
        super().__init__(scope, id)
        bucket = s3.Bucket(self, "bucket")
        topic = sns.Topic(self, "topic")
        bucket.add_object_created_notification(s3notify.SnsDestination(topic),
            s3.NotificationKeyFilter(prefix=prefix))
```

```
public class NotifyingBucket extends Construct {

    public NotifyingBucket(final Construct scope, final String id) {
        this(scope, id, null, null);
    }

    public NotifyingBucket(final Construct scope, final String id, final BucketProps props) {
        this(scope, id, props, null);
    }

    public NotifyingBucket(final Construct scope, final String id, final String prefix) {
        this(scope, id, null, prefix);
    }

    public NotifyingBucket(final Construct scope, final String id, final BucketProps props, final String prefix) {
        super(scope, id);

        Bucket bucket = new Bucket(this, "bucket");
        Topic topic = new Topic(this, "topic");
        if (prefix != null)
            bucket.addObjectCreatedNotification(new SnsDestination(topic),
                NotificationKeyFilter.builder().prefix(prefix).build());
     }
}
```

```
public class NotifyingBucketProps : BucketProps
{
    public string Prefix { get; set; }
}

public class NotifyingBucket : Construct
{
    public NotifyingBucket(Construct scope, string id, NotifyingBucketProps props = null) : base(scope, id)
    {
        var bucket = new Bucket(this, "bucket");
        var topic = new Topic(this, "topic");
        bucket.AddObjectCreatedNotification(new SnsDestination(topic), new NotificationKeyFilter
        {
            Prefix = props?.Prefix
        });
    }
}
```

```
type NotifyingBucketProps struct {
	awss3.BucketProps
	Prefix *string
}

func NewNotifyingBucket(scope constructs.Construct, id *string, props *NotifyingBucketProps) awss3.Bucket {
	var bucket awss3.Bucket
	if props == nil {
		bucket = awss3.NewBucket(scope, jsii.String(*id+"Bucket"), nil)
	} else {
		bucket = awss3.NewBucket(scope, jsii.String(*id+"Bucket"), &props.BucketProps)
	}
	topic := awssns.NewTopic(scope, jsii.String(*id+"Topic"), nil)
	if props == nil {
		bucket.AddObjectCreatedNotification(awss3notifications.NewSnsDestination(topic))
	} else {
		bucket.AddObjectCreatedNotification(awss3notifications.NewSnsDestination(topic), &awss3.NotificationKeyFilter{
			Prefix: props.Prefix,
		})
	}
	return bucket
}
```

**Nota**  
Il nostro `NotifyingBucket` costrutto non eredita da, ma piuttosto da. `Bucket` `Construct` Utilizziamo la composizione, non l'ereditarietà, per raggruppare un bucket Amazon S3 e un argomento Amazon SNS. In generale, la composizione è preferita all'ereditarietà quando si sviluppano costrutti CDK. AWS 

Il `NotifyingBucket` costruttore ha una tipica firma del costrutto:,, e. `scope` `id` `props` L'ultimo argomento,`props`, è facoltativo (ottiene il valore predefinito`{}`) perché tutti gli oggetti di scena sono opzionali. (La `Construct` classe base non accetta `props` argomenti.) Puoi definire un'istanza di questo costrutto nella tua app senza`props`, ad esempio:

**Example**  

```
new NotifyingBucket(this, 'MyNotifyingBucket');
```

```
new NotifyingBucket(this, 'MyNotifyingBucket');
```

```
NotifyingBucket(self, "MyNotifyingBucket")
```

```
new NotifyingBucket(this, "MyNotifyingBucket");
```

```
new NotifyingBucket(this, "MyNotifyingBucket");
```

```
NewNotifyingBucket(stack, jsii.String("MyNotifyingBucket"), nil)
```

Oppure puoi usare `props` (in Java, un parametro aggiuntivo) per specificare il prefisso del percorso su cui filtrare, ad esempio:

**Example**  

```
new NotifyingBucket(this, 'MyNotifyingBucket', { prefix: 'images/' });
```

```
new NotifyingBucket(this, 'MyNotifyingBucket', { prefix: 'images/' });
```

```
NotifyingBucket(self, "MyNotifyingBucket", prefix="images/")
```

```
new NotifyingBucket(this, "MyNotifyingBucket", "/images");
```

```
new NotifyingBucket(this, "MyNotifyingBucket", new NotifyingBucketProps
{
    Prefix = "/images"
});
```

```
NewNotifyingBucket(stack, jsii.String("MyNotifyingBucket"), &NotifyingBucketProps{
	Prefix: jsii.String("images/"),
})
```

In genere, dovresti anche esporre alcune proprietà o metodi sui tuoi costrutti. Non è molto utile avere un argomento nascosto dietro il costrutto, perché gli utenti del costrutto non sono in grado di sottoscriverlo. L'aggiunta di una `topic` proprietà consente ai consumatori di accedere all'argomento interno, come mostrato nell'esempio seguente:

**Example**  

```
export class NotifyingBucket extends Construct {
  public readonly topic: sns.Topic;

  constructor(scope: Construct, id: string, props: NotifyingBucketProps) {
    super(scope, id);
    const bucket = new s3.Bucket(this, 'bucket');
    this.topic = new sns.Topic(this, 'topic');
    bucket.addObjectCreatedNotification(new s3notify.SnsDestination(this.topic), { prefix: props.prefix });
  }
}
```

```
class NotifyingBucket extends Construct {

  constructor(scope, id, props) {
    super(scope, id);
    const bucket = new s3.Bucket(this, 'bucket');
    this.topic = new sns.Topic(this, 'topic');
    bucket.addObjectCreatedNotification(new s3notify.SnsDestination(this.topic), { prefix: props.prefix });
  }
}

module.exports = { NotifyingBucket };
```

```
class NotifyingBucket(Construct):

    def __init__(self, scope: Construct, id: str, *, prefix=None, **kwargs):
        super().__init__(scope, id)
        bucket = s3.Bucket(self, "bucket")
        self.topic = sns.Topic(self, "topic")
        bucket.add_object_created_notification(s3notify.SnsDestination(self.topic),
            s3.NotificationKeyFilter(prefix=prefix))
```

```
public class NotifyingBucket extends Construct {

    public Topic topic = null;

    public NotifyingBucket(final Construct scope, final String id) {
        this(scope, id, null, null);
    }

    public NotifyingBucket(final Construct scope, final String id, final BucketProps props) {
        this(scope, id, props, null);
    }

    public NotifyingBucket(final Construct scope, final String id, final String prefix) {
        this(scope, id, null, prefix);
    }

    public NotifyingBucket(final Construct scope, final String id, final BucketProps props, final String prefix) {
        super(scope, id);

        Bucket bucket = new Bucket(this, "bucket");
        topic = new Topic(this, "topic");
        if (prefix != null)
            bucket.addObjectCreatedNotification(new SnsDestination(topic),
                NotificationKeyFilter.builder().prefix(prefix).build());
     }
}
```

```
public class NotifyingBucket : Construct
{
    public readonly Topic topic;

    public NotifyingBucket(Construct scope, string id, NotifyingBucketProps props = null) : base(scope, id)
    {
        var bucket = new Bucket(this, "bucket");
        topic = new Topic(this, "topic");
        bucket.AddObjectCreatedNotification(new SnsDestination(topic), new NotificationKeyFilter
        {
            Prefix = props?.Prefix
        });
    }
}
```
Per farlo in Go, avremo bisogno di un po' di tubature extra. La nostra `NewNotifyingBucket` funzione originale ha restituito un`awss3.Bucket`. Dovremo estendere `Bucket` per includere un `topic` membro creando una `NotifyingBucket` struttura. La nostra funzione restituirà quindi questo tipo.  

```
type NotifyingBucket struct {
	awss3.Bucket
	topic awssns.Topic
}

func NewNotifyingBucket(scope constructs.Construct, id *string, props *NotifyingBucketProps) NotifyingBucket {
	var bucket awss3.Bucket
	if props == nil {
		bucket = awss3.NewBucket(scope, jsii.String(*id+"Bucket"), nil)
	} else {
		bucket = awss3.NewBucket(scope, jsii.String(*id+"Bucket"), &props.BucketProps)
	}
	topic := awssns.NewTopic(scope, jsii.String(*id+"Topic"), nil)
	if props == nil {
		bucket.AddObjectCreatedNotification(awss3notifications.NewSnsDestination(topic))
	} else {
		bucket.AddObjectCreatedNotification(awss3notifications.NewSnsDestination(topic), &awss3.NotificationKeyFilter{
			Prefix: props.Prefix,
		})
	}
	var nbucket NotifyingBucket
	nbucket.Bucket = bucket
	nbucket.topic = topic
	return nbucket
}
```

Ora i consumatori possono iscriversi all'argomento, ad esempio:

**Example**  

```
const queue = new sqs.Queue(this, 'NewImagesQueue');
const images = new NotifyingBucket(this, '/images');
images.topic.addSubscription(new sns_sub.SqsSubscription(queue));
```

```
const queue = new sqs.Queue(this, 'NewImagesQueue');
const images = new NotifyingBucket(this, '/images');
images.topic.addSubscription(new sns_sub.SqsSubscription(queue));
```

```
queue = sqs.Queue(self, "NewImagesQueue")
images = NotifyingBucket(self, prefix="Images")
images.topic.add_subscription(sns_sub.SqsSubscription(queue))
```

```
NotifyingBucket images = new NotifyingBucket(this, "MyNotifyingBucket", "/images");
images.topic.addSubscription(new SqsSubscription(queue));
```

```
var queue = new Queue(this, "NewImagesQueue");
var images = new NotifyingBucket(this, "MyNotifyingBucket", new NotifyingBucketProps
{
    Prefix = "/images"
});
images.topic.AddSubscription(new SqsSubscription(queue));
```

```
	queue := awssqs.NewQueue(stack, jsii.String("NewImagesQueue"), nil)
	images := NewNotifyingBucket(stack, jsii.String("MyNotifyingBucket"), &NotifyingBucketProps{
		Prefix: jsii.String("/images"),
	})
	images.topic.AddSubscription(awssnssubscriptions.NewSqsSubscription(queue, nil))
```

## Ulteriori informazioni
<a name="constructs-learn"></a>

Il video seguente fornisce una panoramica completa dei costrutti CDK e spiega come utilizzarli nelle app CDK.

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/PzU-i0rJPGw?rel=0/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/PzU-i0rJPGw?rel=0)


# Miscelazioni
<a name="mixins"></a>

I mixin sono funzionalità riutilizzabili che si applicano ai costrutti utilizzando il metodo. `.with()` Aggiungono funzionalità ai costrutti L1 (CloudFormation-level) e L2 (intent-based), come il controllo delle versioni, l'eliminazione automatica degli oggetti o il blocco dell'accesso pubblico. Ogni mixin funziona su una singola risorsa. Per connettere due risorse, usa invece [Facades.](facades.md)

Ogni mixin si rivolge a un tipo di risorsa specifico e prende il nome da quella risorsa. Ad esempio, è `BucketVersioning` destinato ai bucket Amazon S3. È possibile accedere ai mixin tramite lo spazio dei `mixins` nomi di ciascun modulo di servizio, ad esempio. `s3.mixins`

## Applica Mixins
<a name="mixins-basic"></a>

I mixin vengono applicati utilizzando il `.with()` metodo, disponibile su tutti i costrutti. Puoi concatenare più mixin:

**Example**  

```
import * as s3 from 'aws-cdk-lib/aws-s3';

const bucket = new s3.CfnBucket(this, 'MyBucket')
  .with(new s3.mixins.BucketVersioning())
  .with(new s3.mixins.BucketBlockPublicAccess());
```

```
const s3 = require('aws-cdk-lib/aws-s3');

const bucket = new s3.CfnBucket(this, 'MyBucket')
  .with(new s3.mixins.BucketVersioning())
  .with(new s3.mixins.BucketBlockPublicAccess());
```

```
import aws_cdk.aws_s3 as s3

bucket = s3.CfnBucket(self, "MyBucket") \
    .with_(s3.mixins.BucketVersioning()) \
    .with_(s3.mixins.BucketBlockPublicAccess())
```

```
import software.amazon.awscdk.services.s3.*;

CfnBucket bucket = new CfnBucket(this, "MyBucket");
bucket.with(new BucketVersioning());
bucket.with(new BucketBlockPublicAccess());
```

```
using Amazon.CDK.AWS.S3;

var bucket = new CfnBucket(this, "MyBucket");
bucket.With(new BucketVersioning());
bucket.With(new BucketBlockPublicAccess());
```

```
bucket := awss3.NewCfnBucket(stack, jsii.String("MyBucket"), nil)
bucket.With(awss3.NewBucketVersioning())
bucket.With(awss3.NewBucketBlockPublicAccess())
```

Ogni mixin dichiara quali tipi di risorse supporta. Se applicate un mixin a un costrutto che non supporta, viene ignorato silenziosamente. Ciò significa che potete applicare in modo sicuro i mixin in modo ampio senza preoccuparvi dei disallineamenti tra i tipi. [Se devi assicurarti che venga applicato un mixin, usa o. `requireAll()``requireAny()`](#mixins-advanced)

## Usa Mixins con costrutti L1 e L2
<a name="mixins-l1-l2"></a>

I mixin funzionano con i costrutti L1 e L2. Quando applicate un mixin a un costrutto L2, si applica anche alla risorsa L1 sottostante.

L'esempio seguente mostra come applicare i mixin a entrambi i costrutti L1 e L2:

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

// Using a mixin with an L1 construct
new s3.CfnBucket(this, 'L1Bucket')
  .with(new s3.mixins.BucketVersioning());

// Using a mixin with an L2 construct
new s3.Bucket(this, 'L2Bucket', {
  removalPolicy: cdk.RemovalPolicy.DESTROY,
}).with(new s3.mixins.BucketAutoDeleteObjects());
```

```
const cdk = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');

// Using a mixin with an L1 construct
new s3.CfnBucket(this, 'L1Bucket')
  .with(new s3.mixins.BucketVersioning());

// Using a mixin with an L2 construct
new s3.Bucket(this, 'L2Bucket', {
  removalPolicy: cdk.RemovalPolicy.DESTROY,
}).with(new s3.mixins.BucketAutoDeleteObjects());
```

```
import aws_cdk as cdk
import aws_cdk.aws_s3 as s3

# Using a mixin with an L1 construct
s3.CfnBucket(self, "L1Bucket") \
    .with_(s3.mixins.BucketVersioning())

# Using a mixin with an L2 construct
s3.Bucket(self, "L2Bucket",
    removal_policy=cdk.RemovalPolicy.DESTROY,
).with_(s3.mixins.BucketAutoDeleteObjects())
```

```
import software.amazon.awscdk.*;
import software.amazon.awscdk.services.s3.*;

// Using a mixin with an L1 construct
CfnBucket l1Bucket = new CfnBucket(this, "L1Bucket");
l1Bucket.with(new BucketVersioning());

// Using a mixin with an L2 construct
Bucket l2Bucket = Bucket.Builder.create(this, "L2Bucket")
        .removalPolicy(RemovalPolicy.DESTROY)
        .build();
l2Bucket.with(new BucketAutoDeleteObjects());
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

// Using a mixin with an L1 construct
var l1Bucket = new CfnBucket(this, "L1Bucket");
l1Bucket.With(new BucketVersioning());

// Using a mixin with an L2 construct
var l2Bucket = new Bucket(this, "L2Bucket", new BucketProps
{
    RemovalPolicy = RemovalPolicy.DESTROY
});
l2Bucket.With(new BucketAutoDeleteObjects());
```

```
l1Bucket := awss3.NewCfnBucket(stack, jsii.String("L1Bucket"), nil)
l1Bucket.With(awss3.NewBucketVersioning())

l2Bucket := awss3.NewBucket(stack, jsii.String("L2Bucket"), &awss3.BucketProps{
    RemovalPolicy: awscdk.RemovalPolicy_DESTROY,
})
l2Bucket.With(awss3.NewBucketAutoDeleteObjects())
```

## Mixins e proprietà di costruzione
<a name="mixins-vs-props"></a>

I mixin e le proprietà di costruzione funzionano insieme. Le proprietà del costrutto L2 impostano una risorsa al momento della creazione. I mixin possono essere applicati in qualsiasi momento.

Utilizzate le proprietà del costrutto L2 quando  
Stai utilizzando un costrutto L2 e la proprietà che ti serve è disponibile. Questo è l'approccio più semplice.

Usa Mixins quando  
+ Stai lavorando con un costrutto L1 e desideri funzionalità simili a L2.
+ Volete aggiungere una funzionalità a un costrutto L2 che non è disponibile come proprietà.
+ Desiderate applicare la stessa funzionalità a più costrutti di tipi diversi.

I mixin non sostituiscono le proprietà del costrutto. Non possono rendere facoltativa una proprietà obbligatoria o modificare i valori predefiniti.

## Applica Mixins a più costrutti
<a name="mixins-advanced"></a>

L'`Mixins.of()`API offre un maggiore controllo sul modo in cui i mixin vengono applicati in un ambito. Invece di richiamare `.with()` singoli costrutti, puoi applicare un mixin a tutti i costrutti corrispondenti in uno stack o in un ambito contemporaneamente:

**Example**  

```
import { Mixins } from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

// Apply to all supported constructs in the stack
Mixins.of(stack).apply(new s3.mixins.BucketVersioning());
```

```
const { Mixins } = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');

// Apply to all supported constructs in the stack
Mixins.of(stack).apply(new s3.mixins.BucketVersioning());
```

```
from aws_cdk import Mixins
import aws_cdk.aws_s3 as s3

# Apply to all supported constructs in the stack
Mixins.of(stack).apply(s3.mixins.BucketVersioning())
```

```
import software.amazon.awscdk.Mixins;
import software.amazon.awscdk.services.s3.*;

// Apply to all supported constructs in the stack
Mixins.of(stack).apply(new BucketVersioning());
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

// Apply to all supported constructs in the stack
Mixins.Of(stack).Apply(new BucketVersioning());
```

```
awscdk.Mixins_Of(stack, nil).Apply(awss3.NewBucketVersioning())
```

Per impostazione predefinita, i costrutti che non supportano il mixin vengono ignorati silenziosamente. Si usa `requireAll()` per affermare che il mixin viene applicato a ogni costrutto della selezione o per affermare che viene applicato `requireAny()` ad almeno uno. Questo è utile per far sì che le risorse abbiano una configurazione richiesta:

**Example**  

```
// Throws an error if any construct in the scope doesn't support the mixin
Mixins.of(stack)
  .requireAll()
  .apply(new s3.mixins.BucketVersioning());
```

```
// Throws an error if any construct in the scope doesn't support the mixin
Mixins.of(stack)
  .requireAll()
  .apply(new s3.mixins.BucketVersioning());
```

```
# Throws an error if any construct in the scope doesn't support the mixin
Mixins.of(stack) \
    .require_all() \
    .apply(s3.mixins.BucketVersioning())
```

```
// Throws an error if any construct in the scope doesn't support the mixin
Mixins.of(stack)
        .requireAll()
        .apply(new BucketVersioning());
```

```
// Throws an error if any construct in the scope doesn't support the mixin
Mixins.Of(stack)
    .RequireAll()
    .Apply(new BucketVersioning());
```

```
awscdk.Mixins_Of(stack, nil).RequireAll().Apply(awss3.NewBucketVersioning())
```

## Miscele e aspetti
<a name="mixins-aspects"></a>

Mixin e [Aspects](aspects.md) sono correlati ma hanno scopi diversi:
+  **I mixin** vengono applicati immediatamente quando si chiama. `.with()` Scegliete esattamente a quali costrutti applicarli.
+  **Gli aspetti** si applicano durante la sintesi a tutti i costrutti di un ambito. Usali per politiche e controlli generali.

Usa Mixins per aggiungere una funzionalità a costrutti specifici. Usa Aspects per applicare regole o applicare modifiche all'intera applicazione.

## Risorse correlate
<a name="mixins-related"></a>
+  [Facades](facades.md): Connect le risorse con i presidi IAM e altri servizi.
+  [Aspetti](aspects.md): applica modifiche o convalida costrutti nell'intera applicazione.
+  [Costrutti](constructs.md): scopri i costrutti L1, L2 e L3.
+  [Personalizza i costrutti: personalizza](cfn-layer.md) i costrutti con portelli di fuga e sostituzioni non elaborate.

# facciate
<a name="facades"></a>

Le facciate sono classi che collegano una risorsa con altre parti dell'applicazione. Ogni Facade si rivolge a un tipo di risorsa. Ad esempio, la classe è denominata `BucketGrants` perché concede l'accesso ai bucket Amazon S3. Le facciate funzionano sia con costrutti L1 (CloudFormation-level) che L2 (intent based).

Alcune facciate sono generate e pronte all'uso per la maggior parte delle risorse, come le classi di metriche e riflessioni. Altre sono create manualmente per risorse che richiedono una logica personalizzata, come le classi Grants.

## Classi Grants
<a name="facades-grants"></a>

Le facciate più utilizzate sono le classi Grants. Consentono di concedere l'accesso alle AWS risorse utilizzando metodi semplici. Ad esempio, puoi utilizzarlo `BucketGrants` per i bucket Amazon S3 e per argomenti di Amazon `TopicGrants` SNS.

I costrutti L2 hanno una proprietà per un facile accesso`grants`. Potete anche creare una classe Grants da un costrutto L1 usando il relativo metodo factory. L'esempio seguente mostra entrambi gli approcci:

**Example**  

```
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as iam from 'aws-cdk-lib/aws-iam';

// myRole is an IAM role defined elsewhere in your app

// Using grants on an L2 construct (via the grants property)
const l2Bucket = new s3.Bucket(this, 'L2Bucket');
l2Bucket.grants.read(myRole);

// Using grants on an L1 construct (via the factory method)
const l1Bucket = new s3.CfnBucket(this, 'L1Bucket');
s3.BucketGrants.fromBucket(l1Bucket).read(myRole);
```

```
const s3 = require('aws-cdk-lib/aws-s3');
const iam = require('aws-cdk-lib/aws-iam');

// myRole is an IAM role defined elsewhere in your app

// Using grants on an L2 construct (via the grants property)
const l2Bucket = new s3.Bucket(this, 'L2Bucket');
l2Bucket.grants.read(myRole);

// Using grants on an L1 construct (via the factory method)
const l1Bucket = new s3.CfnBucket(this, 'L1Bucket');
s3.BucketGrants.fromBucket(l1Bucket).read(myRole);
```

```
import aws_cdk.aws_s3 as s3
import aws_cdk.aws_iam as iam

# my_role is an IAM role defined elsewhere in your app

# Using grants on an L2 construct (via the grants property)
l2_bucket = s3.Bucket(self, "L2Bucket")
l2_bucket.grants.read(my_role)

# Using grants on an L1 construct (via the factory method)
l1_bucket = s3.CfnBucket(self, "L1Bucket")
s3.BucketGrants.from_bucket(l1_bucket).read(my_role)
```

```
import software.amazon.awscdk.services.s3.*;
import software.amazon.awscdk.services.iam.*;

// myRole is an IAM role defined elsewhere in your app

// Using grants on an L2 construct (via the grants property)
Bucket l2Bucket = new Bucket(this, "L2Bucket");
l2Bucket.getGrants().read(myRole);

// Using grants on an L1 construct (via the factory method)
CfnBucket l1Bucket = new CfnBucket(this, "L1Bucket");
BucketGrants.fromBucket(l1Bucket).read(myRole);
```

```
using Amazon.CDK.AWS.S3;
using Amazon.CDK.AWS.IAM;

// myRole is an IAM role defined elsewhere in your app

// Using grants on an L2 construct (via the grants property)
var l2Bucket = new Bucket(this, "L2Bucket");
l2Bucket.Grants.Read(myRole);

// Using grants on an L1 construct (via the factory method)
var l1Bucket = new CfnBucket(this, "L1Bucket");
BucketGrants.FromBucket(l1Bucket).Read(myRole);
```

```
import (
	"github.com/aws/jsii-runtime-go"
	awss3 "github.com/aws/aws-cdk-go/awscdk/v2/awss3"
)

// myRole is an IAM role defined elsewhere in your app

l2Bucket := awss3.NewBucket(stack, jsii.String("L2Bucket"), nil)
l2Bucket.Grants().Read(myRole, nil)

l1Bucket := awss3.NewCfnBucket(stack, jsii.String("L1Bucket"), nil)
awss3.BucketGrants_FromBucket(l1Bucket).Read(myRole, nil)
```

[Per ulteriori informazioni su sovvenzioni e autorizzazioni, vedere Sovvenzioni.](permissions.md#permissions-grants)

## Usa Facades con Mixins
<a name="facades-mixins-together"></a>

Puoi combinare Facades con [Mixins per ottenere un'esperienza completa simile](mixins.md) a L2 sui costrutti L1. Usa Mixins per configurare la risorsa e Facades per concedere l'accesso:

**Example**  

```
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as iam from 'aws-cdk-lib/aws-iam';

// Configure the resource with Mixins
const bucket = new s3.CfnBucket(this, 'MyBucket')
  .with(new s3.mixins.BucketVersioning())
  .with(new s3.mixins.BucketBlockPublicAccess());

// Grant permissions using a Facade
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
});
s3.BucketGrants.fromBucket(bucket).read(role);
```

```
const s3 = require('aws-cdk-lib/aws-s3');
const iam = require('aws-cdk-lib/aws-iam');

// Configure the resource with Mixins
const bucket = new s3.CfnBucket(this, 'MyBucket')
  .with(new s3.mixins.BucketVersioning())
  .with(new s3.mixins.BucketBlockPublicAccess());

// Grant permissions using a Facade
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
});
s3.BucketGrants.fromBucket(bucket).read(role);
```

```
import aws_cdk.aws_s3 as s3
import aws_cdk.aws_iam as iam

# Configure the resource with Mixins
bucket = s3.CfnBucket(self, "MyBucket") \
    .with_(s3.mixins.BucketVersioning()) \
    .with_(s3.mixins.BucketBlockPublicAccess())

# Grant permissions using a Facade
role = iam.Role(self, "MyRole",
    assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"),
)
s3.BucketGrants.from_bucket(bucket).read(role)
```

```
import software.amazon.awscdk.services.s3.*;
import software.amazon.awscdk.services.iam.*;

// Configure the resource with Mixins
CfnBucket bucket = new CfnBucket(this, "MyBucket");
bucket.with(new BucketVersioning());
bucket.with(new BucketBlockPublicAccess());

// Grant permissions using a Facade
Role role = Role.Builder.create(this, "MyRole")
        .assumedBy(new ServicePrincipal("lambda.amazonaws.com"))
        .build();
BucketGrants.fromBucket(bucket).read(role);
```

```
using Amazon.CDK.AWS.S3;
using Amazon.CDK.AWS.IAM;

// Configure the resource with Mixins
var bucket = new CfnBucket(this, "MyBucket");
bucket.With(new BucketVersioning());
bucket.With(new BucketBlockPublicAccess());

// Grant permissions using a Facade
var role = new Role(this, "MyRole", new RoleProps
{
    AssumedBy = new ServicePrincipal("lambda.amazonaws.com")
});
BucketGrants.FromBucket(bucket).Read(role);
```

```
bucket := awss3.NewCfnBucket(stack, jsii.String("MyBucket"), nil)
bucket.With(awss3.NewBucketVersioning())
bucket.With(awss3.NewBucketBlockPublicAccess())

role := awsiam.NewRole(stack, jsii.String("MyRole"), &awsiam.RoleProps{
    AssumedBy: awsiam.NewServicePrincipal(jsii.String("lambda.amazonaws.com"), nil),
})
awss3.BucketGrants_FromBucket(bucket).Read(role, nil)
```

## Risorse correlate
<a name="facades-related"></a>
+  [Mixins](mixins.md): aggiungi funzionalità riutilizzabili ai costrutti L1 e L2.
+  [Sovvenzioni: concede autorizzazioni](permissions.md#permissions-grants) tra le risorse.
+  [Costrutti](constructs.md): scopri i costrutti L1, L2 e L3.

# Ambienti per il AWS CDK
<a name="environments"></a>

Un ambiente è composto dall' AWS account e dalla AWS regione in cui viene distribuito uno stack AWS Cloud Development Kit (AWS CDK).

 ** AWS account**   
Quando crei un AWS account, ricevi un ID account. Questo ID è un numero di 12 cifre, ad esempio **012345678901**, che identifica in modo univoco l'account. *Per ulteriori informazioni, consulta [Visualizza AWS](https://docs.aws.amazon.com/accounts/latest/reference/manage-acct-identifiers.html) gli identificatori degli account nella Guida di riferimento alla gestione degli account. AWS *

 ** AWS Regione**   
 AWS Le regioni vengono denominate utilizzando una combinazione di posizione geografica e un numero che rappresenta una zona di disponibilità nella regione. Ad esempio, ** us-east-1 **rappresenta una zona di disponibilità nella regione Stati Uniti orientali (Virginia settentrionale). Per ulteriori informazioni sulle AWS regioni, consulta [Regioni e zone di disponibilità](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/). Per un elenco dei codici regionali, consulta [Endpoint regionali](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints) nella Guida *di riferimento AWS generale*.

Il AWS CDK può determinare gli ambienti in base alle credenziali e ai file di configurazione. Questi file possono essere creati e gestiti con l'interfaccia a riga di AWS comando (AWS CLI). Di seguito è riportato un esempio di base di questi file:

 **File di credenziali**   

```
[default]
aws_access_key_id=ASIAIOSFODNN7EXAMPLE
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
aws_session_token = IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZVERYLONGSTRINGEXAMPLE

[user1]
aws_access_key_id=ASIAI44QH8DHBEXAMPLE
aws_secret_access_key=je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY
aws_session_token = fcZib3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZVERYLONGSTRINGEXAMPLE
```

 **File di configurazione**   

```
[default]
region=us-west-2
output=json

[profile user1]
region=us-east-1
output=text
```

È possibile passare le informazioni sull'ambiente da questi file nel codice CDK tramite variabili di ambiente fornite dal CDK. Quando esegui un comando CDK CLI, ad esempio`cdk deploy`, fornisci il profilo dalle tue credenziali e dai file di configurazione da cui raccogliere informazioni sull'ambiente.

Di seguito è riportato un esempio di come specificare queste variabili di ambiente nel codice CDK:

```
new MyDevStack(app, 'dev', {
  env: {
    account: process.env.CDK_DEFAULT_ACCOUNT,
    region: process.env.CDK_DEFAULT_REGION
}});
```

Di seguito è riportato un esempio di trasferimento dei valori associati al `user1` profilo dalle credenziali e dai file di configurazione alla CLI CDK utilizzando l'opzione. `--profile` I valori di questi file verranno passati alle variabili di ambiente:

```
$ cdk deploy <myStack> --profile <user1>
```

Invece di utilizzare i valori delle credenziali e dei file di configurazione, potete anche codificare i valori di ambiente nel codice CDK. Di seguito è riportato un esempio:

```
const envEU = { account: '238383838383', region: 'eu-west-1' };
const envUSA = { account: '837873873873', region: 'us-west-2' };

new MyFirstStack(app, 'first-stack-us', { env: envUSA });
new MyFirstStack(app, 'first-stack-eu', { env: envEU });
```

## Ulteriori informazioni
<a name="environments-learn"></a>

Per iniziare a usare ambienti con AWS CDK, consulta [Configurare gli ambienti da usare](configure-env.md) con il CDK. AWS 

# AWS Avvio CDK
<a name="bootstrapping"></a>

 Il *bootstrapping* è il processo di preparazione dell' AWS ambiente per l'utilizzo con il AWS Cloud Development Kit (AWS CDK). Prima di distribuire uno stack CDK in un AWS ambiente, è necessario avviare l'ambiente.

## Che cos'è il bootstrap?
<a name="bootstrapping-what"></a>

Il bootstrap prepara l' AWS ambiente fornendo AWS risorse specifiche nell'ambiente utilizzate dal CDK. AWS *Queste risorse vengono comunemente chiamate risorse di bootstrap.* Queste includono i seguenti:
+  Bucket **Amazon Simple Storage Service (Amazon S3)**: utilizzato per archiviare i file di progetto CDK, come il codice della funzione AWS Lambda e le risorse.
+  Repository **Amazon Elastic Container Registry (Amazon ECR)**: utilizzato principalmente per archiviare Docker immagini.
+  AWS Ruoli **Identity and Access Management (IAM)**: configurati per concedere le autorizzazioni necessarie al CDK per eseguire AWS le distribuzioni. [Per ulteriori informazioni sui ruoli IAM creati durante il bootstrap, consulta Ruoli IAM creati durante il bootstrap.](bootstrapping-env.md#bootstrapping-env-roles)

## Come funziona il bootstrap?
<a name="bootstrapping-how"></a>

Le risorse e la loro configurazione utilizzate dal CDK sono definite in un modello. AWS CloudFormation Questo modello viene creato e gestito dal team CDK. Per la versione più recente di questo modello, consulta [https://github.com/aws/aws-cdk-cli/blob/main/packages/aws-cdk/lib/api/bootstrap/bootstrap-template.yaml](https://github.com/aws/aws-cdk-cli/blob/main/packages/aws-cdk/lib/api/bootstrap/bootstrap-template.yaml)la * aws-cdk-cli GitHub archivio. *

Per avviare un ambiente, si utilizza il comando AWS CDK Command Line Interface (AWS CDK CLI). `cdk bootstrap` *La CLI CDK recupera il modello e lo distribuisce come stack, AWS CloudFormation noto come stack bootstrap.* Per impostazione predefinita, il nome dello stack è. `CDKToolkit` Implementando questo modello, effettua il CloudFormation provisioning delle risorse del tuo ambiente. Dopo la distribuzione, lo stack di bootstrap verrà visualizzato nella AWS CloudFormation console del tuo ambiente.

È inoltre possibile personalizzare il bootstrap modificando il modello o utilizzando le opzioni della CLI CDK con il comando. `cdk bootstrap`

 AWS gli ambienti sono indipendenti. Ogni ambiente che si desidera utilizzare con il AWS CDK deve prima essere avviato.

## Ulteriori informazioni
<a name="bootstrapping-learn"></a>

Per istruzioni su come avviare il vostro ambiente, consultate [Bootstrap your environment](bootstrapping-env.md) for use with the CDK. AWS 

# Risorse e AWS CDK
<a name="resources"></a>

 Le *risorse* sono ciò che configuri per utilizzare AWS i servizi nelle tue applicazioni. Le risorse sono una funzionalità di AWS CloudFormation. Configurando le risorse e le relative proprietà in un AWS CloudFormation modello, è possibile implementarlo per AWS CloudFormation eseguire il provisioning delle risorse. Con il AWS Cloud Development Kit (AWS CDK), puoi configurare le risorse tramite costrutti. Quindi distribuisci l'app CDK, che prevede la sintesi di un AWS CloudFormation modello e la distribuzione per fornire le tue risorse. AWS CloudFormation 

## Configurazione delle risorse mediante costrutti
<a name="resources-configure"></a>

*Come descritto in [AWS CDK Constructs](constructs.md), il AWS CDK fornisce una ricca libreria di classi di costrutti, chiamati costrutti, che rappresentano tutte le risorse.* AWS 

Per creare un'istanza di una risorsa utilizzando il costrutto corrispondente, inserite l'ambito come primo argomento, l'ID logico del costrutto e un insieme di proprietà di configurazione (props). Ad esempio, ecco come creare una coda Amazon SQS con crittografia AWS KMS utilizzando il costrutto della [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_sqs.Queue.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_sqs.Queue.html)Construct Library. AWS 

**Example**  

```
import * as sqs from '@aws-cdk/aws-sqs';

new sqs.Queue(this, 'MyQueue', {
    encryption: sqs.QueueEncryption.KMS_MANAGED
});
```

```
const sqs = require('@aws-cdk/aws-sqs');

new sqs.Queue(this, 'MyQueue', {
    encryption: sqs.QueueEncryption.KMS_MANAGED
});
```

```
import aws_cdk.aws_sqs as sqs

sqs.Queue(self, "MyQueue", encryption=sqs.QueueEncryption.KMS_MANAGED)
```

```
import software.amazon.awscdk.services.sqs.*;

Queue.Builder.create(this, "MyQueue").encryption(
        QueueEncryption.KMS_MANAGED).build();
```

```
using Amazon.CDK.AWS.SQS;

new Queue(this, "MyQueue", new QueueProps
{
    Encryption = QueueEncryption.KMS_MANAGED
});
```

```
import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/jsii-runtime-go"
  sqs "github.com/aws/aws-cdk-go/awscdk/v2/awssqs"
)

sqs.NewQueue(stack, jsii.String("MyQueue"), &sqs.QueueProps{
  Encryption: sqs.QueueEncryption_KMS_MANAGED,
})
```

Alcuni oggetti di configurazione sono opzionali e in molti casi hanno valori predefiniti. In alcuni casi, tutti gli oggetti di scena sono opzionali e l'ultimo argomento può essere omesso completamente.

### Attributi delle risorse
<a name="resources-attributes"></a>

La maggior parte delle risorse della AWS Construct Library espongono gli attributi, che vengono risolti al momento della distribuzione da. AWS CloudFormation Gli attributi sono esposti sotto forma di proprietà sulle classi di risorse con il nome del tipo come prefisso. L'esempio seguente mostra come ottenere l'URL di una coda Amazon SQS utilizzando la proprietà (`queueUrl`Python:). `queue_url`

**Example**  

```
import * as sqs from '@aws-cdk/aws-sqs';

const queue = new sqs.Queue(this, 'MyQueue');
const url = queue.queueUrl; // => A string representing a deploy-time value
```

```
const sqs = require('@aws-cdk/aws-sqs');

const queue = new sqs.Queue(this, 'MyQueue');
const url = queue.queueUrl; // => A string representing a deploy-time value
```

```
import aws_cdk.aws_sqs as sqs

queue = sqs.Queue(self, "MyQueue")
url = queue.queue_url # => A string representing a deploy-time value
```

```
Queue queue = new Queue(this, "MyQueue");
String url = queue.getQueueUrl();    // => A string representing a deploy-time value
```

```
var queue = new Queue(this, "MyQueue");
var url = queue.QueueUrl; // => A string representing a deploy-time value
```

```
import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/jsii-runtime-go"
  sqs "github.com/aws/aws-cdk-go/awscdk/v2/awssqs"
)

queue := sqs.NewQueue(stack, jsii.String("MyQueue"), &sqs.QueueProps{})
url := queue.QueueUrl() // => A string representing a deploy-time value
```

Vedi [Tokens and the AWS CDK per informazioni su come il CDK](tokens.md) codifica gli attributi di deployment time come AWS stringhe.

## Riferimento delle risorse
<a name="resources-referencing"></a>

Quando configuri le risorse, dovrai spesso fare riferimento alle proprietà di un'altra risorsa. Di seguito vengono mostrati gli esempi:
+ Una risorsa Amazon Elastic Container Service (Amazon ECS) richiede un riferimento al cluster su cui viene eseguita.
+ Una CloudFront distribuzione Amazon richiede un riferimento al bucket Amazon Simple Storage Service (Amazon S3) contenente il codice sorgente.

Puoi fare riferimento alle risorse in uno dei seguenti modi:
+ Passando una risorsa definita nell'app CDK, nello stesso stack o in uno diverso
+ Passando un oggetto proxy che fa riferimento a una risorsa definita nell' AWS account, creata da un identificatore univoco della risorsa (ad esempio un ARN)

Se la proprietà di un costrutto rappresenta un costrutto per un'altra risorsa, il suo tipo è quello del tipo di interfaccia del costrutto. Ad esempio, il costrutto Amazon ECS accetta una proprietà `cluster` di tipo. `ecs.ICluster` Un altro esempio è il costrutto di CloudFront distribuzione che accetta una proprietà `sourceBucket` (Python`source_bucket`:) di tipo. `s3.IBucket`

È possibile passare direttamente qualsiasi oggetto risorsa del tipo corretto definito nella stessa app AWS CDK. L'esempio seguente definisce un cluster Amazon ECS e quindi lo utilizza per definire un servizio Amazon ECS.

**Example**  

```
const cluster = new ecs.Cluster(this, 'Cluster', { /*...*/ });

const service = new ecs.Ec2Service(this, 'Service', { cluster: cluster });
```

```
const cluster = new ecs.Cluster(this, 'Cluster', { /*...*/ });

const service = new ecs.Ec2Service(this, 'Service', { cluster: cluster });
```

```
cluster = ecs.Cluster(self, "Cluster")

service = ecs.Ec2Service(self, "Service", cluster=cluster)
```

```
Cluster cluster = new Cluster(this, "Cluster");
Ec2Service service = new Ec2Service(this, "Service",
        new Ec2ServiceProps.Builder().cluster(cluster).build());
```

```
var cluster = new Cluster(this, "Cluster");
var service = new Ec2Service(this, "Service", new Ec2ServiceProps { Cluster = cluster });
```

```
import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/jsii-runtime-go"
  ecs "github.com/aws/aws-cdk-go/awscdk/v2/awsecs"
)

cluster := ecs.NewCluster(stack, jsii.String("MyCluster"), &ecs.ClusterProps{})
service := ecs.NewEc2Service(stack, jsii.String("MyService"), &ecs.Ec2ServiceProps{
  Cluster: cluster,
})
```

### Riferimento a risorse in uno stack diverso
<a name="resource-stack"></a>

Puoi fare riferimento a risorse in uno stack diverso purché siano definite nella stessa app e si trovino nello stesso ambiente. AWS In genere viene utilizzato lo schema seguente:
+ Memorizza un riferimento al costrutto come attributo dello stack che produce la risorsa. (Per ottenere un riferimento allo stack del costrutto corrente, usa.) `Stack.of(this)`
+ Passa questo riferimento al costruttore dello stack che consuma la risorsa come parametro o proprietà. Lo stack di consumo lo passa quindi come proprietà a qualsiasi costrutto che ne abbia bisogno.

L'esempio seguente definisce uno stack. `stack1` Questo stack definisce un bucket Amazon S3 e memorizza un riferimento al costrutto del bucket come attributo dello stack. Quindi l'app definisce un secondo stack, `stack2` che accetta un bucket al momento dell'istanziazione. `stack2`potrebbe, ad esempio, definire una AWS Glue Table che utilizza il bucket per l'archiviazione dei dati.

**Example**  

```
const prod = { account: '123456789012', region: 'us-east-1' };

const stack1 = new StackThatProvidesABucket(app, 'Stack1', { env: prod });

// stack2 will take a property { bucket: IBucket }
const stack2 = new StackThatExpectsABucket(app, 'Stack2', {
  bucket: stack1.bucket,
  env: prod
});
```

```
const prod = { account: '123456789012', region: 'us-east-1' };

const stack1 = new StackThatProvidesABucket(app, 'Stack1', { env: prod });

// stack2 will take a property { bucket: IBucket }
const stack2 = new StackThatExpectsABucket(app, 'Stack2', {
  bucket: stack1.bucket,
  env: prod
});
```

```
prod = core.Environment(account="123456789012", region="us-east-1")

stack1 = StackThatProvidesABucket(app, "Stack1", env=prod)

# stack2 will take a property "bucket"
stack2 = StackThatExpectsABucket(app, "Stack2", bucket=stack1.bucket, env=prod)
```

```
// Helper method to build an environment
static Environment makeEnv(String account, String region) {
    return Environment.builder().account(account).region(region)
            .build();
}

App app = new App();

Environment prod = makeEnv("123456789012", "us-east-1");

StackThatProvidesABucket stack1 = new StackThatProvidesABucket(app, "Stack1",
        StackProps.builder().env(prod).build());

// stack2 will take an argument "bucket"
StackThatExpectsABucket stack2 = new StackThatExpectsABucket(app, "Stack,",
        StackProps.builder().env(prod).build(), stack1.bucket);
```

```
Amazon.CDK.Environment makeEnv(string account, string region)
{
    return new Amazon.CDK.Environment { Account = account, Region = region };
}

var prod = makeEnv(account: "123456789012", region: "us-east-1");

var stack1 = new StackThatProvidesABucket(app, "Stack1", new StackProps { Env = prod });

// stack2 will take a property "bucket"
var stack2 = new StackThatExpectsABucket(app, "Stack2", new StackProps { Env = prod,
    bucket = stack1.Bucket});
```

Se il AWS CDK determina che la risorsa si trova nello stesso ambiente, ma in uno stack diverso, sintetizza automaticamente AWS CloudFormation [le esportazioni](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-stack-exports.html) nello stack di produzione e nello stack di consumo per trasferire tali informazioni da uno [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html)stack all'altro.

#### Risoluzione dei deadlock legati alle dipendenze
<a name="resources-deadlock"></a>

Il riferimento a una risorsa da uno stack in uno stack diverso crea una dipendenza tra i due stack. In questo modo si assicura che vengano distribuiti nell'ordine corretto. Dopo l'implementazione degli stack, questa dipendenza è concreta. Dopodiché, la rimozione dell'uso della risorsa condivisa dallo stack di consumo può causare un errore di distribuzione imprevisto. Ciò accade se esiste un'altra dipendenza tra i due stack che li obbliga a essere distribuiti nello stesso ordine. Può avvenire anche senza dipendenza se lo stack di produzione viene semplicemente scelto dal CDK Toolkit per essere distribuito per primo. L' AWS CloudFormation esportazione viene rimossa dallo stack di produzione perché non è più necessaria, ma la risorsa esportata viene ancora utilizzata nello stack di consumo perché il relativo aggiornamento non è ancora stato distribuito. Pertanto, l'implementazione dello stack di produzione non riesce.

Per superare questa situazione di stallo, rimuovete l'uso della risorsa condivisa dallo stack di consumo. (Ciò rimuove l'esportazione automatica dallo stack di produzione.) Quindi, aggiungi manualmente la stessa esportazione allo stack di produzione utilizzando esattamente lo stesso ID logico dell'esportazione generata automaticamente. Rimuovi l'uso della risorsa condivisa nello stack di consumo e distribuisci entrambi gli stack. Quindi, rimuovi l'esportazione manuale (e la risorsa condivisa se non è più necessaria) e distribuisci nuovamente entrambi gli stack. Il [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#exportwbrvalueexportedvalue-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#exportwbrvalueexportedvalue-options)metodo dello stack è un modo conveniente per creare l'esportazione manuale per questo scopo. (Vedi l'esempio nel riferimento al metodo collegato.)

### Riferimento alle risorse presenti nel tuo account AWS
<a name="resources-external"></a>

Supponiamo che tu voglia utilizzare una risorsa già disponibile nel tuo AWS account nell'app AWS CDK. Potrebbe trattarsi di una risorsa definita tramite la console, un AWS SDK, direttamente con AWS CloudFormation o in un'altra AWS applicazione CDK. È possibile trasformare l'ARN della risorsa (o un altro attributo identificativo o gruppo di attributi) in un oggetto proxy. L'oggetto proxy funge da riferimento alla risorsa chiamando un metodo factory statico sulla classe della risorsa.

Quando create un proxy di questo tipo, la risorsa esterna **non** diventa parte dell'app AWS CDK. Pertanto, le modifiche apportate al proxy nell'app AWS CDK non influiscono sulla risorsa distribuita. Il proxy può, tuttavia, essere passato a qualsiasi metodo AWS CDK che richieda una risorsa di quel tipo.

L'esempio seguente mostra come fare riferimento a un bucket basato su un bucket esistente con l'ARN `arn:aws:s3:::amzn-s3-demo-bucket1` e a un Amazon Virtual Private Cloud basato su un VPC esistente con un ID specifico.

**Example**  

```
// Construct a proxy for a bucket by its name (must be same account)
s3.Bucket.fromBucketName(this, 'MyBucket', 'amzn-s3-demo-bucket1');

// Construct a proxy for a bucket by its full ARN (can be another account)
s3.Bucket.fromBucketArn(this, 'MyBucket', 'arn:aws:s3:::amzn-s3-demo-bucket1');

// Construct a proxy for an existing VPC from its attribute(s)
ec2.Vpc.fromVpcAttributes(this, 'MyVpc', {
  vpcId: 'vpc-1234567890abcde',
});
```

```
// Construct a proxy for a bucket by its name (must be same account)
s3.Bucket.fromBucketName(this, 'MyBucket', 'amzn-s3-demo-bucket1');

// Construct a proxy for a bucket by its full ARN (can be another account)
s3.Bucket.fromBucketArn(this, 'MyBucket', 'arn:aws:s3:::amzn-s3-demo-bucket1');

// Construct a proxy for an existing VPC from its attribute(s)
ec2.Vpc.fromVpcAttributes(this, 'MyVpc', {
  vpcId: 'vpc-1234567890abcde'
});
```

```
# Construct a proxy for a bucket by its name (must be same account)
s3.Bucket.from_bucket_name(self, "MyBucket", "amzn-s3-demo-bucket1")

# Construct a proxy for a bucket by its full ARN (can be another account)
s3.Bucket.from_bucket_arn(self, "MyBucket", "arn:aws:s3:::amzn-s3-demo-bucket1")

# Construct a proxy for an existing VPC from its attribute(s)
ec2.Vpc.from_vpc_attributes(self, "MyVpc", vpc_id="vpc-1234567890abcdef")
```

```
// Construct a proxy for a bucket by its name (must be same account)
Bucket.fromBucketName(this, "MyBucket", "amzn-s3-demo-bucket1");

// Construct a proxy for a bucket by its full ARN (can be another account)
Bucket.fromBucketArn(this, "MyBucket",
        "arn:aws:s3:::amzn-s3-demo-bucket1");

// Construct a proxy for an existing VPC from its attribute(s)
Vpc.fromVpcAttributes(this, "MyVpc", VpcAttributes.builder()
        .vpcId("vpc-1234567890abcdef").build());
```

```
// Construct a proxy for a bucket by its name (must be same account)
Bucket.FromBucketName(this, "MyBucket", "amzn-s3-demo-bucket1");

// Construct a proxy for a bucket by its full ARN (can be another account)
Bucket.FromBucketArn(this, "MyBucket", "arn:aws:s3:::amzn-s3-demo-bucket1");

// Construct a proxy for an existing VPC from its attribute(s)
Vpc.FromVpcAttributes(this, "MyVpc", new VpcAttributes
{
    VpcId = "vpc-1234567890abcdef"
});
```

```
// Define a proxy for a bucket by its name (must be same account)
s3.Bucket_FromBucketName(stack, jsii.String("MyBucket"), jsii.String("amzn-s3-demo-bucket1"))

// Define a proxy for a bucket by its full ARN (can be another account)
s3.Bucket_FromBucketArn(stack, jsii.String("MyBucket"), jsii.String("arn:aws:s3:::amzn-s3-demo-bucket1"))

// Define a proxy for an existing VPC from its attributes
ec2.Vpc_FromVpcAttributes(stack, jsii.String("MyVpc"), &ec2.VpcAttributes{
  VpcId: jsii.String("vpc-1234567890abcde"),
})
```

Diamo un'occhiata più da vicino al metodo. [https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-ec2.Vpc.html#static-fromwbrlookupscope-id-options](https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-ec2.Vpc.html#static-fromwbrlookupscope-id-options) Poiché il `ec2.Vpc` costrutto è complesso, ci sono molti modi in cui potresti voler selezionare il VPC da utilizzare con la tua app CDK. Per risolvere questo problema, il costrutto VPC ha un metodo `fromLookup` statico (Python:`from_lookup`) che consente di cercare il VPC Amazon desiderato interrogando il proprio account al momento della sintesi. AWS 

Per poter essere utilizzato`Vpc.fromLookup()`, il sistema che sintetizza lo stack deve avere accesso all'account proprietario di Amazon VPC. Questo perché CDK Toolkit interroga l'account per trovare l'Amazon VPC giusto al momento della sintesi.

[Inoltre, `Vpc.fromLookup()` funziona solo in stack definiti con un **account** e una **regione** espliciti (vedi Environments for the CDK). AWS](environments.md) Se il AWS CDK tenta di cercare un Amazon VPC da uno stack [indipendente dall'ambiente](stacks.md#stack-api), CDK Toolkit non sa in quale ambiente interrogare per trovare il VPC.

Devi fornire `Vpc.fromLookup()` attributi sufficienti per identificare in modo univoco un VPC nel AWS tuo account. Ad esempio, può esserci sempre un solo VPC predefinito, quindi è sufficiente specificare il VPC come predefinito.

**Example**  

```
ec2.Vpc.fromLookup(this, 'DefaultVpc', {
  isDefault: true
});
```

```
ec2.Vpc.fromLookup(this, 'DefaultVpc', {
  isDefault: true
});
```

```
ec2.Vpc.from_lookup(self, "DefaultVpc", is_default=True)
```

```
Vpc.fromLookup(this, "DefaultVpc", VpcLookupOptions.builder()
        .isDefault(true).build());
```

```
Vpc.FromLookup(this, id = "DefaultVpc", new VpcLookupOptions { IsDefault = true });
```

```
ec2.Vpc_FromLookup(this, jsii.String("DefaultVpc"), &ec2.VpcLookupOptions{
  IsDefault: jsii.Bool(true),
})
```

È inoltre possibile utilizzare la `tags` proprietà per eseguire query per VPCs tag. Puoi aggiungere tag ad Amazon VPC al momento della sua creazione utilizzando AWS CloudFormation o il AWS CDK. Puoi modificare i tag in qualsiasi momento dopo la creazione utilizzando la console di AWS gestione, la AWS CLI o un AWS SDK. Oltre ai tag che aggiungi tu stesso, il AWS CDK aggiunge automaticamente i seguenti tag a tutto ciò VPCs che crea.
+  **Nome**: il nome del VPC.
+  **aws-cdk:subnet-name — Il nome della sottorete**.
+  **aws-cdk:subnet-type — Il tipo di sottorete: pubblica**, privata o isolata.

**Example**  

```
ec2.Vpc.fromLookup(this, 'PublicVpc',
    {tags: {'aws-cdk:subnet-type': "Public"}});
```

```
ec2.Vpc.fromLookup(this, 'PublicVpc',
    {tags: {'aws-cdk:subnet-type': "Public"}});
```

```
ec2.Vpc.from_lookup(self, "PublicVpc",
    tags={"aws-cdk:subnet-type": "Public"})
```

```
Vpc.fromLookup(this, "PublicVpc", VpcLookupOptions.builder()
        .tags(java.util.Map.of("aws-cdk:subnet-type", "Public"))  // Java 9 or later
        .build());
```

```
Vpc.FromLookup(this, id: "PublicVpc", new VpcLookupOptions
{
    Tags = new Dictionary<string, string> { ["aws-cdk:subnet-type"] = "Public" }
});
```

```
ec2.Vpc_FromLookup(this, jsii.String("DefaultVpc"), &ec2.VpcLookupOptions{
  Tags: &map[string]*string{"aws-cdk:subnet-type": jsii.String("Public")},
})
```

I risultati di vengono memorizzati nella cache del file del progetto. `Vpc.fromLookup()` `cdk.context.json` (Vedi [Valori di contesto e AWS CDK).](context.md) Affida questo file al controllo della versione in modo che la tua app continui a fare riferimento allo stesso Amazon VPC. Funziona anche se successivamente modifichi gli attributi del tuo VPCs VPC in modo da selezionare un VPC diverso. [Ciò è particolarmente importante se si implementa lo stack in un ambiente che non ha accesso all' AWS account che definisce il VPC, come CDK Pipelines.](cdk-pipeline.md)

Sebbene sia possibile utilizzare una risorsa esterna ovunque si utilizzi una risorsa simile definita nell'app AWS CDK, non è possibile modificarla. Ad esempio, chiamare `addToResourcePolicy` (Python:`add_to_resource_policy`) su un dispositivo esterno `s3.Bucket` non fa nulla.

## Nomi fisici delle risorse
<a name="resources-physical-names"></a>

I nomi logici delle risorse in AWS CloudFormation sono diversi dai nomi delle risorse visualizzati nella Console di AWS gestione dopo la loro distribuzione da AWS CloudFormation. Il AWS CDK chiama questi nomi finali nomi *fisici*.

Ad esempio, AWS CloudFormation potrebbe creare il bucket Amazon S3 con l'ID logico `Stack2MyBucket4DD88B4F` e il nome fisico. `stack2MyBucket4dd88b4f-iuv1rbv9z3to`

È possibile specificare un nome fisico durante la creazione di costrutti che rappresentano risorse utilizzando la proprietà. `<resourceType>Name` L'esempio seguente crea un bucket Amazon S3 con il nome fisico. `amzn-s3-demo-bucket`

**Example**  

```
const bucket = new s3.Bucket(this, 'MyBucket', {
  bucketName: 'amzn-s3-demo-bucket',
});
```

```
const bucket = new s3.Bucket(this, 'MyBucket', {
  bucketName: 'amzn-s3-demo-bucket'
});
```

```
bucket = s3.Bucket(self, "MyBucket", bucket_name="amzn-s3-demo-bucket")
```

```
Bucket bucket = Bucket.Builder.create(this, "MyBucket")
        .bucketName("amzn-s3-demo-bucket").build();
```

```
var bucket = new Bucket(this, "MyBucket", new BucketProps { BucketName = "amzn-s3-demo-bucket" });
```

```
bucket := s3.NewBucket(this, jsii.String("MyBucket"), &s3.BucketProps{
  BucketName: jsii.String("amzn-s3-demo-bucket"),
})
```

L'assegnazione di nomi fisici alle risorse presenta alcuni svantaggi in. AWS CloudFormation Soprattutto, qualsiasi modifica alle risorse distribuite che richieda la sostituzione di una risorsa, ad esempio le modifiche alle proprietà di una risorsa che sono immutabili dopo la creazione, avrà esito negativo se a una risorsa è assegnato un nome fisico. Se ti ritrovi in quello stato, l'unica soluzione è eliminare lo AWS CloudFormation stack, quindi distribuire nuovamente l'app CDK. AWS Consulta la [AWS CloudFormation documentazione per i dettagli](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-name.html).

In alcuni casi, ad esempio quando si crea un'app AWS CDK con riferimenti a più ambienti, sono necessari nomi fisici per il corretto funzionamento del AWS CDK. In questi casi, se non vuoi preoccuparti di inventarti un nome fisico, puoi lasciare che sia il AWS CDK a dargli il nome. A tale scopo, utilizzate il valore speciale`PhysicalName.GENERATE_IF_NEEDED`, come segue.

**Example**  

```
const bucket = new s3.Bucket(this, 'MyBucket', {
  bucketName: core.PhysicalName.GENERATE_IF_NEEDED,
});
```

```
const bucket = new s3.Bucket(this, 'MyBucket', {
  bucketName: core.PhysicalName.GENERATE_IF_NEEDED
});
```

```
bucket = s3.Bucket(self, "MyBucket",
                         bucket_name=core.PhysicalName.GENERATE_IF_NEEDED)
```

```
Bucket bucket = Bucket.Builder.create(this, "MyBucket")
        .bucketName(PhysicalName.GENERATE_IF_NEEDED).build();
```

```
var bucket = new Bucket(this, "MyBucket", new BucketProps
    { BucketName = PhysicalName.GENERATE_IF_NEEDED });
```

```
bucket := s3.NewBucket(this, jsii.String("MyBucket"), &s3.BucketProps{
  BucketName: awscdk.PhysicalName_GENERATE_IF_NEEDED(),
})
```

## Passaggio di identificatori di risorse univoci
<a name="resources-identifiers"></a>

Quando possibile, è necessario passare le risorse per riferimento, come descritto nella sezione precedente. Tuttavia, in alcuni casi non avete altra scelta che fare riferimento a una risorsa tramite uno dei suoi attributi. I casi d'uso di esempio includono quanto segue:
+ Quando si utilizzano AWS CloudFormation risorse di basso livello.
+ Quando è necessario esporre risorse ai componenti di runtime di un'applicazione AWS CDK, ad esempio quando si fa riferimento alle funzioni Lambda tramite variabili di ambiente.

Questi identificatori sono disponibili come attributi sulle risorse, come i seguenti.

**Example**  

```
bucket.bucketName
lambdaFunc.functionArn
securityGroup.groupArn
```

```
bucket.bucketName
lambdaFunc.functionArn
securityGroup.groupArn
```

```
bucket.bucket_name
lambda_func.function_arn
security_group_arn
```
L'associazione Java AWS CDK utilizza metodi getter per gli attributi.  

```
bucket.getBucketName()
lambdaFunc.getFunctionArn()
securityGroup.getGroupArn()
```

```
bucket.BucketName
lambdaFunc.FunctionArn
securityGroup.GroupArn
```

```
bucket.BucketName()
fn.FunctionArn()
```

L'esempio seguente mostra come passare il nome di un bucket generato a una funzione AWS Lambda.

**Example**  

```
const bucket = new s3.Bucket(this, 'Bucket');

new lambda.Function(this, 'MyLambda', {
  // ...
  environment: {
    BUCKET_NAME: bucket.bucketName,
  },
});
```

```
const bucket = new s3.Bucket(this, 'Bucket');

new lambda.Function(this, 'MyLambda', {
  // ...
  environment: {
    BUCKET_NAME: bucket.bucketName
  }
});
```

```
bucket = s3.Bucket(self, "Bucket")

lambda.Function(self, "MyLambda", environment=dict(BUCKET_NAME=bucket.bucket_name))
```

```
final Bucket bucket = new Bucket(this, "Bucket");

Function.Builder.create(this, "MyLambda")
        .environment(java.util.Map.of(    // Java 9 or later
                "BUCKET_NAME", bucket.getBucketName()))
        .build();
```

```
var bucket = new Bucket(this, "Bucket");

new Function(this, "MyLambda", new FunctionProps
{
    Environment = new Dictionary<string, string>
    {
        ["BUCKET_NAME"] = bucket.BucketName
    }
});
```

```
bucket := s3.NewBucket(this, jsii.String("Bucket"), &s3.BucketProps{})
lambda.NewFunction(this, jsii.String("MyLambda"), &lambda.FunctionProps{
  Environment: &map[string]*string{"BUCKET_NAME": bucket.BucketName()},
})
```

## Concessione di autorizzazioni tra risorse
<a name="resources-grants"></a>

I costrutti di livello superiore rendono possibili le autorizzazioni con privilegi minimi offrendo requisiti di autorizzazione semplici, basati sull'intenzione di esprimere. APIs Ad esempio, molti costrutti offrono metodi di concessione che è possibile utilizzare per concedere a un'entità (come un ruolo o un utente IAM) l'autorizzazione a lavorare con la risorsa, senza dover creare manualmente istruzioni di autorizzazione IAM.

I metodi di concessione sono disponibili tramite le classi Grants (ad esempio `BucketGrants` per i bucket Amazon S3). Queste classi funzionano con i costrutti L1 e L2. I costrutti L2 espongono una `grants` proprietà per comodità, ma potete anche creare una classe Grants direttamente da un costrutto L1. È possibile combinare le classi Grants con [Mixins](mixins.md) per ottenere una praticità simile a L2 sui costrutti L1.

L'esempio seguente crea le autorizzazioni per consentire al ruolo di esecuzione di una funzione Lambda di leggere e scrivere oggetti in un particolare bucket Amazon S3. Se il bucket Amazon S3 è crittografato con una chiave AWS KMS, questo metodo concede anche le autorizzazioni al ruolo di esecuzione della funzione Lambda per la decrittografia con la chiave.

**Example**  

```
if (bucket.grants.readWrite(func).success) {
  // ...
}
```

```
if ( bucket.grants.readWrite(func).success) {
  // ...
}
```

```
if bucket.grants.read_write(func).success:
    # ...
```

```
if (bucket.getGrants().readWrite(func).getSuccess()) {
    // ...
}
```

```
if (bucket.Grants.ReadWrite(func).Success)
{
    // ...
}
```

```
if *bucket.Grants().ReadWrite(function, nil).Success() {
  // ...
}
```

I `iam.Grant` metodi di concessione restituiscono un oggetto. Utilizzate l'`success`attributo dell'`Grant`oggetto per determinare se la concessione è stata effettivamente applicata (ad esempio, potrebbe non essere stata applicata a [risorse esterne](#resources-referencing)). Puoi anche usare il metodo `assertSuccess` (Python:`assert_success`) dell'`Grant`oggetto per far sì che la concessione sia stata applicata con successo.

Se un metodo di concessione specifico non è disponibile per il particolare caso d'uso, è possibile utilizzare un metodo di concessione generico per definire una nuova concessione con un elenco di azioni specificato.

L'esempio seguente mostra come concedere a una funzione Lambda l'accesso all'azione Amazon DynamoDB. `CreateBackup`

**Example**  

```
table.grants.actions(func, 'dynamodb:CreateBackup');
```

```
table.grants.actions(func, 'dynamodb:CreateBackup');
```

```
table.grants.actions(func, "dynamodb:CreateBackup")
```

```
table.getGrants().actions(func, "dynamodb:CreateBackup");
```

```
table.Grants.Actions(func, "dynamodb:CreateBackup");
```

```
table := dynamodb.NewTable(this, jsii.String("MyTable"), &dynamodb.TableProps{})
table.Grants().Actions(function, jsii.String("dynamodb:CreateBackup"))
```

Molte risorse, come le funzioni Lambda, richiedono l'assunzione di un ruolo durante l'esecuzione del codice. Una proprietà di configurazione consente di specificare un`iam.IRole`. Se non viene specificato alcun ruolo, la funzione crea automaticamente un ruolo specifico per questo uso. È quindi possibile utilizzare i metodi di concessione sulle risorse per aggiungere istruzioni al ruolo.

I metodi di concessione sono creati utilizzando un livello inferiore APIs per la gestione con le politiche IAM. Le politiche sono modellate come oggetti. [PolicyDocument](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyDocument.html) Aggiungi istruzioni direttamente ai ruoli (o al ruolo associato a un costrutto) usando il `addToRolePolicy` metodo (Python`add_to_role_policy`:) o alla politica di una risorsa (come `Bucket` una politica) usando il metodo `addToResourcePolicy` (`add_to_resource_policy`Python:).

## Metriche e allarmi relativi alle risorse
<a name="resources-metrics"></a>

Molte risorse emettono CloudWatch metriche che possono essere utilizzate per configurare dashboard di monitoraggio e allarmi. I costrutti di livello superiore dispongono di metodi metrici che consentono di accedere alle metriche senza cercare il nome corretto da utilizzare.

L'esempio seguente mostra come definire un allarme quando il numero `ApproximateNumberOfMessagesNotVisible` di una coda Amazon SQS supera 100.

**Example**  

```
import * as cw from '@aws-cdk/aws-cloudwatch';
import * as sqs from '@aws-cdk/aws-sqs';
import { Duration } from '@aws-cdk/core';

const queue = new sqs.Queue(this, 'MyQueue');

const metric = queue.metricApproximateNumberOfMessagesNotVisible({
  label: 'Messages Visible (Approx)',
  period: Duration.minutes(5),
  // ...
});
metric.createAlarm(this, 'TooManyMessagesAlarm', {
  comparisonOperator: cw.ComparisonOperator.GREATER_THAN_THRESHOLD,
  threshold: 100,
  // ...
});
```

```
const cw = require('@aws-cdk/aws-cloudwatch');
const sqs = require('@aws-cdk/aws-sqs');
const { Duration } = require('@aws-cdk/core');

const queue = new sqs.Queue(this, 'MyQueue');

const metric = queue.metricApproximateNumberOfMessagesNotVisible({
  label: 'Messages Visible (Approx)',
  period: Duration.minutes(5)
  // ...
});
metric.createAlarm(this, 'TooManyMessagesAlarm', {
  comparisonOperator: cw.ComparisonOperator.GREATER_THAN_THRESHOLD,
  threshold: 100
  // ...
});
```

```
import aws_cdk.aws_cloudwatch as cw
import aws_cdk.aws_sqs as sqs
from aws_cdk.core import Duration

queue = sqs.Queue(self, "MyQueue")
metric = queue.metric_approximate_number_of_messages_not_visible(
    label="Messages Visible (Approx)",
    period=Duration.minutes(5),
    # ...
)
metric.create_alarm(self, "TooManyMessagesAlarm",
    comparison_operator=cw.ComparisonOperator.GREATER_THAN_THRESHOLD,
    threshold=100,
    # ...
)
```

```
import software.amazon.awscdk.core.Duration;
import software.amazon.awscdk.services.sqs.Queue;
import software.amazon.awscdk.services.cloudwatch.Metric;
import software.amazon.awscdk.services.cloudwatch.MetricOptions;
import software.amazon.awscdk.services.cloudwatch.CreateAlarmOptions;
import software.amazon.awscdk.services.cloudwatch.ComparisonOperator;

Queue queue = new Queue(this, "MyQueue");

Metric metric = queue
        .metricApproximateNumberOfMessagesNotVisible(MetricOptions.builder()
                .label("Messages Visible (Approx)")
                .period(Duration.minutes(5)).build());

metric.createAlarm(this, "TooManyMessagesAlarm", CreateAlarmOptions.builder()
                .comparisonOperator(ComparisonOperator.GREATER_THAN_THRESHOLD)
                .threshold(100)
                // ...
                .build());
```

```
using cdk = Amazon.CDK;
using cw = Amazon.CDK.AWS.CloudWatch;
using sqs = Amazon.CDK.AWS.SQS;

var queue = new sqs.Queue(this, "MyQueue");
var metric = queue.MetricApproximateNumberOfMessagesNotVisible(new cw.MetricOptions
{
    Label = "Messages Visible (Approx)",
    Period = cdk.Duration.Minutes(5),
    // ...
});
metric.CreateAlarm(this, "TooManyMessagesAlarm", new cw.CreateAlarmOptions
{
    ComparisonOperator = cw.ComparisonOperator.GREATER_THAN_THRESHOLD,
    Threshold = 100,
    // ..
});
```

```
import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/jsii-runtime-go"
  cw "github.com/aws/aws-cdk-go/awscdk/v2/awscloudwatch"
  sqs "github.com/aws/aws-cdk-go/awscdk/v2/awssqs"
)

queue := sqs.NewQueue(this, jsii.String("MyQueue"), &sqs.QueueProps{})
metric := queue.MetricApproximateNumberOfMessagesNotVisible(&cw.MetricOptions{
  Label: jsii.String("Messages Visible (Approx)"),
  Period: awscdk.Duration_Minutes(jsii.Number(5)),
})

metric.CreateAlarm(this, jsii.String("TooManyMessagesAlarm"), &cw.CreateAlarmOptions{
  ComparisonOperator: cw.ComparisonOperator_GREATER_THAN_THRESHOLD,
  Threshold: jsii.Number(100),
})
```

Se non esiste un metodo per una particolare metrica, puoi utilizzare il metodo metrico generale per specificare il nome della metrica manualmente.

Le metriche possono anche essere aggiunte ai dashboard. CloudWatch Per informazioni, consulta [CloudWatch](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_cloudwatch-readme.html).

## Traffico di rete
<a name="resources-traffic"></a>

In molti casi, è necessario abilitare le autorizzazioni su una rete affinché un'applicazione funzioni, ad esempio quando l'infrastruttura di elaborazione deve accedere al livello di persistenza. Le risorse che stabiliscono o ascoltano le connessioni espongono metodi che abilitano i flussi di traffico, inclusa l'impostazione delle regole dei gruppi di sicurezza o della rete. ACLs

 [IConnectable](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.IConnectable.html)le risorse hanno una `connections` proprietà che funge da gateway per la configurazione delle regole del traffico di rete.

È possibile abilitare il flusso dei dati su un determinato percorso di rete utilizzando `allow` metodi. L'esempio seguente abilita le connessioni HTTPS al Web e le connessioni in entrata dal gruppo Amazon EC2 Auto Scaling. `fleet2`

**Example**  

```
import * as asg from '@aws-cdk/aws-autoscaling';
import * as ec2 from '@aws-cdk/aws-ec2';

const fleet1: asg.AutoScalingGroup = asg.AutoScalingGroup(/*...*/);

// Allow surfing the (secure) web
fleet1.connections.allowTo(new ec2.Peer.anyIpv4(), new ec2.Port({ fromPort: 443, toPort: 443 }));

const fleet2: asg.AutoScalingGroup = asg.AutoScalingGroup(/*...*/);
fleet1.connections.allowFrom(fleet2, ec2.Port.AllTraffic());
```

```
const asg = require('@aws-cdk/aws-autoscaling');
const ec2 = require('@aws-cdk/aws-ec2');

const fleet1 = asg.AutoScalingGroup();

// Allow surfing the (secure) web
fleet1.connections.allowTo(new ec2.Peer.anyIpv4(), new ec2.Port({ fromPort: 443, toPort: 443 }));

const fleet2 = asg.AutoScalingGroup();
fleet1.connections.allowFrom(fleet2, ec2.Port.AllTraffic());
```

```
import aws_cdk.aws_autoscaling as asg
import aws_cdk.aws_ec2 as ec2

fleet1 = asg.AutoScalingGroup( ... )

# Allow surfing the (secure) web
fleet1.connections.allow_to(ec2.Peer.any_ipv4(),
  ec2.Port(PortProps(from_port=443, to_port=443)))

fleet2 = asg.AutoScalingGroup( ... )
fleet1.connections.allow_from(fleet2, ec2.Port.all_traffic())
```

```
import software.amazon.awscdk.services.autoscaling.AutoScalingGroup;
import software.amazon.awscdk.services.ec2.Peer;
import software.amazon.awscdk.services.ec2.Port;

AutoScalingGroup fleet1 = AutoScalingGroup.Builder.create(this, "MyFleet")
        /* ... */.build();

// Allow surfing the (secure) Web
fleet1.getConnections().allowTo(Peer.anyIpv4(),
        Port.Builder.create().fromPort(443).toPort(443).build());

AutoScalingGroup fleet2 = AutoScalingGroup.Builder.create(this, "MyFleet2")
        /* ... */.build();
fleet1.getConnections().allowFrom(fleet2, Port.allTraffic());
```

```
using cdk = Amazon.CDK;
using asg = Amazon.CDK.AWS.AutoScaling;
using ec2 = Amazon.CDK.AWS.EC2;

// Allow surfing the (secure) Web
var fleet1 = new asg.AutoScalingGroup(this, "MyFleet", new asg.AutoScalingGroupProps { /* ... */ });
fleet1.Connections.AllowTo(ec2.Peer.AnyIpv4(), new ec2.Port(new ec2.PortProps
  { FromPort = 443, ToPort = 443 }));

var fleet2 = new asg.AutoScalingGroup(this, "MyFleet2", new asg.AutoScalingGroupProps { /* ... */ });
fleet1.Connections.AllowFrom(fleet2, ec2.Port.AllTraffic());
```

```
import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/jsii-runtime-go"
  autoscaling "github.com/aws/aws-cdk-go/awscdk/v2/awsautoscaling"
  ec2 "github.com/aws/aws-cdk-go/awscdk/v2/awsec2"
)

fleet1 := autoscaling.NewAutoScalingGroup(this, jsii.String("MyFleet1"), &autoscaling.AutoScalingGroupProps{})
fleet1.Connections().AllowTo(ec2.Peer_AnyIpv4(),ec2.NewPort(&ec2.PortProps{ FromPort: jsii.Number(443), ToPort: jsii.Number(443) }),jsii.String("secure web"))

fleet2 := autoscaling.NewAutoScalingGroup(this, jsii.String("MyFleet2"), &autoscaling.AutoScalingGroupProps{})
fleet1.Connections().AllowFrom(fleet2, ec2.Port_AllTraffic(),jsii.String("all traffic"))
```

Ad alcune risorse sono associate porte predefinite. Gli esempi includono il listener di un load balancer sulla porta pubblica e le porte su cui il motore di database accetta connessioni per le istanze di un database Amazon RDS. In questi casi, è possibile applicare un controllo rigoroso della rete senza dover specificare manualmente la porta. Per farlo, usa i `allowToDefaultPort` metodi `allowDefaultPortFrom` and (Python:`allow_default_port_from`,`allow_to_default_port`).

L'esempio seguente mostra come abilitare le connessioni da qualsiasi IPV4 indirizzo e una connessione da un gruppo Auto Scaling per accedere a un database.

**Example**  

```
listener.connections.allowDefaultPortFromAnyIpv4('Allow public access');

fleet.connections.allowToDefaultPort(rdsDatabase, 'Fleet can access database');
```

```
listener.connections.allowDefaultPortFromAnyIpv4('Allow public access');

fleet.connections.allowToDefaultPort(rdsDatabase, 'Fleet can access database');
```

```
listener.connections.allow_default_port_from_any_ipv4("Allow public access")

fleet.connections.allow_to_default_port(rds_database, "Fleet can access database")
```

```
listener.getConnections().allowDefaultPortFromAnyIpv4("Allow public access");

fleet.getConnections().AllowToDefaultPort(rdsDatabase, "Fleet can access database");
```

```
listener.Connections.AllowDefaultPortFromAnyIpv4("Allow public access");

fleet.Connections.AllowToDefaultPort(rdsDatabase, "Fleet can access database");
```

```
listener.Connections().AllowDefaultPortFromAnyIpv4(jsii.String("Allow public Access"))
fleet.Connections().AllowToDefaultPort(rdsDatabase, jsii.String("Fleet can access database"))
```

## Gestione degli eventi
<a name="resources-events"></a>

Alcune risorse possono fungere da fonti di eventi. Usa il `addEventNotification` metodo (Python:`add_event_notification`) per registrare un obiettivo di evento su un particolare tipo di evento emesso dalla risorsa. Inoltre, i `addXxxNotification` metodi offrono un modo semplice per registrare un gestore per i tipi di eventi più comuni.

L'esempio seguente mostra come attivare una funzione Lambda quando un oggetto viene aggiunto a un bucket Amazon S3.

**Example**  

```
import * as s3nots from '@aws-cdk/aws-s3-notifications';

const handler = new lambda.Function(this, 'Handler', { /*…*/ });
const bucket = new s3.Bucket(this, 'Bucket');
bucket.addObjectCreatedNotification(new s3nots.LambdaDestination(handler));
```

```
const s3nots = require('@aws-cdk/aws-s3-notifications');

const handler = new lambda.Function(this, 'Handler', { /*…*/ });
const bucket = new s3.Bucket(this, 'Bucket');
bucket.addObjectCreatedNotification(new s3nots.LambdaDestination(handler));
```

```
import aws_cdk.aws_s3_notifications as s3_nots

handler = lambda_.Function(self, "Handler", ...)
bucket = s3.Bucket(self, "Bucket")
bucket.add_object_created_notification(s3_nots.LambdaDestination(handler))
```

```
import software.amazon.awscdk.services.s3.Bucket;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.s3.notifications.LambdaDestination;

Function handler = Function.Builder.create(this, "Handler")/* ... */.build();
Bucket bucket = new Bucket(this, "Bucket");
bucket.addObjectCreatedNotification(new LambdaDestination(handler));
```

```
using lambda = Amazon.CDK.AWS.Lambda;
using s3 = Amazon.CDK.AWS.S3;
using s3Nots = Amazon.CDK.AWS.S3.Notifications;

var handler = new lambda.Function(this, "Handler", new lambda.FunctionProps { .. });
var bucket = new s3.Bucket(this, "Bucket");
bucket.AddObjectCreatedNotification(new s3Nots.LambdaDestination(handler));
```

```
import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/jsii-runtime-go"
  s3 "github.com/aws/aws-cdk-go/awscdk/v2/awss3"
  s3nots "github.com/aws/aws-cdk-go/awscdk/v2/awss3notifications"
)

handler := lambda.NewFunction(this, jsii.String("MyFunction"), &lambda.FunctionProps{})
bucket := s3.NewBucket(this, jsii.String("Bucket"), &s3.BucketProps{})
bucket.AddObjectCreatedNotification(s3nots.NewLambdaDestination(handler), nil)
```

## Politiche di rimozione
<a name="resources-removal"></a>

*Le risorse che mantengono dati persistenti, come database, bucket Amazon S3 e registri Amazon ECR, hanno una politica di rimozione.* La politica di rimozione indica se eliminare gli oggetti persistenti quando lo AWS stack CDK che li contiene viene distrutto. I valori che specificano la politica di rimozione sono disponibili tramite l'`RemovalPolicy`enumerazione nel modulo CDK. AWS `core`

**Nota**  
Le risorse oltre a quelle che archiviano i dati in modo persistente potrebbero anche avere una `removalPolicy` che viene utilizzata per uno scopo diverso. Ad esempio, una versione della funzione Lambda utilizza un `removalPolicy` attributo per determinare se una determinata versione viene mantenuta quando viene distribuita una nuova versione. Questi hanno significati e impostazioni predefinite diversi rispetto alla politica di rimozione su un bucket Amazon S3 o una tabella DynamoDB.


| Valore | Significato | 
| --- | --- | 
|   `RemovalPolicy.RETAIN`   |  Conserva il contenuto della risorsa quando distruggi lo stack (impostazione predefinita). La risorsa è rimasta orfana dallo stack e deve essere eliminata manualmente. Se tenti di ridistribuire lo stack mentre la risorsa esiste ancora, riceverai un messaggio di errore a causa di un conflitto di nomi.  | 
|   `RemovalPolicy.DESTROY`   |  La risorsa verrà distrutta insieme allo stack.  | 

 AWS CloudFormation non rimuove i bucket Amazon S3 che contengono file anche se la politica di rimozione è impostata su. `DESTROY` Tentare di farlo è un errore. AWS CloudFormation Per fare in modo che il AWS CDK elimini tutti i file dal bucket prima di distruggerlo, imposta la proprietà del bucket su. `autoDeleteObjects` `true`

Di seguito è riportato un esempio di creazione di un bucket Amazon S3 con `RemovalPolicy` of `DESTROY` e `autoDeleteOjbects` impostato su. `true`

**Example**  

```
import * as cdk from '@aws-cdk/core';
import * as s3 from '@aws-cdk/aws-s3';

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

    const bucket = new s3.Bucket(this, 'Bucket', {
      removalPolicy: cdk.RemovalPolicy.DESTROY,
      autoDeleteObjects: true
    });
  }
}
```

```
const cdk = require('@aws-cdk/core');
const s3 = require('@aws-cdk/aws-s3');

class CdkTestStack extends cdk.Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    const bucket = new s3.Bucket(this, 'Bucket', {
      removalPolicy: cdk.RemovalPolicy.DESTROY,
      autoDeleteObjects: true
    });
  }
}

module.exports = { CdkTestStack }
```

```
import aws_cdk.core as cdk
import aws_cdk.aws_s3 as s3

class CdkTestStack(cdk.stack):
    def __init__(self, scope: cdk.Construct, id: str, **kwargs):
        super().__init__(scope, id, **kwargs)

        bucket = s3.Bucket(self, "Bucket",
            removal_policy=cdk.RemovalPolicy.DESTROY,
            auto_delete_objects=True)
```

```
software.amazon.awscdk.core.*;
import software.amazon.awscdk.services.s3.*;

public class CdkTestStack extends Stack {
    public CdkTestStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkTestStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        Bucket.Builder.create(this, "Bucket")
                .removalPolicy(RemovalPolicy.DESTROY)
                .autoDeleteObjects(true).build();
    }
}
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

public CdkTestStack(Construct scope, string id, IStackProps props) : base(scope, id, props)
{
    new Bucket(this, "Bucket", new BucketProps {
        RemovalPolicy = RemovalPolicy.DESTROY,
        AutoDeleteObjects = true
    });
}
```

```
import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/jsii-runtime-go"
  s3 "github.com/aws/aws-cdk-go/awscdk/v2/awss3"
)

s3.NewBucket(this, jsii.String("Bucket"), &s3.BucketProps{
  RemovalPolicy: awscdk.RemovalPolicy_DESTROY,
  AutoDeleteObjects: jsii.Bool(true),
})
```

Puoi anche applicare una politica di rimozione direttamente alla AWS CloudFormation risorsa sottostante tramite il `applyRemovalPolicy()` metodo. Questo metodo è disponibile su alcune risorse stateful che non hanno una `removalPolicy` proprietà negli oggetti di scena della risorsa L2. Considerare i seguenti esempi:
+  AWS CloudFormation pile
+ Pool di utenti Amazon Cognito
+ Istanze di database Amazon DocumentDB
+ Volumi Amazon EC2
+ Domini Amazon OpenSearch Service
+  FSx File system Amazon
+ Code Amazon SQS

**Example**  

```
const resource = bucket.node.findChild('Resource') as cdk.CfnResource;
resource.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
```

```
const resource = bucket.node.findChild('Resource');
resource.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
```

```
resource = bucket.node.find_child('Resource')
resource.apply_removal_policy(cdk.RemovalPolicy.DESTROY);
```

```
CfnResource resource = (CfnResource)bucket.node.findChild("Resource");
resource.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
```

```
var resource = (CfnResource)bucket.node.findChild('Resource');
resource.ApplyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
```

**Nota**  
Il AWS CDK `RemovalPolicy` si traduce in «s». AWS CloudFormation `DeletionPolicy` Tuttavia, l'impostazione predefinita in AWS CDK è quella di conservare i dati, che è l'opposto dell'impostazione predefinita. AWS CloudFormation 

# Identificatori e CDK AWS
<a name="identifiers"></a>

Quando crei app AWS Cloud Development Kit (AWS CDK), utilizzerai molti tipi di identificatori e nomi. Per utilizzare il AWS CDK in modo efficace ed evitare errori, è importante comprendere i tipi di identificatori.

Gli identificatori devono essere unici nell'ambito in cui vengono creati; non è necessario che siano univoci a livello globale nell'applicazione CDK. AWS 

Se si tenta di creare un identificatore con lo stesso valore all'interno dello stesso ambito, il AWS CDK genera un'eccezione.

## Costruisci IDs
<a name="identifiers-construct-ids"></a>

L'identificatore più comune,`id`, è l'identificatore passato come secondo argomento durante l'istanziazione di un oggetto di costruzione. Questo identificatore, come tutti gli identificatori, deve essere univoco solo nell'ambito in cui viene creato, che è il primo argomento quando si crea un'istanza di un oggetto di costruzione.

**Nota**  
L'`id`of a stack è anche l'identificatore utilizzato per fare riferimento ad esso nel riferimento [AWS CDK CLI](cli.md).

Diamo un'occhiata a un esempio in cui abbiamo due costrutti con l'identificatore nella nostra app. `MyBucket` Il primo è definito nell'ambito dello stack con l'identificatore. `Stack1` Il secondo è definito nell'ambito di uno stack con l'identificatore. `Stack2` Poiché sono definiti in ambiti diversi, ciò non causa alcun conflitto e possono coesistere nella stessa app senza problemi.

**Example**  

```
import { App, Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';

class MyStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps = {}) {
    super(scope, id, props);

    new s3.Bucket(this, 'MyBucket');
  }
}

const app = new App();
new MyStack(app, 'Stack1');
new MyStack(app, 'Stack2');
```

```
const { App , Stack } = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');

class MyStack extends Stack {
  constructor(scope, id, props = {}) {
    super(scope, id, props);

    new s3.Bucket(this, 'MyBucket');
  }
}

const app = new App();
new MyStack(app, 'Stack1');
new MyStack(app, 'Stack2');
```

```
from aws_cdk import App, Construct, Stack, StackProps
from constructs import Construct
from aws_cdk import aws_s3 as s3

class MyStack(Stack):

    def __init__(self, scope: Construct, id: str, **kwargs):

        super().__init__(scope, id, **kwargs)
        s3.Bucket(self, "MyBucket")

app = App()
MyStack(app, 'Stack1')
MyStack(app, 'Stack2')
```

```
// MyStack.java
package com.myorg;

import software.amazon.awscdk.App;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.constructs.Construct;
import software.amazon.awscdk.services.s3.Bucket;

public class MyStack extends Stack {
    public MyStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public MyStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);
        new Bucket(this, "MyBucket");
    }
}

// Main.java
package com.myorg;

import software.amazon.awscdk.App;

public class Main {
    public static void main(String[] args) {
        App app = new App();
        new MyStack(app, "Stack1");
        new MyStack(app, "Stack2");
    }
}
```

```
using Amazon.CDK;
using constructs;
using Amazon.CDK.AWS.S3;

public class MyStack : Stack
{
    public MyStack(Construct scope, string id, IStackProps props) : base(scope, id, props)
    {
        new Bucket(this, "MyBucket");
    }
}

class Program
{
    static void Main(string[] args)
    {
        var app = new App();
        new MyStack(app, "Stack1");
        new MyStack(app, "Stack2");
    }
}
```

## Percorsi
<a name="identifiers-paths"></a>

I costrutti in un'applicazione AWS CDK formano una gerarchia radicata nella classe. `App` *Ci riferiamo alla raccolta di elementi IDs da un determinato costrutto, dal suo costrutto genitore, dal suo predecessore e così via fino alla radice dell'albero dei costrutti, come percorso.*

Il AWS CDK in genere visualizza i percorsi nei modelli sotto forma di stringa. I livelli sono separati IDs da barre, a partire dal nodo immediatamente sotto l'`App`istanza root, che di solito è una pila. Ad esempio, i percorsi delle due risorse del bucket Amazon S3 nell'esempio di codice precedente sono e. `Stack1/MyBucket` `Stack2/MyBucket`

È possibile accedere al percorso di qualsiasi costrutto a livello di codice, come illustrato nell'esempio seguente. Questo ottiene il percorso di `myConstruct` (o`my_construct`, come lo scriverebbero gli sviluppatori Python). Poiché IDs devono essere unici nell'ambito in cui vengono creati, i loro percorsi sono sempre unici all'interno di un'applicazione AWS CDK.

**Example**  

```
const path: string = myConstruct.node.path;
```

```
const path = myConstruct.node.path;
```

```
path = my_construct.node.path
```

```
String path = myConstruct.getNode().getPath();
```

```
string path = myConstruct.Node.Path;
```

## Unici IDs
<a name="identifiers-unique-ids"></a>

 AWS CloudFormation richiede che tutte le IDs logiche di un modello siano uniche. Per questo motivo, il AWS CDK deve essere in grado di generare un identificatore univoco per ogni costrutto di un'applicazione. Le risorse hanno percorsi univoci a livello globale (i nomi di tutti gli ambiti dallo stack a una risorsa specifica). Pertanto, il AWS CDK genera gli identificatori univoci necessari concatenando gli elementi del percorso e aggiungendo un hash a 8 cifre. (L'hash è necessario per distinguere percorsi distinti, come `A/B/C` e`A/BC`, che risulterebbero nello stesso identificatore. AWS CloudFormation AWS CloudFormation gli identificatori sono alfanumerici e non possono contenere barre o altri caratteri separatori.) *Il AWS CDK chiama questa stringa l'ID univoco del costrutto.*

In generale, la tua app AWS CDK non dovrebbe aver bisogno di conoscere Unique. IDs Tuttavia, potete accedere all'ID univoco di qualsiasi costrutto a livello di codice, come mostrato nell'esempio seguente.

**Example**  

```
const uid: string = Names.uniqueId(myConstruct);
```

```
const uid = Names.uniqueId(myConstruct);
```

```
uid = Names.unique_id(my_construct)
```

```
String uid = Names.uniqueId(myConstruct);
```

```
string uid = Names.Uniqueid(myConstruct);
```

L'*indirizzo* è un altro tipo di identificatore univoco che distingue in modo univoco le risorse CDK. Derivato dall'hash SHA-1 del percorso, non è leggibile dall'uomo. Tuttavia, la sua lunghezza costante e relativamente breve (sempre 42 caratteri esadecimali) lo rende utile in situazioni in cui l'ID univoco «tradizionale» potrebbe essere troppo lungo. Alcuni costrutti possono utilizzare l'indirizzo nel AWS CloudFormation modello sintetizzato anziché l'ID univoco. Anche in questo caso, la tua app in genere non dovrebbe aver bisogno di conoscere gli indirizzi dei suoi costrutti, ma puoi recuperare l'indirizzo di un costrutto come segue.

**Example**  

```
const addr: string = myConstruct.node.addr;
```

```
const addr = myConstruct.node.addr;
```

```
addr = my_construct.node.addr
```

```
String addr = myConstruct.getNode().getAddr();
```

```
string addr = myConstruct.Node.Addr;
```

## Logico IDs
<a name="identifiers-logical-ids"></a>

Gli unici IDs fungono da *identificatori logici* (o *nomi logici*) delle risorse nei AWS CloudFormation modelli generati per i costrutti che rappresentano AWS le risorse.

Ad esempio, il bucket Amazon S3 dell'esempio precedente creato all'interno `Stack2` restituisce una risorsa. ` AWS::S3::Bucket` L'ID logico della risorsa si trova `Stack2MyBucket4DD88B4F` nel modello risultante AWS CloudFormation . (Per i dettagli su come viene generato questo identificatore, consulta [Unique IDs](#identifiers-unique-ids).)

### Stabilità dell'ID logico
<a name="identifiers-logical-id-stability"></a>

Evita di modificare l'ID logico di una risorsa dopo la sua creazione. AWS CloudFormation identifica le risorse in base al relativo ID logico. Pertanto, se si modifica l'ID logico di una risorsa, AWS CloudFormation crea una nuova risorsa con il nuovo ID logico, quindi elimina quello esistente. A seconda del tipo di risorsa, ciò potrebbe causare l'interruzione del servizio, la perdita di dati o entrambe le cose.

# Token e CDK AWS
<a name="tokens"></a>

Nel AWS Cloud Development Kit (AWS CDK), i *token* sono segnaposto per valori che non sono noti quando si definiscono costrutti o si sintetizzano gli stack. Questi valori verranno completamente risolti al momento dell'implementazione, quando verrà creata l'infrastruttura effettiva. Durante lo sviluppo di applicazioni AWS CDK, utilizzerai i token per gestire questi valori in tutta l'applicazione.

## Esempio di token
<a name="tokens-example"></a>

Di seguito è riportato un esempio di stack CDK che definisce un costrutto per un bucket Amazon Simple Storage Service (Amazon S3). Poiché il nome del nostro bucket non è ancora noto, il valore di viene memorizzato come token: `bucketName`

**Example**  

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

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

    // Define an S3 bucket
    const myBucket = new s3.Bucket(this, 'myBucket');

    // Store value of the S3 bucket name
    const myBucketName = myBucket.bucketName;

    // Print the current value for the S3 bucket name at synthesis
    console.log("myBucketName: " + myBucketName);
  }
}
```

```
const { Stack, Duration } = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');

class CdkDemoAppStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define an S3 bucket
    const myBucket = new s3.Bucket(this, 'myBucket');

    // Store value of the S3 bucket name
    const myBucketName = myBucket.bucketName;

    // Print the current value for the S3 bucket name at synthesis
    console.log("myBucketName: " + myBucketName);
  }
}

module.exports = { CdkDemoAppStack }
```

```
from aws_cdk import (
    Stack
)
from constructs import Construct
from aws_cdk import aws_s3 as s3

class CdkDemoAppStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Define an S3 bucket
        my_bucket = s3.Bucket(self, "myBucket")

        # Store the value of the S3 bucket name
        my_bucket_name = my_bucket.bucket_name

        # Print the current value for the S3 bucket name at synthesis
        print(f"myBucketName: {my_bucket_name}")
```

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.s3.Bucket;

import java.util.Map;

public class CdkDemoAppStack extends Stack {
    public CdkDemoAppStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkDemoAppStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // Define an S3 bucket
        Bucket myBucket = Bucket.Builder.create(this, "myBucket")
            .build();

        // Store the token for the bucket name
        String myBucketName = myBucket.getBucketName();

        // Print the token at synthesis
        System.out.println("myBucketName: " + myBucketName);
    }
}
```

```
using Amazon.CDK;
using Constructs;
using Amazon.CDK.AWS.S3;

namespace CdkDemoApp
{
    public class CdkDemoAppStack : Stack
    {
        internal CdkDemoAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // Define an S3 bucket
            var myBucket = new Bucket(this, "myBucket");

            // Store the token for the bucket name
            var myBucketName = myBucket.BucketName;

            // Print the token at synthesis
            System.Console.WriteLine($"myBucketName: {myBucketName}");
        }
    }
}
```

```
package main

import (
	"fmt"

	"github.com/aws/aws-cdk-go/awscdk/v2"
	"github.com/aws/aws-cdk-go/awscdk/v2/awss3"
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
)

type CdkDemoAppStackProps struct {
	awscdk.StackProps
}

func NewCdkDemoAppStack(scope constructs.Construct, id string, props *CdkDemoAppStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	// Define an S3 bucket
	myBucket := awss3.NewBucket(stack, jsii.String("myBucket"), &awss3.BucketProps{})

	// Store the token for the bucket name
	myBucketName := myBucket.BucketName()

	// Print the token at synthesis
	fmt.Println("myBucketName: ", *myBucketName)

	return stack
}

// ...
```
Quando eseguiamo `cdk synth` la sintesi del nostro stack, il valore di `myBucketName` verrà visualizzato nel formato token di. `${Token[TOKEN.<1234>]}` Questo formato di token è il risultato del modo in cui il AWS CDK codifica i token. In questo esempio, il token è codificato come stringa:  

```
$ cdk synth --quiet
myBucketName: ${Token[TOKEN.21]}
```
Poiché il valore del nome del nostro bucket non è noto al momento della sintesi, il token viene reso come. `myBucket<unique-hash>` Il nostro AWS CloudFormation modello utilizza la funzione `Ref` intrinseca per fare riferimento al suo valore, che sarà noto al momento dell'implementazione:  

```
Resources:
  myBucket<5AF9C99B>:
    # ...
Outputs:
  bucketNameOutput:
    Description: The name of the S3 bucket
    Value:
      Ref: myBucket<5AF9C99B>
```

Per ulteriori informazioni su come viene generato l'hash univoco, consulta Generated [logical IDs in your template](configure-synth.md#how-synth-default-logical-ids). AWS CloudFormation 

## Passare gettoni
<a name="tokens-passing"></a>

I token possono essere trasferiti come se fossero il valore effettivo che rappresentano. Di seguito è riportato un esempio che passa il token per il nome del nostro bucket a un costrutto per una funzione Lambda AWS :

**Example**  

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

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

    // Define an S3 bucket
    const myBucket = new s3.Bucket(this, 'myBucket');

    // ...

    // Define a Lambda function
    const myFunction = new lambda.Function(this, "myFunction", {
      runtime: lambda.Runtime.NODEJS_20_X,
      handler: "index.handler",
      code: lambda.Code.fromInline(`
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
      `),
      functionName: myBucketName + "Function", // Pass token for the S3 bucket name
      environment: {
        BUCKET_NAME: myBucketName, // Pass token for the S3 bucket name
      }
    });
  }
}
```

```
const { Stack, Duration } = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');
const lambda = require('aws-cdk-lib/aws-lambda');

class CdkDemoAppStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define an S3 bucket
    const myBucket = new s3.Bucket(this, 'myBucket');

    // ...

    // Define a Lambda function
    const myFunction = new lambda.Function(this, 'myFunction', {
      runtime: lambda.Runtime.NODEJS_20_X,
      handler: 'index.handler',
      code: lambda.Code.fromInline(`
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
      `),
      functionName: myBucketName + 'Function', // Pass token for the S3 bucket name
      environment: {
        BUCKET_NAME: myBucketName, // Pass token for the S3 bucket name
      }
    });
  }
}

module.exports = { CdkDemoAppStack }
```

```
from aws_cdk import (
    Stack
)
from constructs import Construct
from aws_cdk import aws_s3 as s3
from aws_cdk import aws_lambda as _lambda

class CdkDemoAppStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Define an S3 bucket
        my_bucket = s3.Bucket(self, "myBucket")

        # ...

        # Define a Lambda function
        my_function = _lambda.Function(self, "myFunction",
            runtime=_lambda.Runtime.NODEJS_20_X,
            handler="index.handler",
            code=_lambda.Code.from_inline("""
                exports.handler = async function(event) {
                  return {
                    statusCode: 200,
                    body: JSON.stringify('Hello World!'),
                  };
                };
            """),
            function_name=f"{my_bucket_name}Function",  # Pass token for the S3 bucket name
            environment={
                "BUCKET_NAME": my_bucket_name  # Pass token for the S3 bucket name
            }
        )
```

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.s3.Bucket;
import software.amazon.awscdk.services.lambda.Code;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.lambda.Runtime;

import java.util.Map;

public class CdkDemoAppStack extends Stack {
    public CdkDemoAppStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkDemoAppStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // Define an S3 bucket
        Bucket myBucket = Bucket.Builder.create(this, "myBucket")
            .build();

        // ...

        // Define a Lambda function
        Function myFunction = Function.Builder.create(this, "myFunction")
            .runtime(Runtime.NODEJS_20_X)
            .handler("index.handler")
            .code(Code.fromInline(
                "exports.handler = async function(event) {" +
                "return {" +
                "statusCode: 200," +
                "body: JSON.stringify('Hello World!')," +
                "};" +
                "};"
            ))
            .functionName(myBucketName + "Function") // Pass the token for the s3 bucket to the function construct
            .environment(Map.of("BUCKET_NAME", myBucketName))  // Pass the bucket name as environment variable
            .build();
    }
}
```

```
using Amazon.CDK;
using Constructs;
using Amazon.CDK.AWS.S3;
using Amazon.CDK.AWS.Lambda;
using System;
using System.Collections.Generic;

namespace CdkDemoApp
{
    public class CdkDemoAppStack : Stack
    {
        internal CdkDemoAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // Define an S3 bucket
            var myBucket = new Bucket(this, "myBucket");

            // ...

            // Define a Lambda function
            var myFunction = new Function(this, "myFunction", new FunctionProps
            {
                 Runtime = Runtime.NODEJS_20_X,
                 Handler = "index.handler",
                 Code = Code.FromInline(@"
                     exports.handler = async function(event) {
                       return {
                         statusCode: 200,
                         body: JSON.stringify('Hello World!'),
                       };
                     };
                 "),
                 // Pass the token for the S3 bucket name
                 Environment = new Dictionary<string, string>
                 {
                     { "BUCKET_NAME", myBucketName }
                 },
                 FunctionName = $"{myBucketName}Function" // Pass the token for the s3 bucket to the function construct
            });
        }
    }
}
```

```
package main

import (
	"fmt"

	"github.com/aws/aws-cdk-go/awscdk/v2"
	"github.com/aws/aws-cdk-go/awscdk/v2/awslambda"
	"github.com/aws/aws-cdk-go/awscdk/v2/awss3"
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
)

type CdkDemoAppStackProps struct {
	awscdk.StackProps
}

func NewCdkDemoAppStack(scope constructs.Construct, id string, props *CdkDemoAppStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	// Define an S3 bucket
	myBucket := awss3.NewBucket(stack, jsii.String("myBucket"), &awss3.BucketProps{})

	// ...

	// Define a Lambda function
	myFunction := awslambda.NewFunction(stack, jsii.String("myFunction"), &awslambda.FunctionProps{
		Runtime: awslambda.Runtime_NODEJS_20_X(),
		Handler: jsii.String("index.handler"),
		Code: awslambda.Code_FromInline(jsii.String(`
			exports.handler = async function(event) {
				return {
					statusCode: 200,
					body: JSON.stringify('Hello World!'),
				};
			};
		`)),
		FunctionName: jsii.String(fmt.Sprintf("%sFunction", *myBucketName)), // Pass the token for the S3 bucket to the function name
		Environment: &map[string]*string{
			"BUCKET_NAME": myBucketName,
		},
	})

	return stack
}
// ...
```
Quando sintetizziamo il nostro modello, le `Ref` funzioni `Fn::Join` intrinseche vengono utilizzate per specificare i valori, che saranno noti al momento dell'implementazione:  

```
Resources:
  myBucket<5AF9C99B>:
    Type: AWS::S3::Bucket
    # ...
  myFunction<884E1557>:
    Type: AWS::Lambda::Function
    Properties:
      # ...
      Environment:
        Variables:
          BUCKET_NAME:
            Ref: myBucket<5AF9C99B>
      FunctionName:
        Fn::Join:
          - ""
          - - Ref: myBucket<5AF9C99B>
            - Function
      # ...
```

## Come funzionano le codifiche dei token
<a name="tokens-work"></a>

I token sono oggetti che implementano l'[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.IResolvable.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.IResolvable.html)interfaccia, che contiene un unico `resolve` metodo. Durante la sintesi, il AWS CDK chiama questo metodo per produrre il valore finale dei token nel modello. CloudFormation 

**Nota**  
Raramente lavorerai direttamente con l'`IResolvable`interfaccia. Molto probabilmente vedrai solo versioni di token con codifica a stringa.

### Tipi di codifica dei token
<a name="tokens-work-types"></a>

I token partecipano al processo di sintesi per produrre valori arbitrari di qualsiasi tipo. Le altre funzioni in genere accettano solo argomenti di tipo base, come `string` o. `number` Per utilizzare i token in questi casi, potete codificarli in uno dei tre tipi utilizzando metodi statici sulla [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html)classe.
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-aswbrstringvalue-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-aswbrstringvalue-options)per generare una codifica di stringhe (o chiamare l'`.toString()`oggetto token).
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-aswbrlistvalue-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-aswbrlistvalue-options)per generare una codifica di elenco.
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-aswbrnumbervalue](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-aswbrnumbervalue)per generare una codifica numerica.

Questi prendono un valore arbitrario, che può essere un`IResolvable`, e li codificano in un valore primitivo del tipo indicato.

**Importante**  
Poiché uno qualsiasi dei tipi precedenti può essere potenzialmente un token codificato, fai attenzione quando analizzi o provi a leggerne il contenuto. Ad esempio, se tenti di analizzare una stringa per estrarne un valore e la stringa è un token codificato, l'analisi fallisce. Analogamente, se si tenta di interrogare la lunghezza di un array o di eseguire operazioni matematiche con un numero, è necessario innanzitutto verificare che non si tratti di token codificati.

## Come verificare la presenza di token nella tua app
<a name="tokens-check"></a>

Per verificare se un valore contiene un token non risolto, chiamate il metodo [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-iswbrunresolvedobj](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-iswbrunresolvedobj)(Python`is_unresolved`:). Di seguito è riportato un esempio che verifica se il valore del nome del nostro bucket Amazon S3 è un token. Se non è un token, convalidiamo la lunghezza del nome del bucket:

**Example**  

```
// ...

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

    // Define an S3 bucket
    const myBucket = new s3.Bucket(this, 'myBucket');
    // ...

    // Check if bucket name is a token. If not, check if length is less than 10 characters
    if (cdk.Token.isUnresolved(myBucketName)) {
      console.log("Token identified.");
    } else if (!cdk.Token.isUnresolved(myBucketName) && myBucketName.length > 10) {
      throw new Error('Maximum length for name is 10 characters.');
    };

    // ...
  }
}
```

```
const { Stack, Duration, Token, CfnOutput } = require('aws-cdk-lib');
// ...

class CdkDemoAppStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define an S3 bucket
    const myBucket = new s3.Bucket(this, 'myBucket');

    // ...

    // Check if bucket name is a token. If not, check if length is less than 10 characters
    if (Token.isUnresolved(myBucketName)) {
      console.log("Token identified.");
    } else if (!Token.isUnresolved(myBucketName) && myBucketName.length > 10) {
      throw new Error('Maximum length for name is 10 characters.');
    };

    // ...
  }
}
```

```
from aws_cdk import (
    Stack,
    Token
)
# ...

class CdkDemoAppStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Define an S3 bucket
        my_bucket = s3.Bucket(self, "myBucket")

        # ...

        # Check if bucket name is a token. If not, check if length is less than 10 characters
        if Token.is_unresolved(my_bucket_name):
            print("Token identified.")
        elif not Token.is_unresolved(my_bucket_name) and len(my_bucket_name) < 10:
            raise ValueError("Maximum length for name is 10 characters.")

        # ...
```

```
// ...
import software.amazon.awscdk.Token;
import software.amazon.awscdk.services.s3.Bucket;
// ...

public class CdkDemoAppStack extends Stack {
    public CdkDemoAppStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkDemoAppStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // Define an S3 bucket
        Bucket myBucket = Bucket.Builder.create(this, "myBucket")
            .build();

        // ...

        // Get the bucket name
        String myBucketName = myBucket.getBucketName();

        // Check if the bucket name is a token. If not, check if length is less than 10 characters
        if (Token.isUnresolved(myBucketName)) {
            System.out.println("Token identified.");
        } else if (!Token.isUnresolved(myBucketName) && myBucketName.length() > 10) {
            throw new IllegalArgumentException("Maximum length for name is 10 characters.");
        }

        // ...
      }
    }
  }
```

```
using Amazon.CDK;
using Constructs;
using Amazon.CDK.AWS.S3;
using Amazon.CDK.AWS.Lambda;
using System;
using System.Collections.Generic;

namespace CdkDemoApp
{
    public class CdkDemoAppStack : Stack
    {
        internal CdkDemoAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // Define an S3 bucket
            var myBucket = new Bucket(this, "myBucket");

            // ...

            // Get the bucket name
            var myBucketName = myBucket.BucketName;

            // Check if bucket name is a token. If not, check if length is less than 10 characters
            if (Token.IsUnresolved(myBucketName))
            {
                System.Console.WriteLine("Token identified.");
            }
            else if (!Token.IsUnresolved(myBucketName) && myBucketName.Length > 10)
            {
                throw new System.Exception("Maximum length for name is 10 characters.");
            }

            // ...
        }
    }
}
```

```
// ...

func NewCdkDemoAppStack(scope constructs.Construct, id string, props *CdkDemoAppStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	// Define an S3 bucket
	myBucket := awss3.NewBucket(stack, jsii.String("myBucket"), &awss3.BucketProps{})

	// ...

	// Check if the bucket name is unresolved (a token)
	if tokenUnresolved := awscdk.Token_IsUnresolved(myBucketName); tokenUnresolved != nil && *tokenUnresolved {
		fmt.Println("Token identified.")
	} else if tokenUnresolved != nil && !*tokenUnresolved && len(*myBucketName) > 10 {
		panic("Maximum length for name is 10 characters.")
	}

	// ...
}
```

Quando eseguiamo`cdk synth`, `myBucketName` viene identificato come token:

```
$ cdk synth --quiet
Token identified.
```

**Nota**  
È possibile utilizzare le codifiche dei token per sfuggire al sistema di tipi. Ad esempio, potete codificare tramite stringa un token che produce un valore numerico al momento della sintesi. Se utilizzate queste funzioni, è vostra responsabilità assicurarvi che il modello si risolva in uno stato utilizzabile dopo la sintesi.

## Lavorare con token codificati in stringhe
<a name="tokens-string"></a>

I token con codifica in stringa hanno il seguente aspetto.

```
${TOKEN[Bucket.Name.1234]}
```

Possono essere passati in giro come normali stringhe e possono essere concatenati, come mostrato nell'esempio seguente.

**Example**  

```
const functionName = bucket.bucketName + 'Function';
```

```
const functionName = bucket.bucketName + 'Function';
```

```
function_name = bucket.bucket_name + "Function"
```

```
String functionName = bucket.getBucketName().concat("Function");
```

```
string functionName = bucket.BucketName + "Function";
```

```
functionName := *bucket.BucketName() + "Function"
```

È inoltre possibile utilizzare l'interpolazione di stringhe, se la lingua in uso la supporta, come illustrato nell'esempio seguente.

**Example**  

```
const functionName = `${bucket.bucketName}Function`;
```

```
const functionName = `${bucket.bucketName}Function`;
```

```
function_name = f"{bucket.bucket_name}Function"
```

```
String functionName = String.format("%sFunction". bucket.getBucketName());
```

```
string functionName = $"${bucket.bucketName}Function";
```
Utilizza `fmt.Sprintf` per funzionalità simili:  

```
functionName := fmt.Sprintf("%sFunction", *bucket.BucketName())
```

Evita di manipolare la stringa in altri modi. Ad esempio, è probabile che l'acquisizione di una sottostringa di una stringa interrompa il token della stringa.

## Lavorare con token codificati in elenchi
<a name="tokens-list"></a>

I token con codifica a elenco hanno il seguente aspetto:

```
["#{TOKEN[Stack.NotificationArns.1234]}"]
```

L'unica cosa sicura da fare con questi elenchi è passarli direttamente ad altri costrutti. I token in forma di elenco di stringhe non possono essere concatenati, né è possibile prelevare un elemento dal token. L'unico modo sicuro per manipolarli è usare funzioni intrinseche come. AWS CloudFormation [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-select.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-select.html)

## Lavorare con token con codifica numerica
<a name="tokens-number"></a>

I token con codifica numerica sono un insieme di minuscoli numeri negativi a virgola mobile che assomigliano ai seguenti.

```
-1.8881545897087626e+289
```

Come con i token di lista, non è possibile modificare il valore numerico, poiché così facendo si rischia di rompere il token numerico.

Di seguito è riportato un esempio di costrutto che contiene un token codificato come numero:

**Example**  

```
import { Stack, Duration, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as rds from 'aws-cdk-lib/aws-rds';
import * as ec2 from 'aws-cdk-lib/aws-ec2';

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

    // Define a new VPC
    const vpc = new ec2.Vpc(this, 'MyVpc', {
      maxAzs: 3,  // Maximum number of availability zones to use
    });

    // Define an RDS database cluster
    const dbCluster = new rds.DatabaseCluster(this, 'MyRDSCluster', {
      engine: rds.DatabaseClusterEngine.AURORA,
      instanceProps: {
        vpc,
      },
    });

    // Get the port token (this is a token encoded as a number)
    const portToken = dbCluster.clusterEndpoint.port;

    // Print the value for our token at synthesis
    console.log("portToken: " + portToken);
  }
}
```

```
const { Stack, Duration } = require('aws-cdk-lib');
const lambda = require('aws-cdk-lib/aws-lambda');
const rds = require('aws-cdk-lib/aws-rds');
const ec2 = require('aws-cdk-lib/aws-ec2');

class CdkDemoAppStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define a new VPC
    const vpc = new ec2.Vpc(this, 'MyVpc', {
      maxAzs: 3,  // Maximum number of availability zones to use
    });

    // Define an RDS database cluster
    const dbCluster = new rds.DatabaseCluster(this, 'MyRDSCluster', {
      engine: rds.DatabaseClusterEngine.AURORA,
      instanceProps: {
        vpc,
      },
    });

    // Get the port token (this is a token encoded as a number)
    const portToken = dbCluster.clusterEndpoint.port;

    // Print the value for our token at synthesis
    console.log("portToken: " + portToken);
  }
}

module.exports = { CdkDemoAppStack }
```

```
from aws_cdk import (
    Duration,
    Stack,
)
from aws_cdk import aws_rds as rds
from aws_cdk import aws_ec2 as ec2
from constructs import Construct

class CdkDemoAppStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Define a new VPC
        vpc = ec2.Vpc(self, 'MyVpc',
            max_azs=3  # Maximum number of availability zones to use
        )

        # Define an RDS database cluster
        db_cluster = rds.DatabaseCluster(self, 'MyRDSCluster',
            engine=rds.DatabaseClusterEngine.AURORA,
            instance_props=rds.InstanceProps(
                vpc=vpc
            )
        )

        # Get the port token (this is a token encoded as a number)
        port_token = db_cluster.cluster_endpoint.port

        # Print the value for our token at synthesis
        print(f"portToken: {port_token}")
```

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.ec2.Vpc;
import software.amazon.awscdk.services.rds.DatabaseCluster;
import software.amazon.awscdk.services.rds.DatabaseClusterEngine;
import software.amazon.awscdk.services.rds.InstanceProps;

public class CdkDemoAppStack extends Stack {
    public CdkDemoAppStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkDemoAppStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // Define a new VPC
        Vpc vpc = Vpc.Builder.create(this, "MyVpc")
            .maxAzs(3) // Maximum number of availability zones to use
            .build();

        // Define an RDS database cluster
        DatabaseCluster dbCluster = DatabaseCluster.Builder.create(this, "MyRDSCluster")
            .engine(DatabaseClusterEngine.AURORA)
            .instanceProps(InstanceProps.builder()
                .vpc(vpc)
                .build())
            .build();

        // Get the port token (this is a token encoded as a number)
        Number portToken = dbCluster.getClusterEndpoint().getPort();

        // Print the value for our token at synthesis
        System.out.println("portToken: " + portToken);
    }
}
```

```
using Amazon.CDK;
using Constructs;
using Amazon.CDK.AWS.EC2;
using Amazon.CDK.AWS.RDS;
using System;
using System.Collections.Generic;

namespace CdkDemoApp
{
    public class CdkDemoAppStack : Stack
    {
        internal CdkDemoAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // Define a new VPC
            var vpc = new Vpc(this, "MyVpc", new VpcProps
            {
                MaxAzs = 3  // Maximum number of availability zones to use
            });

            // Define an RDS database cluster
            var dbCluster = new DatabaseCluster(this, "MyRDSCluster", new DatabaseClusterProps
            {
                Engine = DatabaseClusterEngine.AURORA,  // Remove parentheses
                InstanceProps = new Amazon.CDK.AWS.RDS.InstanceProps // Specify RDS InstanceProps
                {
                    Vpc = vpc
                }
            });

            // Get the port token (this is a token encoded as a number)
            var portToken = dbCluster.ClusterEndpoint.Port;

            // Print the value for our token at synthesis
            System.Console.WriteLine($"portToken: {portToken}");
        }
    }
}
```

```
package main

import (
	"fmt"

	"github.com/aws/aws-cdk-go/awscdk/v2"
	"github.com/aws/aws-cdk-go/awscdk/v2/awsec2"
	"github.com/aws/aws-cdk-go/awscdk/v2/awsrds"
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
)

type CdkDemoAppStackProps struct {
	awscdk.StackProps
}

func NewCdkDemoAppStack(scope constructs.Construct, id string, props *CdkDemoAppStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	// Define a new VPC
	vpc := awsec2.NewVpc(stack, jsii.String("MyVpc"), &awsec2.VpcProps{
		MaxAzs: jsii.Number(3), // Maximum number of availability zones to use
	})

	// Define an RDS database cluster
	dbCluster := awsrds.NewDatabaseCluster(stack, jsii.String("MyRDSCluster"), &awsrds.DatabaseClusterProps{
		Engine: awsrds.DatabaseClusterEngine_AURORA(),
		InstanceProps: &awsrds.InstanceProps{
			Vpc: vpc,
		},
	})

	// Get the port token (this is a token encoded as a number)
	portToken := dbCluster.ClusterEndpoint().Port()

	// Print the value for our token at synthesis
	fmt.Println("portToken: ", portToken)

	return stack
}

// ...
```

Quando eseguiamo`cdk synth`, il valore di `portToken` viene visualizzato come token con codifica numerica:

```
$ cdk synth --quiet
portToken: -1.8881545897087968e+289
```

### Passa token con codifica numerica
<a name="tokens-number-pass"></a>

Quando passate token con codifica numerica ad altri costrutti, può essere opportuno convertirli prima in stringhe. Ad esempio, se desiderate utilizzare il valore di una stringa con codifica numerica come parte di una stringa concatenata, la conversione ne facilita la leggibilità.

Nell'esempio seguente, `portToken` è un token con codifica numerica che vogliamo passare alla nostra funzione Lambda come parte di: `connectionString`

**Example**  

```
import { Stack, Duration, CfnOutput, StackProps } from 'aws-cdk-lib';
// ...
import * as lambda from 'aws-cdk-lib/aws-lambda';

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

    // Define a new VPC
    // ...

    // Define an RDS database cluster
    // ...

    // Get the port token (this is a token encoded as a number)
    const portToken = dbCluster.clusterEndpoint.port;

    // ...

    // Example connection string with the port token as a number
    const connectionString = `jdbc:mysql://mydb.cluster.amazonaws.com:${portToken}/mydatabase`;

    // Use the connection string as an environment variable in a Lambda function
    const myFunction = new lambda.Function(this, 'MyLambdaFunction', {
      runtime: lambda.Runtime.NODEJS_20_X,
      handler: 'index.handler',
      code: lambda.Code.fromInline(`
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
      `),
      environment: {
        DATABASE_CONNECTION_STRING: connectionString,  // Using the port token as part of the string
      },
    });

    // Output the value of our connection string at synthesis
    console.log("connectionString: " + connectionString);

    // Output the connection string
    new CfnOutput(this, 'ConnectionString', {
      value: connectionString,
    });
  }
}
```

```
const { Stack, Duration, CfnOutput } = require('aws-cdk-lib');
// ...
const lambda = require('aws-cdk-lib/aws-lambda');

class CdkDemoAppStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define a new VPC
    // ...

    // Define an RDS database cluster
    // ...

    // Get the port token (this is a token encoded as a number)
    const portToken = dbCluster.clusterEndpoint.port;

    // ...

    // Example connection string with the port token as a number
    const connectionString = `jdbc:mysql://mydb.cluster.amazonaws.com:${portToken}/mydatabase`;

    // Use the connection string as an environment variable in a Lambda function
    const myFunction = new lambda.Function(this, 'MyLambdaFunction', {
      runtime: lambda.Runtime.NODEJS_20_X,
      handler: 'index.handler',
      code: lambda.Code.fromInline(`
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
      `),
      environment: {
        DATABASE_CONNECTION_STRING: connectionString,  // Using the port token as part of the string
      },
    });

    // Output the value of our connection string at synthesis
    console.log("connectionString: " + connectionString);

    // Output the connection string
    new CfnOutput(this, 'ConnectionString', {
      value: connectionString,
    });
  }
}

module.exports = { CdkDemoAppStack }
```

```
from aws_cdk import (
    Duration,
    Stack,
    CfnOutput,
)
from aws_cdk import aws_lambda as _lambda
# ...

class CdkDemoAppStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Define a new VPC
        # ...

        # Define an RDS database cluster
        # ...

        # Get the port token (this is a token encoded as a number)
        port_token = db_cluster.cluster_endpoint.port

        # ...

        # Example connection string with the port token as a number
        connection_string = f"jdbc:mysql://mydb.cluster.amazonaws.com:{port_token}/mydatabase"

        # Use the connection string as an environment variable in a Lambda function
        my_function = _lambda.Function(self, 'MyLambdaFunction',
            runtime=_lambda.Runtime.NODEJS_20_X,
            handler='index.handler',
            code=_lambda.Code.from_inline("""
                exports.handler = async function(event) {
                    return {
                        statusCode: 200,
                        body: JSON.stringify('Hello World!'),
                    };
                };
            """),
            environment={
                'DATABASE_CONNECTION_STRING': connection_string  # Using the port token as part of the string
            }
        )

        # Output the value of our connection string at synthesis
        print(f"connectionString: {connection_string}")

        # Output the connection string
        CfnOutput(self, 'ConnectionString',
            value=connection_string
        )
```

```
// ...
import software.amazon.awscdk.CfnOutput;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.lambda.Runtime;
import software.amazon.awscdk.services.lambda.Code;

import java.util.Map;

public class CdkDemoAppStack extends Stack {
    public CdkDemoAppStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkDemoAppStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // Define a new VPC
        // ...

        // Define an RDS database cluster
        // ...

        // Get the port token (this is a token encoded as a number)
        Number portToken = dbCluster.getClusterEndpoint().getPort();

        // ...

        // Example connection string with the port token as a number
        String connectionString = "jdbc:mysql://mydb.cluster.amazonaws.com:" + portToken + "/mydatabase";

        // Use the connection string as an environment variable in a Lambda function
        Function myFunction = Function.Builder.create(this, "MyLambdaFunction")
            .runtime(Runtime.NODEJS_20_X)
            .handler("index.handler")
            .code(Code.fromInline(
                "exports.handler = async function(event) {\n" +
                "  return {\n" +
                "    statusCode: 200,\n" +
                "    body: JSON.stringify('Hello World!'),\n" +
                "  };\n" +
                "};"))
            .environment(Map.of(
                "DATABASE_CONNECTION_STRING", connectionString // Using the port token as part of the string
            ))
            .build();

        // Output the value of our connection string at synthesis
        System.out.println("connectionString: " + connectionString);

        // Output the connection string
        CfnOutput.Builder.create(this, "ConnectionString")
            .value(connectionString)
            .build();
    }
}
```

```
// ...
using Amazon.CDK.AWS.Lambda;
using Amazon.CDK.AWS.RDS;
using Amazon.CDK;
using Constructs;
using System;
using System.Collections.Generic;

namespace CdkDemoApp
{
    public class CdkDemoAppStack : Stack
    {
        internal CdkDemoAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // Define a new VPC
            // ...

            // Define an RDS database cluster
            var dbCluster = new DatabaseCluster(this, "MyRDSCluster", new DatabaseClusterProps
            {
                // ... properties would go here
            });

            // Get the port token (this is a token encoded as a number)
            var portToken = dbCluster.ClusterEndpoint.Port;

            // ...

            // Example connection string with the port token as a number
            var connectionString = $"jdbc:mysql://mydb.cluster.amazonaws.com:{portToken}/mydatabase";

            // Use the connection string as an environment variable in a Lambda function
            var myFunction = new Function(this, "MyLambdaFunction", new FunctionProps
            {
                Runtime = Runtime.NODEJS_20_X,
                Handler = "index.handler",
                Code = Code.FromInline(@"
                    exports.handler = async function(event) {
                        return {
                            statusCode: 200,
                            body: JSON.stringify('Hello World!'),
                        };
                    };
                "),
                Environment = new Dictionary<string, string>
                {
                    { "DATABASE_CONNECTION_STRING", connectionString }  // Using the port token as part of the string
                }
            });

            // Output the value of our connection string at synthesis
            Console.WriteLine($"connectionString: {connectionString}");

            // Output the connection string
            new CfnOutput(this, "ConnectionString", new CfnOutputProps
            {
                Value = connectionString
            });
        }
    }
}
```

```
// ...
	"github.com/aws/aws-cdk-go/awscdk/v2/awslambda"
)

type CdkDemoAppStackProps struct {
	awscdk.StackProps
}

func NewCdkDemoAppStack(scope constructs.Construct, id string, props *CdkDemoAppStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	// Define a new VPC
	// ...

	// Define an RDS database cluster
	// ...

	// Get the port token (this is a token encoded as a number)
	portToken := dbCluster.ClusterEndpoint().Port()

	// ...

	// Example connection string with the port token as a number
	 connectionString := fmt.Sprintf("jdbc:mysql://mydb.cluster.amazonaws.com:%s/mydatabase", portToken)

	// Use the connection string as an environment variable in a Lambda function
	myFunction := awslambda.NewFunction(stack, jsii.String("MyLambdaFunction"), &awslambda.FunctionProps{
		Runtime: awslambda.Runtime_NODEJS_20_X(),
		Handler: jsii.String("index.handler"),
		Code: awslambda.Code_FromInline(jsii.String(`
			exports.handler = async function(event) {
				return {
					statusCode: 200,
					body: JSON.stringify('Hello World!'),
				};
			};
		`)),
		Environment: &map[string]*string{
			"DATABASE_CONNECTION_STRING": jsii.String(connectionString), // Using the port token as part of the string
		},
	})

	// Output the value of our connection string at synthesis
	fmt.Println("connectionString: ", connectionString)

	// Output the connection string
	awscdk.NewCfnOutput(stack, jsii.String("ConnectionString"), &awscdk.CfnOutputProps{
		Value: jsii.String(connectionString),
	})

	return stack
}

// ...
```

Se passiamo questo valore a`connectionString`, il valore di output durante l'esecuzione `cdk synth` potrebbe creare confusione a causa della stringa con codifica numerica:

```
$ cdk synth --quiet
connectionString: jdbc:mysql://mydb.cluster.amazonaws.com:-1.888154589708796e+289/mydatabase
```

Per convertire un token con codifica numerica in una stringa, usa. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tokenization.html#static-stringifywbrnumberx](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tokenization.html#static-stringifywbrnumberx) Nell'esempio seguente, convertiamo il token con codifica numerica in una stringa prima di definire la nostra stringa di connessione:

**Example**  

```
import { Stack, Duration, Tokenization, CfnOutput, StackProps } from 'aws-cdk-lib';
// ...

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

    // Define a new VPC
    // ...

    // Define an RDS database cluster
    // ...

    // Get the port token (this is a token encoded as a number)
    const portToken = dbCluster.clusterEndpoint.port;

    // ...

    // Convert the encoded number to an encoded string for use in the connection string
    const portAsString = Tokenization.stringifyNumber(portToken);

    // Example connection string with the port token as a string
    const connectionString = `jdbc:mysql://mydb.cluster.amazonaws.com:${portAsString}/mydatabase`;

    // Use the connection string as an environment variable in a Lambda function
    const myFunction = new lambda.Function(this, 'MyLambdaFunction', {
      // ...
      environment: {
        DATABASE_CONNECTION_STRING: connectionString,  // Using the port token as part of the string
      },
    });

    // Output the value of our connection string at synthesis
    console.log("connectionString: " + connectionString);

    // Output the connection string
    new CfnOutput(this, 'ConnectionString', {
      value: connectionString,
    });
  }
}
```

```
const { Stack, Duration, Tokenization, CfnOutput } = require('aws-cdk-lib');
// ...

class CdkDemoAppStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define a new VPC
    // ...

    // Define an RDS database cluster
    // ...

    // Get the port token (this is a token encoded as a number)
    const portToken = dbCluster.clusterEndpoint.port;

    // ...

    // Convert the encoded number to an encoded string for use in the connection string
    const portAsString = Tokenization.stringifyNumber(portToken);

    // Example connection string with the port token as a string
    const connectionString = `jdbc:mysql://mydb.cluster.amazonaws.com:${portAsString}/mydatabase`;

    // Use the connection string as an environment variable in a Lambda function
    const myFunction = new lambda.Function(this, 'MyLambdaFunction', {
      // ...
      environment: {
        DATABASE_CONNECTION_STRING: connectionString,  // Using the port token as part of the string
      },
    });

    // Output the value of our connection string at synthesis
    console.log("connectionString: " + connectionString);

    // Output the connection string
    new CfnOutput(this, 'ConnectionString', {
      value: connectionString,
    });
  }
}

module.exports = { CdkDemoAppStack }
```

```
from aws_cdk import (
    Duration,
    Stack,
    Tokenization,
    CfnOutput,
)
# ...

class CdkDemoAppStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Define a new VPC
        # ...

        # Define an RDS database cluster
        # ...

        # Get the port token (this is a token encoded as a number)
        port_token = db_cluster.cluster_endpoint.port

        # Convert the encoded number to an encoded string for use in the connection string
        port_as_string = Tokenization.stringify_number(port_token)

        # Example connection string with the port token as a string
        connection_string = f"jdbc:mysql://mydb.cluster.amazonaws.com:{port_as_string}/mydatabase"

        # Use the connection string as an environment variable in a Lambda function
        my_function = _lambda.Function(self, 'MyLambdaFunction',
            # ...
            environment={
                'DATABASE_CONNECTION_STRING': connection_string  # Using the port token as part of the string
            }
        )

        # Output the value of our connection string at synthesis
        print(f"connectionString: {connection_string}")

        # Output the connection string
        CfnOutput(self, 'ConnectionString',
            value=connection_string
        )
```

```
// ...
import software.amazon.awscdk.Tokenization;

public class CdkDemoAppStack extends Stack {
    public CdkDemoAppStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkDemoAppStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // Define a new VPC
        // ...

        // Define an RDS database cluster
        // ...

        // Get the port token (this is a token encoded as a number)
        Number portToken = dbCluster.getClusterEndpoint().getPort();

        // ...

        // Convert the encoded number to an encoded string for use in the connection string
        String portAsString = Tokenization.stringifyNumber(portToken);

        // Example connection string with the port token as a string
        String connectionString = "jdbc:mysql://mydb.cluster.amazonaws.com:" + portAsString + "/mydatabase";

        // Use the connection string as an environment variable in a Lambda function
        Function myFunction = Function.Builder.create(this, "MyLambdaFunction")
            // ...
            .environment(Map.of(
                "DATABASE_CONNECTION_STRING", connectionString // Using the port token as part of the string
            ))
            .build();

        // Output the value of our connection string at synthesis
        System.out.println("connectionString: " + connectionString);

        // Output the connection string
        CfnOutput.Builder.create(this, "ConnectionString")
            .value(connectionString)
            .build();
    }
}
```

```
// ...

namespace CdkDemoApp
{
    public class CdkDemoAppStack : Stack
    {
        internal CdkDemoAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // Define a new VPC
            // ...

            // Define an RDS database cluster
            // ...

            // Get the port token (this is a token encoded as a number)
            var portToken = dbCluster.ClusterEndpoint.Port;

            // ...

            // Convert the encoded number to an encoded string for use in the connection string
            var portAsString = Tokenization.StringifyNumber(portToken);

            // Example connection string with the port token as a string
            var connectionString = $"jdbc:mysql://mydb.cluster.amazonaws.com:{portAsString}/mydatabase";

            // Use the connection string as an environment variable in a Lambda function
            var myFunction = new Function(this, "MyLambdaFunction", new FunctionProps
            {
                // ...
                Environment = new Dictionary<string, string>
                {
                    { "DATABASE_CONNECTION_STRING", connectionString }  // Using the port token as part of the string
                }
            });

            // Output the value of our connection string at synthesis
            Console.WriteLine($"connectionString: {connectionString}");

            // Output the connection string
            new CfnOutput(this, "ConnectionString", new CfnOutputProps
            {
                Value = connectionString
            });
        }
    }
}
```

```
// ...

func NewCdkDemoAppStack(scope constructs.Construct, id string, props *CdkDemoAppStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	// Define a new VPC
	// ...

	// Define an RDS database cluster
	// ...

	// Get the port token (this is a token encoded as a number)
	portToken := dbCluster.ClusterEndpoint().Port()

	// ...

	// Convert the encoded number to an encoded string for use in the connection string
	portAsString := awscdk.Tokenization_StringifyNumber(portToken)

	// Example connection string with the port token as a string
	connectionString := fmt.Sprintf("jdbc:mysql://mydb.cluster.amazonaws.com:%s/mydatabase", portAsString)

	// Use the connection string as an environment variable in a Lambda function
	myFunction := awslambda.NewFunction(stack, jsii.String("MyLambdaFunction"), &awslambda.FunctionProps{
		// ...
		Environment: &map[string]*string{
			"DATABASE_CONNECTION_STRING": jsii.String(connectionString), // Using the port token as part of the string
		},
	})

	// Output the value of our connection string at synthesis
	fmt.Println("connectionString: ", connectionString)

	// Output the connection string
	awscdk.NewCfnOutput(stack, jsii.String("ConnectionString"), &awscdk.CfnOutputProps{
		Value: jsii.String(connectionString),
	})

	fmt.Println(myFunction)

	return stack
}

// ...
```

Quando eseguiamo`cdk synth`, il valore della nostra stringa di connessione è rappresentato in un formato più pulito e chiaro:

```
$ cdk synth --quiet
connectionString: jdbc:mysql://mydb.cluster.amazonaws.com:${Token[TOKEN.242]}/mydatabase
```

## Valori pigri
<a name="tokens-lazy"></a>

Oltre a rappresentare i valori del tempo di implementazione, come i AWS CloudFormation [parametri, i](parameters.md) token vengono comunemente utilizzati anche per rappresentare valori lazy in fase di sintesi. Si tratta di valori per i quali il valore finale verrà determinato prima del completamento della sintesi, ma non nel punto in cui viene costruito il valore. Utilizzate i token per passare una stringa letterale o un valore numerico a un altro costrutto, mentre il valore effettivo al momento della sintesi potrebbe dipendere da alcuni calcoli che devono ancora essere eseguiti.

È possibile creare token che rappresentano valori lazy in fase di sintetizzazione utilizzando metodi statici sulla classe, come e. `Lazy` [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Lazy.html#static-stringproducer-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Lazy.html#static-stringproducer-options) Questi metodi accettano un oggetto la cui `produce` proprietà è una funzione che accetta un argomento di contesto e restituisce il valore finale quando viene chiamata.

L'esempio seguente crea un gruppo Auto Scaling la cui capacità viene determinata dopo la sua creazione.

**Example**  

```
let actualValue: number;

new AutoScalingGroup(this, 'Group', {
  desiredCapacity: Lazy.numberValue({
    produce(context) {
      return actualValue;
    }
  })
});

// At some later point
actualValue = 10;
```

```
let actualValue;

new AutoScalingGroup(this, 'Group', {
  desiredCapacity: Lazy.numberValue({
    produce(context) {
      return (actualValue);
    }
  })
});

// At some later point
actualValue = 10;
```

```
class Producer:
    def __init__(self, func):
        self.produce = func

actual_value = None

AutoScalingGroup(self, "Group",
    desired_capacity=Lazy.number_value(Producer(lambda context: actual_value))
)

# At some later point
actual_value = 10
```

```
double actualValue = 0;

class ProduceActualValue implements INumberProducer {

    @Override
    public Number produce(IResolveContext context) {
        return actualValue;
    }
}

AutoScalingGroup.Builder.create(this, "Group")
    .desiredCapacity(Lazy.numberValue(new ProduceActualValue())).build();

// At some later point
actualValue = 10;
```

```
public class NumberProducer : INumberProducer
{
    Func<Double> function;

    public NumberProducer(Func<Double> function)
    {
        this.function = function;
    }

    public Double Produce(IResolveContext context)
    {
        return function();
    }
}

double actualValue = 0;

new AutoScalingGroup(this, "Group", new AutoScalingGroupProps
{
    DesiredCapacity = Lazy.NumberValue(new NumberProducer(() => actualValue))
});

// At some later point
actualValue = 10;
```

## Conversione in JSON
<a name="tokens-json"></a>

A volte vuoi produrre una stringa JSON di dati arbitrari e potresti non sapere se i dati contengono token. Per codificare correttamente in JSON qualsiasi struttura di dati, indipendentemente dal fatto che contenga o meno token, utilizzate il metodo [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#towbrjsonwbrstringobj-space](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#towbrjsonwbrstringobj-space), come illustrato nell'esempio seguente.

**Example**  

```
const stack = Stack.of(this);
const str = stack.toJsonString({
  value: bucket.bucketName
});
```

```
const stack = Stack.of(this);
const str = stack.toJsonString({
  value: bucket.bucketName
});
```

```
stack = Stack.of(self)
string = stack.to_json_string(dict(value=bucket.bucket_name))
```

```
Stack stack = Stack.of(this);
String stringVal = stack.toJsonString(java.util.Map.of(    // Map.of requires Java 9+
        put("value", bucket.getBucketName())));
```

```
var stack = Stack.Of(this);
var stringVal = stack.ToJsonString(new Dictionary<string, string>
{
    ["value"] = bucket.BucketName
});
```

# Parametri e AWS CDK
<a name="parameters"></a>

 *I parametri* sono valori personalizzati forniti al momento della distribuzione. [I parametri](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html) sono una funzionalità di AWS CloudFormation. Poiché il AWS Cloud Development Kit (AWS CDK) sintetizza i AWS CloudFormation modelli, offre anche supporto per i parametri del tempo di implementazione.

## Informazioni sui parametri
<a name="parameters-about"></a>

Utilizzando il AWS CDK, è possibile definire i parametri, che possono quindi essere utilizzati nelle proprietà dei costrutti creati. È inoltre possibile distribuire pile che contengono parametri.

Quando si distribuisce il AWS CloudFormation modello utilizzando la AWS CLI CDK, si forniscono i valori dei parametri sulla riga di comando. Se si distribuisce il modello tramite la AWS CloudFormation console, vengono richiesti i valori dei parametri.

In generale, si consiglia di non utilizzare i AWS CloudFormation parametri con il AWS CDK. I metodi usuali per passare valori nelle app AWS CDK sono i [valori di contesto](context.md) e le variabili di ambiente. Poiché non sono disponibili al momento della sintesi, i valori dei parametri non possono essere utilizzati facilmente per il controllo del flusso e per altri scopi nell'app CDK.

**Nota**  
Per controllare il flusso con i parametri, è possibile utilizzare [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.CfnCondition.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.CfnCondition.html)i costrutti, sebbene ciò sia scomodo rispetto alle istruzioni native. `if`

L'utilizzo dei parametri richiede di prestare attenzione al comportamento del codice che state scrivendo al momento della distribuzione e anche in fase di sintesi. Ciò rende più difficile comprendere e ragionare sull'applicazione AWS CDK, in molti casi con scarsi vantaggi.

In genere, è meglio fare in modo che l'app CDK accetti le informazioni necessarie in un modo ben definito e le utilizzi direttamente per dichiarare i costrutti nell'app CDK. Un AWS CloudFormation modello ideale AWS generato da CDK è concreto, senza altri valori da specificare al momento dell'implementazione.

Esistono, tuttavia, casi d'uso per i quali i AWS CloudFormation parametri si adattano in modo univoco. Se disponi di team separati che definiscono e implementano l'infrastruttura, ad esempio, puoi utilizzare i parametri per rendere i modelli generati più utili. Inoltre, poiché il AWS CDK supporta i AWS CloudFormation parametri, è possibile utilizzare il AWS CDK con AWS servizi che utilizzano AWS CloudFormation modelli (come Service Catalog). Questi AWS servizi utilizzano parametri per configurare il modello che viene distribuito.

## Ulteriori informazioni
<a name="parameters-learn"></a>

Per istruzioni sullo sviluppo di app CDK con parametri, consulta [Usare CloudFormation i parametri per ottenere un CloudFormation valore](get-cfn-param.md).

# Tag e AWS CDK
<a name="tagging"></a>

I tag sono elementi chiave-valore informativi che puoi aggiungere ai costrutti dell'app CDK. AWS Un tag applicato a un determinato costrutto si applica anche a tutti i suoi figli taggabili. I tag sono inclusi nel AWS CloudFormation modello sintetizzato dall'app e vengono applicati alle risorse che distribuisce. AWS Puoi utilizzare i tag per identificare e classificare le risorse per i seguenti scopi:
+ Semplificazione della gestione
+ Allocazione dei costi
+ Controllo accessi
+ Qualsiasi altro scopo da te ideato

**Suggerimento**  
*Per ulteriori informazioni su come utilizzare i tag con AWS le risorse, consulta le [migliori pratiche per l'etichettatura AWS delle risorse](https://docs.aws.amazon.com/whitepapers/latest/tagging-best-practices/tagging-best-practices.html) nel white paper. AWS *

## Utilizzo dei tag
<a name="tagging-use"></a>

La classe [Tags](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tags.html) include il metodo statico`of()`, tramite il quale è possibile aggiungere o rimuovere tag dal costrutto specificato.
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tags.html#addkey-value-props](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tags.html#addkey-value-props)applica un nuovo tag al costrutto specificato e a tutti i suoi figli.
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tags.html#removekey-props](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tags.html#removekey-props)rimuove un tag dal costrutto dato e da tutti i suoi figli, compresi i tag che un costrutto figlio potrebbe aver applicato a se stesso.

**Nota**  
Il tagging viene implementato utilizzando [Aspects e](aspects.md) il CDK. AWS Gli aspetti sono un modo per applicare un'operazione (come l'etichettatura) a tutti i costrutti in un determinato ambito.

L'esempio seguente applica la **chiave** del tag con il valore **value** a un costrutto.

**Example**  

```
Tags.of(myConstruct).add('key', 'value');
```

```
Tags.of(myConstruct).add('key', 'value');
```

```
Tags.of(my_construct).add("key", "value")
```

```
Tags.of(myConstruct).add("key", "value");
```

```
Tags.Of(myConstruct).Add("key", "value");
```

```
awscdk.Tags_Of(myConstruct).Add(jsii.String("key"), jsii.String("value"), &awscdk.TagProps{})
```

L'esempio seguente elimina la **chiave** del tag da un costrutto.

**Example**  

```
Tags.of(myConstruct).remove('key');
```

```
Tags.of(myConstruct).remove('key');
```

```
Tags.of(my_construct).remove("key")
```

```
Tags.of(myConstruct).remove("key");
```

```
Tags.Of(myConstruct).Remove("key");
```

```
awscdk.Tags_Of(myConstruct).Remove(jsii.String("key"), &awscdk.TagProps{})
```

Se utilizzate `Stage` costrutti, applicate il tag al `Stage` livello o al di sotto. I tag non vengono applicati oltre `Stage` i limiti.

## Priorità dei tag
<a name="tagging-priorities"></a>

Il AWS CDK applica e rimuove i tag in modo ricorsivo. In caso di conflitti, vince l'operazione di tagging con la priorità più alta. (Le priorità vengono impostate utilizzando la `priority` proprietà opzionale). Se le priorità di due operazioni sono le stesse, vince l'operazione di etichettatura più vicina alla parte inferiore dell'albero di costruzione. Per impostazione predefinita, l'applicazione di un tag ha una priorità di 100 (ad eccezione dei tag aggiunti direttamente a una AWS CloudFormation risorsa, che ha una priorità di 50). La priorità predefinita per la rimozione di un tag è 200.

Quanto segue applica un tag con una priorità di 300 a un costrutto.

**Example**  

```
Tags.of(myConstruct).add('key', 'value', {
  priority: 300
});
```

```
Tags.of(myConstruct).add('key', 'value', {
  priority: 300
});
```

```
Tags.of(my_construct).add("key", "value", priority=300)
```

```
Tags.of(myConstruct).add("key", "value", TagProps.builder()
        .priority(300).build());
```

```
Tags.Of(myConstruct).Add("key", "value", new TagProps { Priority = 300 });
```

```
awscdk.Tags_Of(myConstruct).Add(jsii.String("key"), jsii.String("value"), &awscdk.TagProps{
  Priority: jsii.Number(300),
})
```

## Proprietà facoltative
<a name="tagging-props"></a>

I tag [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.TagProps.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.TagProps.html)consentono di ottimizzare il modo in cui i tag vengono applicati o rimossi dalle risorse. Tutte le proprietà sono facoltative.

 `applyToLaunchedInstances`(Python:) `apply_to_launched_instances`  
Disponibile solo per add (). Per impostazione predefinita, i tag vengono applicati alle istanze avviate in un gruppo Auto Scaling. Imposta questa proprietà su **false** per ignorare le istanze avviate in un gruppo Auto Scaling.

 `includeResourceTypes`/`excludeResourceTypes`(Python:`include_resource_types`/) `exclude_resource_types`  
Usali per manipolare i tag solo su un sottoinsieme di risorse, in base AWS CloudFormation ai tipi di risorse. Per impostazione predefinita, l'operazione viene applicata a tutte le risorse del sottoalbero di costruzione, ma può essere modificata includendo o escludendo determinati tipi di risorse. L'esclusione ha la precedenza sull'inclusione, se vengono specificati entrambi.

 `priority`   
Utilizzatelo per impostare la priorità di questa operazione rispetto alle altre `Tags.remove()` operazioni `Tags.add()` and. I valori più alti hanno la precedenza sui valori più bassi. L'impostazione predefinita è 100 per le operazioni di aggiunta (50 per i tag applicati direttamente alle AWS CloudFormation risorse) e 200 per le operazioni di rimozione.

L'esempio seguente applica il tag **tagname con il** valore **value** e la priorità **100** alle risorse di tipo ** AWS: :Xxx: :Yyy** nel costrutto. Non applica il tag alle istanze avviate in un gruppo Amazon EC2 Auto Scaling o a risorse di ** AWS tipo: :Xxx: :Zzz**. (Si tratta di segnaposti per due tipi di risorse arbitrari ma diversi.) AWS CloudFormation 

**Example**  

```
Tags.of(myConstruct).add('tagname', 'value', {
  applyToLaunchedInstances: false,
  includeResourceTypes: ['AWS::Xxx::Yyy'],
  excludeResourceTypes: ['AWS::Xxx::Zzz'],
  priority: 100,
});
```

```
Tags.of(myConstruct).add('tagname', 'value', {
  applyToLaunchedInstances: false,
  includeResourceTypes: ['AWS::Xxx::Yyy'],
  excludeResourceTypes: ['AWS::Xxx::Zzz'],
  priority: 100
});
```

```
Tags.of(my_construct).add("tagname", "value",
    apply_to_launched_instances=False,
    include_resource_types=["AWS::Xxx::Yyy"],
    exclude_resource_types=["AWS::Xxx::Zzz"],
    priority=100)
```

```
Tags.of(myConstruct).add("tagname", "value", TagProps.builder()
                .applyToLaunchedInstances(false)
                .includeResourceTypes(Arrays.asList("AWS::Xxx::Yyy"))
                .excludeResourceTypes(Arrays.asList("AWS::Xxx::Zzz"))
                .priority(100).build());
```

```
Tags.Of(myConstruct).Add("tagname", "value", new TagProps
{
    ApplyToLaunchedInstances = false,
    IncludeResourceTypes = ["AWS::Xxx::Yyy"],
    ExcludeResourceTypes = ["AWS::Xxx::Zzz"],
    Priority = 100
});
```

```
awscdk.Tags_Of(myConstruct).Add(jsii.String("tagname"), jsii.String("value"), &awscdk.TagProps{
  ApplyToLaunchedInstances: jsii.Bool(false),
  IncludeResourceTypes:     &[]*string{jsii.String("AWS::Xxx:Yyy")},
  ExcludeResourceTypes:     &[]*string{jsii.String("AWS::Xxx:Zzz")},
  Priority:                 jsii.Number(100),
})
```

**L'esempio seguente rimuove il tag **tagname** con priorità **200** dalle risorse di tipo ** AWS: :Xxx: :Yyy** nel costrutto, ma non dalle risorse di tipo: :Xxx: :Zzz. AWS**

**Example**  

```
Tags.of(myConstruct).remove('tagname', {
  includeResourceTypes: ['AWS::Xxx::Yyy'],
  excludeResourceTypes: ['AWS::Xxx::Zzz'],
  priority: 200,
});
```

```
Tags.of(myConstruct).remove('tagname', {
  includeResourceTypes: ['AWS::Xxx::Yyy'],
  excludeResourceTypes: ['AWS::Xxx::Zzz'],
  priority: 200
});
```

```
Tags.of(my_construct).remove("tagname",
    include_resource_types=["AWS::Xxx::Yyy"],
    exclude_resource_types=["AWS::Xxx::Zzz"],
    priority=200,)
```

```
Tags.of((myConstruct).remove("tagname", TagProps.builder()
        .includeResourceTypes(Arrays.asList("AWS::Xxx::Yyy"))
        .excludeResourceTypes(Arrays.asList("AWS::Xxx::Zzz"))
        .priority(100).build());
        )
```

```
Tags.Of(myConstruct).Remove("tagname", new TagProps
{
    IncludeResourceTypes = ["AWS::Xxx::Yyy"],
    ExcludeResourceTypes = ["AWS::Xxx::Zzz"],
    Priority = 100
});
```

```
awscdk.Tags_Of(myConstruct).Remove(jsii.String("tagname"), &awscdk.TagProps{
  IncludeResourceTypes: &[]*string{jsii.String("AWS::Xxx:Yyy")},
  ExcludeResourceTypes: &[]*string{jsii.String("AWS::Xxx:Zzz")},
  Priority:             jsii.Number(200),
})
```

## Esempio
<a name="tagging-example"></a>

L'esempio seguente aggiunge il tag key **StackType**con valore **TheBest**a qualsiasi risorsa creata all'interno del file denominato. `Stack` `MarketingSystem` Quindi lo rimuove nuovamente da tutte le risorse tranne le sottoreti Amazon EC2 VPC. Il risultato è che solo le sottoreti hanno il tag applicato.

**Example**  

```
import { App, Stack, Tags } from 'aws-cdk-lib';

const app = new App();
const theBestStack = new Stack(app, 'MarketingSystem');

// Add a tag to all constructs in the stack
Tags.of(theBestStack).add('StackType', 'TheBest');

// Remove the tag from all resources except subnet resources
Tags.of(theBestStack).remove('StackType', {
  excludeResourceTypes: ['AWS::EC2::Subnet']
});
```

```
const { App, Stack, Tags } = require('aws-cdk-lib');

const app = new App();
const theBestStack = new Stack(app, 'MarketingSystem');

// Add a tag to all constructs in the stack
Tags.of(theBestStack).add('StackType', 'TheBest');

// Remove the tag from all resources except subnet resources
Tags.of(theBestStack).remove('StackType', {
  excludeResourceTypes: ['AWS::EC2::Subnet']
});
```

```
from aws_cdk import App, Stack, Tags

app = App();
the_best_stack = Stack(app, 'MarketingSystem')

# Add a tag to all constructs in the stack
Tags.of(the_best_stack).add("StackType", "TheBest")

# Remove the tag from all resources except subnet resources
Tags.of(the_best_stack).remove("StackType",
    exclude_resource_types=["AWS::EC2::Subnet"])
```

```
import software.amazon.awscdk.App;
import software.amazon.awscdk.Tags;

// Add a tag to all constructs in the stack
Tags.of(theBestStack).add("StackType", "TheBest");

// Remove the tag from all resources except subnet resources
Tags.of(theBestStack).remove("StackType", TagProps.builder()
        .excludeResourceTypes(Arrays.asList("AWS::EC2::Subnet"))
        .build());
```

```
using Amazon.CDK;

var app = new App();
var theBestStack = new Stack(app, 'MarketingSystem');

// Add a tag to all constructs in the stack
Tags.Of(theBestStack).Add("StackType", "TheBest");

// Remove the tag from all resources except subnet resources
Tags.Of(theBestStack).Remove("StackType", new TagProps
{
    ExcludeResourceTypes = ["AWS::EC2::Subnet"]
});
```

```
import "github.com/aws/aws-cdk-go/awscdk/v2"
app := awscdk.NewApp(nil)
theBestStack := awscdk.NewStack(app, jsii.String("MarketingSystem"), &awscdk.StackProps{})

// Add a tag to all constructs in the stack
awscdk.Tags_Of(theBestStack).Add(jsii.String("StackType"), jsii.String("TheBest"), &awscdk.TagProps{})

// Remove the tag from all resources except subnet resources
awscdk.Tags_Of(theBestStack).Add(jsii.String("StackType"), jsii.String("TheBest"), &awscdk.TagProps{
  ExcludeResourceTypes: &[]*string{jsii.String("AWS::EC2::Subnet")},
})
```

Il codice seguente consente di ottenere lo stesso risultato. Considerate quale approccio (inclusione o esclusione) rende più chiaro il vostro intento.

**Example**  

```
Tags.of(theBestStack).add('StackType', 'TheBest',
  { includeResourceTypes: ['AWS::EC2::Subnet']});
```

```
Tags.of(theBestStack).add('StackType', 'TheBest',
  { includeResourceTypes: ['AWS::EC2::Subnet']});
```

```
Tags.of(the_best_stack).add("StackType", "TheBest",
    include_resource_types=["AWS::EC2::Subnet"])
```

```
Tags.of(theBestStack).add("StackType", "TheBest", TagProps.builder()
        .includeResourceTypes(Arrays.asList("AWS::EC2::Subnet"))
        .build());
```

```
Tags.Of(theBestStack).Add("StackType", "TheBest", new TagProps {
    IncludeResourceTypes = ["AWS::EC2::Subnet"]
});
```

```
awscdk.Tags_Of(theBestStack).Add(jsii.String("StackType"), jsii.String("TheBest"), &awscdk.TagProps{
  IncludeResourceTypes: &[]*string{jsii.String("AWS::EC2::Subnet")},
})
```

## Etichettatura di singoli costrutti
<a name="tagging-single"></a>

 `Tags.of(scope).add(key, value)`è il modo standard per aggiungere tag ai costrutti nel CDK. AWS Il suo comportamento di tree-walking, che contrassegna in modo ricorsivo tutte le risorse taggabili nell'ambito di un determinato ambito, è quasi sempre quello che si desidera. A volte, tuttavia, è necessario etichettare uno o più costrutti specifici e arbitrari.

Uno di questi casi prevede l'applicazione di tag il cui valore deriva da alcune proprietà del costrutto da etichettare. L'approccio di etichettatura standard applica in modo ricorsivo la stessa chiave e lo stesso valore a tutte le risorse corrispondenti nell'ambito. Tuttavia, qui il valore potrebbe essere diverso per ogni costrutto taggato.

I tag vengono implementati utilizzando [gli aspetti](aspects.md) e il CDK chiama il `visit()` metodo del tag per ogni costrutto nell'ambito specificato. `Tags.of(scope)` Possiamo chiamare `Tag.visit()` direttamente per applicare un tag a un singolo costrutto.

**Example**  

```
new cdk.Tag(key, value).visit(scope);
```

```
new cdk.Tag(key, value).visit(scope);
```

```
cdk.Tag(key, value).visit(scope)
```

```
Tag.Builder.create(key, value).build().visit(scope);
```

```
new Tag(key, value).Visit(scope);
```

```
awscdk.NewTag(key, value, &awscdk.TagProps{}).Visit(scope)
```

È possibile etichettare tutti i costrutti in un ambito, ma lasciare che i valori dei tag derivino dalle proprietà di ciascun costrutto. A tale scopo, scrivete un aspetto e applicate il tag nel `visit()` metodo dell'aspetto, come mostrato nell'esempio precedente. Quindi, aggiungete l'aspetto all'ambito desiderato utilizzando`Aspects.of(scope).add(aspect)`.

L'esempio seguente applica un tag a ciascuna risorsa in uno stack contenente il percorso della risorsa.

**Example**  

```
class PathTagger implements cdk.IAspect {
  visit(node: IConstruct) {
    new cdk.Tag("aws-cdk-path", node.node.path).visit(node);
  }
}

stack = new MyStack(app);
cdk.Aspects.of(stack).add(new PathTagger())
```

```
class PathTagger {
  visit(node) {
    new cdk.Tag("aws-cdk-path", node.node.path).visit(node);
  }
}

stack = new MyStack(app);
cdk.Aspects.of(stack).add(new PathTagger())
```

```
@jsii.implements(cdk.IAspect)
class PathTagger:
    def visit(self, node: IConstruct):
        cdk.Tag("aws-cdk-path", node.node.path).visit(node)

stack = MyStack(app)
cdk.Aspects.of(stack).add(PathTagger())
```

```
final class PathTagger implements IAspect {
	public void visit(IConstruct node) {
		Tag.Builder.create("aws-cdk-path", node.getNode().getPath()).build().visit(node);
	}
}

stack stack = new MyStack(app);
Aspects.of(stack).add(new PathTagger());
```

```
public class PathTagger : IAspect
{
    public void Visit(IConstruct node)
    {
        new Tag("aws-cdk-path", node.Node.Path).Visit(node);
    }
}

var stack = new MyStack(app);
Aspects.Of(stack).Add(new PathTagger);
```

**Suggerimento**  
La logica dell'etichettatura condizionale, che include priorità, tipi di risorse e così via, è integrata nella classe. `Tag` È possibile utilizzare queste funzionalità quando si applicano tag a risorse arbitrarie; il tag non viene applicato se le condizioni non sono soddisfatte. Inoltre, la `Tag` classe tagga solo le risorse etichettabili, quindi non è necessario verificare se un costrutto è taggabile prima di applicare un tag.

# Risorse e AWS CDK
<a name="assets"></a>

Le risorse sono file, directory o immagini Docker locali che possono essere raggruppati in librerie e app AWS CDK. Ad esempio, una risorsa potrebbe essere una directory che contiene il codice del gestore per una funzione AWS Lambda. Le risorse possono rappresentare qualsiasi elemento di cui l'app ha bisogno per funzionare.

Il seguente video tutorial fornisce una panoramica completa delle risorse CDK e spiega come utilizzarle nella propria infrastruttura come codice (IaC).

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/jHNtXQmkKfw?rel=0/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/jHNtXQmkKfw?rel=0)


Si aggiungono risorse APIs che sono esposte da costrutti specifici AWS . Ad esempio, quando definite un [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html)costrutto, la [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html#code](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html#code)proprietà consente di passare una [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Code.html#static-fromwbrassetpath-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Code.html#static-fromwbrassetpath-options)(directory). `Function`utilizza le risorse per raggruppare il contenuto della directory e utilizzarlo per il codice della funzione. Allo stesso modo, [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs.ContainerImage.html#static-fromwbrassetdirectory-props](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs.ContainerImage.html#static-fromwbrassetdirectory-props)utilizza un'immagine Docker creata da una directory locale per definire una definizione di attività Amazon ECS.

## Risorse in dettaglio
<a name="assets-details"></a>

Quando fai riferimento a una risorsa nell'app, l'[assembly cloud](deploy.md#deploy-how-synth-assemblies) sintetizzato dall'applicazione include informazioni sui metadati con istruzioni per la CLI AWS CDK. Le istruzioni includono dove trovare la risorsa sul disco locale e che tipo di raggruppamento eseguire in base al tipo di risorsa, ad esempio una directory da comprimere (zip) o un'immagine Docker da creare.

Il AWS CDK genera un hash sorgente per le risorse. Questo può essere utilizzato in fase di costruzione per determinare se il contenuto di un asset è cambiato.

Per impostazione predefinita, il AWS CDK crea una copia della risorsa nella directory di cloud assembly, che per impostazione predefinita è`cdk.out`, sotto l'hash di origine. In questo modo, l'assembly cloud è autonomo, quindi se viene spostato su un altro host per l'implementazione, può comunque essere distribuito. Vedi [Cloud Assemblies](deploy.md#deploy-how-synth-assemblies) per i dettagli.

Quando il AWS CDK distribuisce un'app che fa riferimento alle risorse (direttamente tramite il codice dell'app o tramite una libreria), la CLI di AWS CDK prepara e pubblica le risorse in un bucket Amazon S3 o in un repository Amazon ECR. (Il bucket o il repository S3 viene creato durante il bootstrap.) Solo allora vengono distribuite le risorse definite nello stack.

Questa sezione descrive il basso livello APIs disponibile nel framework.

## Tipi di risorse
<a name="assets-types"></a>

Il AWS CDK supporta i seguenti tipi di asset:

Risorse Amazon S3  
Si tratta di file e directory locali che il AWS CDK carica su Amazon S3.

Immagine Docker  
Si tratta di immagini Docker che il AWS CDK carica su Amazon ECR.

Questi tipi di risorse sono spiegati nelle seguenti sezioni.

## Risorse Amazon S3
<a name="assets-types-s3"></a>

Puoi definire file e directory locali come risorse e il AWS CDK li impacchetta e li carica su Amazon S3 tramite il modulo. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3_assets-readme.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3_assets-readme.html)

L'esempio seguente definisce una risorsa di directory locale e una risorsa di file.

**Example**  

```
import { Asset } from 'aws-cdk-lib/aws-s3-assets';

// Archived and uploaded to Amazon S3 as a .zip file
const directoryAsset = new Asset(this, "SampleZippedDirAsset", {
  path: path.join(__dirname, "sample-asset-directory")
});

// Uploaded to Amazon S3 as-is
const fileAsset = new Asset(this, 'SampleSingleFileAsset', {
  path: path.join(__dirname, 'file-asset.txt')
});
```

```
const { Asset } = require('aws-cdk-lib/aws-s3-assets');

// Archived and uploaded to Amazon S3 as a .zip file
const directoryAsset = new Asset(this, "SampleZippedDirAsset", {
  path: path.join(__dirname, "sample-asset-directory")
});

// Uploaded to Amazon S3 as-is
const fileAsset = new Asset(this, 'SampleSingleFileAsset', {
  path: path.join(__dirname, 'file-asset.txt')
});
```

```
import os.path
dirname = os.path.dirname(__file__)

from aws_cdk.aws_s3_assets import Asset

# Archived and uploaded to Amazon S3 as a .zip file
directory_asset = Asset(self, "SampleZippedDirAsset",
  path=os.path.join(dirname, "sample-asset-directory")
)

# Uploaded to Amazon S3 as-is
file_asset = Asset(self, 'SampleSingleFileAsset',
  path=os.path.join(dirname, 'file-asset.txt')
)
```

```
import java.io.File;

import software.amazon.awscdk.services.s3.assets.Asset;

// Directory where app was started
File startDir = new File(System.getProperty("user.dir"));

// Archived and uploaded to Amazon S3 as a .zip file
Asset directoryAsset = Asset.Builder.create(this, "SampleZippedDirAsset")
                .path(new File(startDir, "sample-asset-directory").toString()).build();

// Uploaded to Amazon S3 as-is
Asset fileAsset = Asset.Builder.create(this, "SampleSingleFileAsset")
                .path(new File(startDir, "file-asset.txt").toString()).build();
```

```
using System.IO;
using Amazon.CDK.AWS.S3.Assets;

// Archived and uploaded to Amazon S3 as a .zip file
var directoryAsset = new Asset(this, "SampleZippedDirAsset", new AssetProps
{
    Path = Path.Combine(Directory.GetCurrentDirectory(), "sample-asset-directory")
});

// Uploaded to Amazon S3 as-is
var fileAsset = new Asset(this, "SampleSingleFileAsset", new AssetProps
{
    Path = Path.Combine(Directory.GetCurrentDirectory(), "file-asset.txt")
});
```

```
dirName, err := os.Getwd()
if err != nil {
  panic(err)
}

awss3assets.NewAsset(stack, jsii.String("SampleZippedDirAsset"), awss3assets.AssetProps{
  Path: jsii.String(path.Join(dirName, "sample-asset-directory")),
})

awss3assets.NewAsset(stack, jsii.String("SampleSingleFileAsset"), awss3assets.AssetProps{
  Path: jsii.String(path.Join(dirName, "file-asset.txt")),
})
```

Nella maggior parte dei casi, non è necessario utilizzare direttamente il APIs nel `aws-s3-assets` modulo. I moduli che supportano le risorse, ad esempio`aws-lambda`, dispongono di metodi pratici che consentono di utilizzare le risorse. Per le funzioni Lambda, il metodo [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Code.html#static-fromwbrassetpath-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Code.html#static-fromwbrassetpath-options)statico consente di specificare una directory o un file.zip nel file system locale.

### Esempio di funzione Lambda
<a name="assets-types-s3-lambda"></a>

Un caso d'uso comune è la creazione di funzioni Lambda con il codice del gestore come risorsa Amazon S3.

L'esempio seguente utilizza una risorsa Amazon S3 per definire un gestore Python nella directory locale. `handler` Crea anche una funzione Lambda con la risorsa della directory locale come proprietà. `code` Di seguito è riportato il codice Python per il gestore.

```
def lambda_handler(event, context):
  message = 'Hello World!'
  return {
    'message': message
  }
```

Il codice per l'app AWS CDK principale dovrebbe essere simile al seguente.

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import { Constructs } from 'constructs';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as path from 'path';

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

    new lambda.Function(this, 'myLambdaFunction', {
      code: lambda.Code.fromAsset(path.join(__dirname, 'handler')),
      runtime: lambda.Runtime.PYTHON_3_6,
      handler: 'index.lambda_handler'
    });
  }
}
```

```
const cdk = require('aws-cdk-lib');
const lambda = require('aws-cdk-lib/aws-lambda');
const path = require('path');

class HelloAssetStack extends cdk.Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    new lambda.Function(this, 'myLambdaFunction', {
      code: lambda.Code.fromAsset(path.join(__dirname, 'handler')),
      runtime: lambda.Runtime.PYTHON_3_6,
      handler: 'index.lambda_handler'
    });
  }
}

module.exports = { HelloAssetStack }
```

```
from aws_cdk import Stack
from constructs import Construct
from aws_cdk import aws_lambda as lambda_

import os.path
dirname = os.path.dirname(__file__)

class HelloAssetStack(Stack):
    def __init__(self, scope: Construct, id: str, **kwargs):
        super().__init__(scope, id, **kwargs)

        lambda_.Function(self, 'myLambdaFunction',
            code=lambda_.Code.from_asset(os.path.join(dirname, 'handler')),
            runtime=lambda_.Runtime.PYTHON_3_6,
            handler="index.lambda_handler")
```

```
import java.io.File;

import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.lambda.Runtime;

public class HelloAssetStack extends Stack {

    public HelloAssetStack(final App scope, final String id) {
        this(scope, id, null);
    }

    public HelloAssetStack(final App scope, final String id, final StackProps props) {
        super(scope, id, props);

        File startDir = new File(System.getProperty("user.dir"));

        Function.Builder.create(this, "myLambdaFunction")
                .code(Code.fromAsset(new File(startDir, "handler").toString()))
                .runtime(Runtime.PYTHON_3_6)
                .handler("index.lambda_handler").build();
    }
}
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.Lambda;
using System.IO;

public class HelloAssetStack : Stack
{
    public HelloAssetStack(Construct scope, string id, StackProps props) : base(scope, id, props)
    {
        new Function(this, "myLambdaFunction", new FunctionProps
        {
            Code = Code.FromAsset(Path.Combine(Directory.GetCurrentDirectory(), "handler")),
            Runtime = Runtime.PYTHON_3_6,
            Handler = "index.lambda_handler"
        });
    }
}
```

```
import (
  "os"
  "path"

  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/aws-cdk-go/awscdk/v2/awslambda"
  "github.com/aws/aws-cdk-go/awscdk/v2/awss3assets"
  "github.com/aws/constructs-go/constructs/v10"
  "github.com/aws/jsii-runtime-go"
)

func HelloAssetStack(scope constructs.Construct, id string, props *HelloAssetStackProps) awscdk.Stack {
  var sprops awscdk.StackProps
  if props != nil {
    sprops = props.StackProps
  }
  stack := awscdk.NewStack(scope, id, sprops)

  dirName, err := os.Getwd()
  if err != nil {
    panic(err)
  }

  awslambda.NewFunction(stack, jsii.String("myLambdaFunction"), awslambda.FunctionProps{
    Code: awslambda.AssetCode_FromAsset(jsii.String(path.Join(dirName, "handler")), awss3assets.AssetOptions{}),
    Runtime: awslambda.Runtime_PYTHON_3_6(),
    Handler: jsii.String("index.lambda_handler"),
  })

  return stack
}
```

Il `Function` metodo utilizza le risorse per raggruppare il contenuto della directory e utilizzarlo per il codice della funzione.

**Suggerimento**  
`.jar`I file Java sono file ZIP con un'estensione diversa. Questi vengono caricati così come sono su Amazon S3, ma quando vengono distribuiti come funzione Lambda, i file che contengono vengono estratti, cosa che potresti non volere. Per evitare ciò, posiziona il `.jar` file in una directory e specifica quella directory come risorsa.

### Esempio di attributi Deploy-time
<a name="assets-types-s3-deploy"></a>

I tipi di asset Amazon S3 espongono anche [attributi di implementazione a cui](resources.md#resources-attributes) è possibile fare riferimento nelle librerie e nelle app CDK. AWS Il `cdk synth` comando AWS CDK CLI visualizza le proprietà AWS CloudFormation degli asset come parametri.

L'esempio seguente utilizza gli attributi deploy-time per passare la posizione di una risorsa di immagine a una funzione Lambda come variabili di ambiente. (Il tipo di file non ha importanza; l'immagine PNG utilizzata qui è solo un esempio.)

**Example**  

```
import { Asset } from 'aws-cdk-lib/aws-s3-assets';
import * as path from 'path';

const imageAsset = new Asset(this, "SampleAsset", {
  path: path.join(__dirname, "images/my-image.png")
});

new lambda.Function(this, "myLambdaFunction", {
  code: lambda.Code.asset(path.join(__dirname, "handler")),
  runtime: lambda.Runtime.PYTHON_3_6,
  handler: "index.lambda_handler",
  environment: {
    'S3_BUCKET_NAME': imageAsset.s3BucketName,
    'S3_OBJECT_KEY': imageAsset.s3ObjectKey,
    'S3_OBJECT_URL': imageAsset.s3ObjectUrl
  }
});
```

```
const { Asset } = require('aws-cdk-lib/aws-s3-assets');
const path = require('path');

const imageAsset = new Asset(this, "SampleAsset", {
  path: path.join(__dirname, "images/my-image.png")
});

new lambda.Function(this, "myLambdaFunction", {
  code: lambda.Code.asset(path.join(__dirname, "handler")),
  runtime: lambda.Runtime.PYTHON_3_6,
  handler: "index.lambda_handler",
  environment: {
    'S3_BUCKET_NAME': imageAsset.s3BucketName,
    'S3_OBJECT_KEY': imageAsset.s3ObjectKey,
    'S3_OBJECT_URL': imageAsset.s3ObjectUrl
  }
});
```

```
import os.path

import aws_cdk.aws_lambda as lambda_
from aws_cdk.aws_s3_assets import Asset

dirname = os.path.dirname(__file__)

image_asset = Asset(self, "SampleAsset",
    path=os.path.join(dirname, "images/my-image.png"))

lambda_.Function(self, "myLambdaFunction",
    code=lambda_.Code.asset(os.path.join(dirname, "handler")),
    runtime=lambda_.Runtime.PYTHON_3_6,
    handler="index.lambda_handler",
    environment=dict(
        S3_BUCKET_NAME=image_asset.s3_bucket_name,
        S3_OBJECT_KEY=image_asset.s3_object_key,
        S3_OBJECT_URL=image_asset.s3_object_url))
```

```
import java.io.File;

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.s3.assets.Asset;

public class FunctionStack extends Stack {
    public FunctionStack(final App scope, final String id, final StackProps props) {
        super(scope, id, props);

        File startDir = new File(System.getProperty("user.dir"));

        Asset imageAsset = Asset.Builder.create(this, "SampleAsset")
                .path(new File(startDir, "images/my-image.png").toString()).build())

        Function.Builder.create(this, "myLambdaFunction")
                .code(Code.fromAsset(new File(startDir, "handler").toString()))
                .runtime(Runtime.PYTHON_3_6)
                .handler("index.lambda_handler")
                .environment(java.util.Map.of(    // Java 9 or later
                    "S3_BUCKET_NAME", imageAsset.getS3BucketName(),
                    "S3_OBJECT_KEY", imageAsset.getS3ObjectKey(),
                    "S3_OBJECT_URL", imageAsset.getS3ObjectUrl()))
                .build();
    }
}
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.Lambda;
using Amazon.CDK.AWS.S3.Assets;
using System.IO;
using System.Collections.Generic;

var imageAsset = new Asset(this, "SampleAsset", new AssetProps
{
    Path = Path.Combine(Directory.GetCurrentDirectory(), @"images\my-image.png")
});

new Function(this, "myLambdaFunction", new FunctionProps
{
    Code = Code.FromAsset(Path.Combine(Directory.GetCurrentDirectory(), "handler")),
    Runtime = Runtime.PYTHON_3_6,
    Handler = "index.lambda_handler",
    Environment = new Dictionarystring, string
    {
        ["S3_BUCKET_NAME"] = imageAsset.S3BucketName,
        ["S3_OBJECT_KEY"] = imageAsset.S3ObjectKey,
        ["S3_OBJECT_URL"] = imageAsset.S3ObjectUrl
    }
});
```

```
import (
  "os"
  "path"

  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/aws-cdk-go/awscdk/v2/awslambda"
  "github.com/aws/aws-cdk-go/awscdk/v2/awss3assets"
)

dirName, err := os.Getwd()
if err != nil {
  panic(err)
}

imageAsset := awss3assets.NewAsset(stack, jsii.String("SampleAsset"), awss3assets.AssetProps{
  Path: jsii.String(path.Join(dirName, "images/my-image.png")),
})

awslambda.NewFunction(stack, jsii.String("myLambdaFunction"), awslambda.FunctionProps{
  Code: awslambda.AssetCode_FromAsset(jsii.String(path.Join(dirName, "handler"))),
  Runtime: awslambda.Runtime_PYTHON_3_6(),
  Handler: jsii.String("index.lambda_handler"),
  Environment: map[string]*string{
    "S3_BUCKET_NAME": imageAsset.S3BucketName(),
    "S3_OBJECT_KEY": imageAsset.S3ObjectKey(),
    "S3_URL": imageAsset.S3ObjectUrl(),
  },
})
```

### Autorizzazioni
<a name="assets-types-s3-permissions"></a>

Se utilizzi gli asset Amazon S3 direttamente tramite il [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3_assets-readme.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3_assets-readme.html)modulo, i ruoli IAM, gli utenti o i gruppi e hai bisogno di leggere gli asset in fase di esecuzione, concedi a tali asset le autorizzazioni IAM tramite il metodo. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3_assets.Asset.html#grantwbrreadgrantee](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3_assets.Asset.html#grantwbrreadgrantee)

L'esempio seguente concede a un gruppo IAM le autorizzazioni di lettura su un asset di file.

**Example**  

```
import { Asset } from 'aws-cdk-lib/aws-s3-assets';
import * as path from 'path';

const asset = new Asset(this, 'MyFile', {
  path: path.join(__dirname, 'my-image.png')
});

const group = new iam.Group(this, 'MyUserGroup');
asset.grantRead(group);
```

```
const { Asset } = require('aws-cdk-lib/aws-s3-assets');
const path = require('path');

const asset = new Asset(this, 'MyFile', {
  path: path.join(__dirname, 'my-image.png')
});

const group = new iam.Group(this, 'MyUserGroup');
asset.grantRead(group);
```

```
from aws_cdk.aws_s3_assets import Asset
import aws_cdk.aws_iam as iam

import os.path
dirname = os.path.dirname(__file__)

        asset = Asset(self, "MyFile",
            path=os.path.join(dirname, "my-image.png"))

        group = iam.Group(self, "MyUserGroup")
        asset.grant_read(group)
```

```
import java.io.File;

import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.iam.Group;
import software.amazon.awscdk.services.s3.assets.Asset;

public class GrantStack extends Stack {
    public GrantStack(final App scope, final String id, final StackProps props) {
        super(scope, id, props);

        File startDir = new File(System.getProperty("user.dir"));

        Asset asset = Asset.Builder.create(this, "SampleAsset")
                .path(new File(startDir, "images/my-image.png").toString()).build();

        Group group = new Group(this, "MyUserGroup");
        asset.grantRead(group);   }
}
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.IAM;
using Amazon.CDK.AWS.S3.Assets;
using System.IO;

var asset = new Asset(this, "MyFile", new AssetProps {
    Path = Path.Combine(Path.Combine(Directory.GetCurrentDirectory(), @"images\my-image.png"))
});

var group = new Group(this, "MyUserGroup");
asset.GrantRead(group);
```

```
import (
  "os"
  "path"

  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/aws-cdk-go/awscdk/v2/awsiam"
  "github.com/aws/aws-cdk-go/awscdk/v2/awss3assets"
)

dirName, err := os.Getwd()
if err != nil {
  panic(err)
}

asset := awss3assets.NewAsset(stack, jsii.String("MyFile"), awss3assets.AssetProps{
  Path: jsii.String(path.Join(dirName, "my-image.png")),
})

group := awsiam.NewGroup(stack, jsii.String("MyUserGroup"), awsiam.GroupProps{})

asset.GrantRead(group)
```

## Risorse di immagini Docker
<a name="assets-types-docker"></a>

Il AWS CDK supporta il raggruppamento di immagini Docker locali come risorse tramite il modulo. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr_assets-readme.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr_assets-readme.html)

L'esempio seguente definisce un'immagine Docker creata localmente e inviata ad Amazon ECR. Le immagini vengono create da una directory di contesto Docker locale (con un Dockerfile) e caricate su Amazon ECR dalla AWS CLI CDK o dalla pipeline CI/CD dell'app. Le immagini possono essere referenziate in modo naturale nella tua app CDK. AWS 

**Example**  

```
import { DockerImageAsset } from 'aws-cdk-lib/aws-ecr-assets';

const asset = new DockerImageAsset(this, 'MyBuildImage', {
  directory: path.join(__dirname, 'my-image')
});
```

```
const { DockerImageAsset } = require('aws-cdk-lib/aws-ecr-assets');

const asset = new DockerImageAsset(this, 'MyBuildImage', {
  directory: path.join(__dirname, 'my-image')
});
```

```
from aws_cdk.aws_ecr_assets import DockerImageAsset

import os.path
dirname = os.path.dirname(__file__)

asset = DockerImageAsset(self, 'MyBuildImage',
    directory=os.path.join(dirname, 'my-image'))
```

```
import software.amazon.awscdk.services.ecr.assets.DockerImageAsset;

File startDir = new File(System.getProperty("user.dir"));

DockerImageAsset asset = DockerImageAsset.Builder.create(this, "MyBuildImage")
            .directory(new File(startDir, "my-image").toString()).build();
```

```
using System.IO;
using Amazon.CDK.AWS.ECR.Assets;

var asset = new DockerImageAsset(this, "MyBuildImage", new DockerImageAssetProps
{
    Directory = Path.Combine(Directory.GetCurrentDirectory(), "my-image")
});
```

```
import (
  "os"
  "path"

  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/aws-cdk-go/awscdk/v2/awsecrassets"
)

dirName, err := os.Getwd()
if err != nil {
  panic(err)
}

asset := awsecrassets.NewDockerImageAsset(stack, jsii.String("MyBuildImage"), awsecrassets.DockerImageAssetProps{
  Directory: jsii.String(path.Join(dirName, "my-image")),
})
```

La `my-image` directory deve includere un Dockerfile. La CLI AWS CDK crea un'immagine Docker `my-image` da, la invia a un repository Amazon ECR e specifica il nome del repository come parametro dello stack. AWS CloudFormation [I tipi di asset di immagini Docker espongono attributi di implementazione a cui è possibile fare riferimento nelle librerie e nelle app CDK.](resources.md#resources-attributes) AWS Il `cdk synth` comando AWS CDK CLI visualizza le proprietà AWS CloudFormation degli asset come parametri.

### Esempio di definizione di attività in Amazon ECS
<a name="assets-types-docker-ecs"></a>

Un caso d'uso comune è creare un Amazon ECS [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs.TaskDefinition.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs.TaskDefinition.html)per eseguire contenitori Docker. L'esempio seguente specifica la posizione di una risorsa di immagini Docker che il AWS CDK crea localmente e invia ad Amazon ECR.

**Example**  

```
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as ecr_assets from 'aws-cdk-lib/aws-ecr-assets';
import * as path from 'path';

const taskDefinition = new ecs.FargateTaskDefinition(this, "TaskDef", {
  memoryLimitMiB: 1024,
  cpu: 512
});

const asset = new ecr_assets.DockerImageAsset(this, 'MyBuildImage', {
  directory: path.join(__dirname, 'my-image')
});

taskDefinition.addContainer("my-other-container", {
  image: ecs.ContainerImage.fromDockerImageAsset(asset)
});
```

```
const ecs = require('aws-cdk-lib/aws-ecs');
const ecr_assets = require('aws-cdk-lib/aws-ecr-assets');
const path = require('path');

const taskDefinition = new ecs.FargateTaskDefinition(this, "TaskDef", {
  memoryLimitMiB: 1024,
  cpu: 512
});

const asset = new ecr_assets.DockerImageAsset(this, 'MyBuildImage', {
  directory: path.join(__dirname, 'my-image')
});

taskDefinition.addContainer("my-other-container", {
  image: ecs.ContainerImage.fromDockerImageAsset(asset)
});
```

```
import aws_cdk.aws_ecs as ecs
import aws_cdk.aws_ecr_assets as ecr_assets

import os.path
dirname = os.path.dirname(__file__)

task_definition = ecs.FargateTaskDefinition(self, "TaskDef",
    memory_limit_mib=1024,
    cpu=512)

asset = ecr_assets.DockerImageAsset(self, 'MyBuildImage',
    directory=os.path.join(dirname, 'my-image'))

task_definition.add_container("my-other-container",
    image=ecs.ContainerImage.from_docker_image_asset(asset))
```

```
import java.io.File;

import software.amazon.awscdk.services.ecs.FargateTaskDefinition;
import software.amazon.awscdk.services.ecs.ContainerDefinitionOptions;
import software.amazon.awscdk.services.ecs.ContainerImage;

import software.amazon.awscdk.services.ecr.assets.DockerImageAsset;

File startDir = new File(System.getProperty("user.dir"));

FargateTaskDefinition taskDefinition = FargateTaskDefinition.Builder.create(
        this, "TaskDef").memoryLimitMiB(1024).cpu(512).build();

DockerImageAsset asset = DockerImageAsset.Builder.create(this, "MyBuildImage")
            .directory(new File(startDir, "my-image").toString()).build();

taskDefinition.addContainer("my-other-container",
        ContainerDefinitionOptions.builder()
            .image(ContainerImage.fromDockerImageAsset(asset))
            .build();
)
```

```
using System.IO;
using Amazon.CDK.AWS.ECS;
using Amazon.CDK.AWS.Ecr.Assets;

var taskDefinition = new FargateTaskDefinition(this, "TaskDef", new FargateTaskDefinitionProps
{
    MemoryLimitMiB = 1024,
    Cpu = 512
});

var asset = new DockerImageAsset(this, "MyBuildImage", new DockerImageAssetProps
{
    Directory = Path.Combine(Directory.GetCurrentDirectory(), "my-image")
});

taskDefinition.AddContainer("my-other-container", new ContainerDefinitionOptions
{
    Image = ContainerImage.FromDockerImageAsset(asset)
});
```

```
import (
  "os"
  "path"

  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/aws-cdk-go/awscdk/v2/awsecrassets"
  "github.com/aws/aws-cdk-go/awscdk/v2/awsecs"
)

dirName, err := os.Getwd()
if err != nil {
  panic(err)
}

taskDefinition := awsecs.NewTaskDefinition(stack, jsii.String("TaskDef"), awsecs.TaskDefinitionProps{
  MemoryMiB: jsii.String("1024"),
  Cpu: jsii.String("512"),
})

asset := awsecrassets.NewDockerImageAsset(stack, jsii.String("MyBuildImage"), awsecrassets.DockerImageAssetProps{
  Directory: jsii.String(path.Join(dirName, "my-image")),
})

taskDefinition.AddContainer(jsii.String("MyOtherContainer"), awsecs.ContainerDefinitionOptions{
  Image: awsecs.ContainerImage_FromDockerImageAsset(asset),
})
```

### Esempio di attributi Deploy-time
<a name="assets-types-docker-deploy"></a>

L'esempio seguente mostra come utilizzare gli attributi di deploy-time `repository` e `imageUri` creare una definizione di attività Amazon ECS con il tipo di avvio Fargate AWS . Tieni presente che la ricerca del repository Amazon ECR richiede il tag dell'immagine, non il relativo URI, quindi la separiamo dalla fine dell'URI dell'asset.

**Example**  

```
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as path from 'path';
import { DockerImageAsset } from 'aws-cdk-lib/aws-ecr-assets';

const asset = new DockerImageAsset(this, 'my-image', {
  directory: path.join(__dirname, "..", "demo-image")
});

const taskDefinition = new ecs.FargateTaskDefinition(this, "TaskDef", {
  memoryLimitMiB: 1024,
  cpu: 512
});

taskDefinition.addContainer("my-other-container", {
  image: ecs.ContainerImage.fromEcrRepository(asset.repository, asset.imageUri.split(":").pop())
});
```

```
const ecs = require('aws-cdk-lib/aws-ecs');
const path = require('path');
const { DockerImageAsset } = require('aws-cdk-lib/aws-ecr-assets');

const asset = new DockerImageAsset(this, 'my-image', {
  directory: path.join(__dirname, "..", "demo-image")
});

const taskDefinition = new ecs.FargateTaskDefinition(this, "TaskDef", {
  memoryLimitMiB: 1024,
  cpu: 512
});

taskDefinition.addContainer("my-other-container", {
  image: ecs.ContainerImage.fromEcrRepository(asset.repository, asset.imageUri.split(":").pop())
});
```

```
import aws_cdk.aws_ecs as ecs
from aws_cdk.aws_ecr_assets import DockerImageAsset

import os.path
dirname = os.path.dirname(__file__)

asset = DockerImageAsset(self, 'my-image',
    directory=os.path.join(dirname, "..", "demo-image"))

task_definition = ecs.FargateTaskDefinition(self, "TaskDef",
    memory_limit_mib=1024, cpu=512)

task_definition.add_container("my-other-container",
    image=ecs.ContainerImage.from_ecr_repository(
        asset.repository, asset.image_uri.rpartition(":")[-1]))
```

```
import java.io.File;

import software.amazon.awscdk.services.ecr.assets.DockerImageAsset;

import software.amazon.awscdk.services.ecs.FargateTaskDefinition;
import software.amazon.awscdk.services.ecs.ContainerDefinitionOptions;
import software.amazon.awscdk.services.ecs.ContainerImage;

File startDir = new File(System.getProperty("user.dir"));

DockerImageAsset asset = DockerImageAsset.Builder.create(this, "my-image")
            .directory(new File(startDir, "demo-image").toString()).build();

FargateTaskDefinition taskDefinition = FargateTaskDefinition.Builder.create(
        this, "TaskDef").memoryLimitMiB(1024).cpu(512).build();

// extract the tag from the asset's image URI for use in ECR repo lookup
String imageUri = asset.getImageUri();
String imageTag = imageUri.substring(imageUri.lastIndexOf(":") + 1);

taskDefinition.addContainer("my-other-container",
        ContainerDefinitionOptions.builder().image(ContainerImage.fromEcrRepository(
                asset.getRepository(), imageTag)).build());
```

```
using System.IO;
using Amazon.CDK.AWS.ECS;
using Amazon.CDK.AWS.ECR.Assets;

var asset = new DockerImageAsset(this, "my-image", new DockerImageAssetProps {
    Directory = Path.Combine(Directory.GetCurrentDirectory(), "demo-image")
});

var taskDefinition = new FargateTaskDefinition(this, "TaskDef", new FargateTaskDefinitionProps
{
    MemoryLimitMiB = 1024,
    Cpu = 512
});

taskDefinition.AddContainer("my-other-container", new ContainerDefinitionOptions
{
    Image = ContainerImage.FromEcrRepository(asset.Repository, asset.ImageUri.Split(":").Last())
});
```

```
import (
  "os"
  "path"

  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/aws-cdk-go/awscdk/v2/awsecrassets"
  "github.com/aws/aws-cdk-go/awscdk/v2/awsecs"
)

dirName, err := os.Getwd()
if err != nil {
  panic(err)
}

asset := awsecrassets.NewDockerImageAsset(stack, jsii.String("MyImage"), awsecrassets.DockerImageAssetProps{
  Directory: jsii.String(path.Join(dirName, "demo-image")),
})

taskDefinition := awsecs.NewFargateTaskDefinition(stack, jsii.String("TaskDef"), awsecs.FargateTaskDefinitionProps{
  MemoryLimitMiB: jsii.Number(1024),
  Cpu: jsii.Number(512),
})

taskDefinition.AddContainer(jsii.String("MyOtherContainer"), awsecs.ContainerDefinitionOptions{
  Image: awsecs.ContainerImage_FromEcrRepository(asset.Repository(), asset.ImageTag()),
})
```

### Esempio di compilazione degli argomenti
<a name="assets-types-docker-build"></a>

Puoi fornire argomenti di compilazione personalizzati per la fase di compilazione di Docker tramite l'opzione di proprietà `buildArgs` (Python`build_args`:) quando la CLI AWS CDK crea l'immagine durante la distribuzione.

**Example**  

```
const asset = new DockerImageAsset(this, 'MyBuildImage', {
  directory: path.join(__dirname, 'my-image'),
  buildArgs: {
    HTTP_PROXY: 'http://10.20.30.2:1234'
  }
});
```

```
const asset = new DockerImageAsset(this, 'MyBuildImage', {
  directory: path.join(__dirname, 'my-image'),
  buildArgs: {
    HTTP_PROXY: 'http://10.20.30.2:1234'
  }
});
```

```
asset = DockerImageAsset(self, "MyBuildImage",
    directory=os.path.join(dirname, "my-image"),
    build_args=dict(HTTP_PROXY="http://10.20.30.2:1234"))
```

```
DockerImageAsset asset = DockerImageAsset.Builder.create(this, "my-image"),
            .directory(new File(startDir, "my-image").toString())
            .buildArgs(java.util.Map.of(    // Java 9 or later
                "HTTP_PROXY", "http://10.20.30.2:1234"))
            .build();
```

```
var asset = new DockerImageAsset(this, "MyBuildImage", new DockerImageAssetProps {
    Directory = Path.Combine(Directory.GetCurrentDirectory(), "my-image"),
    BuildArgs = new Dictionarystring, string
    {
        ["HTTP_PROXY"] = "http://10.20.30.2:1234"
    }
});
```

```
dirName, err := os.Getwd()
if err != nil {
  panic(err)
}

asset := awsecrassets.NewDockerImageAsset(stack, jsii.String("MyBuildImage"), awsecrassets.DockerImageAssetProps{
  Directory: jsii.String(path.Join(dirName, "my-image")),
  BuildArgs: map[string]*string{
    "HTTP_PROXY": jsii.String("http://10.20.30.2:1234"),
  },
})
```

### Autorizzazioni
<a name="assets-types-docker-permissions"></a>

Se utilizzi un modulo che supporta le risorse di immagini Docker, ad esempio [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs-readme.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs-readme.html), il AWS CDK gestisce le autorizzazioni per te quando utilizzi le risorse direttamente o tramite ([https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs.ContainerImage.html#static-fromwbrecrwbrrepositoryrepository-tag](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs.ContainerImage.html#static-fromwbrecrwbrrepositoryrepository-tag)Python:). `from_ecr_repository` Se utilizzi direttamente le risorse di immagini Docker, assicurati che l'utente principale disponga delle autorizzazioni per estrarre l'immagine.

Nella maggior parte dei casi, dovresti usare [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr.Repository.html#grantwbrpullgrantee](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr.Repository.html#grantwbrpullgrantee)method (Python:`grant_pull`). Ciò modifica la politica IAM del principale per consentirgli di estrarre immagini da questo repository. Se il responsabile che sta recuperando l'immagine non si trova nello stesso account, o se si tratta di un AWS servizio che non assume alcun ruolo nel tuo account (ad esempio AWS CodeBuild), devi concedere i permessi di pull sulla politica delle risorse e non sulla politica del principale. Usa il [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr.Repository.html#addwbrtowbrresourcewbrpolicystatement](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr.Repository.html#addwbrtowbrresourcewbrpolicystatement)metodo (Python:`add_to_resource_policy`) per concedere le autorizzazioni principali appropriate.

## AWS CloudFormation metadati delle risorse
<a name="assets-cfn"></a>

**Nota**  
Questa sezione è rilevante solo per gli autori dei costrutti. In determinate situazioni, gli strumenti devono sapere che una determinata risorsa CFN utilizza una risorsa locale. Ad esempio, puoi utilizzare la CLI AWS SAM per richiamare le funzioni Lambda localmente per scopi di debug. [Vedi Integrazione SAM per i dettagli.AWS](tools.md#sam)

Per abilitare tali casi d'uso, strumenti esterni consultano una serie di voci di metadati sulle AWS CloudFormation risorse:
+  `aws:asset:path`— Indica il percorso locale della risorsa.
+  `aws:asset:property`— Il nome della proprietà della risorsa in cui viene utilizzata la risorsa.

Utilizzando queste due voci di metadati, gli strumenti possono identificare che le risorse vengono utilizzate da una determinata risorsa e consentire esperienze locali avanzate.

Per aggiungere queste voci di metadati a una risorsa, utilizzate il metodo `asset.addResourceMetadata` (Python`add_resource_metadata`:).

# Autorizzazioni e CDK AWS
<a name="permissions"></a>

La AWS Construct Library utilizza alcuni idiomi comuni e ampiamente implementati per gestire l'accesso e le autorizzazioni. Il modulo IAM fornisce gli strumenti necessari per utilizzare questi idiomi.

 AWS CDK utilizza AWS CloudFormation per implementare le modifiche. Ogni implementazione coinvolge un attore (uno sviluppatore o un sistema automatizzato) che avvia una AWS CloudFormation distribuzione. Nel corso di questa operazione, l'attore assumerà una o più identità IAM (utente o ruoli) e, facoltativamente, assegnerà un ruolo a. AWS CloudFormation

Se utilizzi AWS IAM Identity Center per l'autenticazione come utente, il provider Single Sign-on fornisce credenziali di sessione di breve durata che ti autorizzano a svolgere il ruolo IAM predefinito. *Per scoprire come il AWS CDK ottiene le AWS credenziali dall'autenticazione IAM Identity Center, consulta Understand IAM Identity Center authentication nella and Tools [Reference Guide](https://docs.aws.amazon.com/sdkref/latest/guide/understanding-sso.html). AWS SDKs *

## Principali
<a name="permissions-principals"></a>

Un principale IAM è un' AWS entità autenticata che rappresenta un utente, un servizio o un'applicazione che può effettuare chiamate. AWS APIs La AWS Construct Library supporta la specificazione dei principali in diversi modi flessibili per consentire loro di accedere alle tue risorse. AWS 

Nei contesti di sicurezza, il termine «principale» si riferisce specificamente a entità autenticate come gli utenti. Oggetti come gruppi e ruoli non *rappresentano* gli utenti (e altre entità autenticate) ma li *identificano* indirettamente allo scopo di concedere le autorizzazioni.

Ad esempio, se crei un gruppo IAM, puoi concedere al gruppo (e quindi ai suoi membri) l'accesso in scrittura a una tabella Amazon RDS. Tuttavia, il gruppo stesso non è un principale perché non rappresenta una singola entità (inoltre, non è possibile accedere a un gruppo).

Nella libreria IAM del CDK, le classi che identificano direttamente o indirettamente i principali implementano l'[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.IPrincipal.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.IPrincipal.html)interfaccia, che consente di utilizzare questi oggetti in modo intercambiabile nelle politiche di accesso. Tuttavia, non tutti sono principi in senso di sicurezza. Questi oggetti includono:

1. Risorse IAM come [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html), e [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Group.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Group.html) 

1. Responsabili del servizio () `new iam.[ServicePrincipal](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ServicePrincipal.html)('service.amazonaws.com')`

1. Responsabili federati () `new iam.[FederatedPrincipal](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.FederatedPrincipal.html)('cognito-identity.amazonaws.com')`

1. Responsabili del conto () `new iam.[AccountPrincipal](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.AccountPrincipal.html)('0123456789012')`

1. Principi utente canonici () `new iam.[CanonicalUserPrincipal](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.CanonicalUserPrincipal.html)('79a59d[…​]7ef2be')`

1.  AWS Organizzazioni principali () `new iam.[OrganizationPrincipal](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.OrganizationPrincipal.html)('org-id')`

1. Principi ARN arbitrari () `new iam.[ArnPrincipal](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ArnPrincipal.html)(res.arn)`

1. E `iam.[CompositePrincipal](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.CompositePrincipal.html)(principal1, principal2, …​)` fidarsi di più principi

## Concessioni
<a name="permissions-grants"></a>

Molti costrutti rappresentano risorse a cui è possibile accedere, come un bucket Amazon S3 o una tabella Amazon DynamoDB. Per queste, puoi concedere l'accesso a un'altra entità. **Esistono due modi per farlo, a seconda del particolare costrutto: utilizzando la classe Grants corrispondente (ad esempio, `BucketGrants` per i bucket Amazon S3) o utilizzando metodi nel costrutto stesso, i cui nomi iniziano con grant.** I primi sono preferiti perché possono essere utilizzati per concedere l'accesso alle risorse L1 e L2 nello stesso modo. Per creare un'istanza di una classe Grants, usa il suo metodo factory:

**Example**  

```
BucketGrants.fromBucket(bucket); // bucket can be either a Bucket (L2) or a CfnBucket (L1)
```

```
BucketGrants.fromBucket(bucket); // bucket can be either a Bucket (L2) or a CfnBucket (L1)
```

```
BucketGrants.from_bucket(bucket) # bucket can be either a Bucket (L2) or a CfnBucket (L1)
```

```
BucketGrants.fromBucket(bucket); // bucket can be either a Bucket (L2) or a CfnBucket (L1)
```

```
BucketGrants.FromBucket(bucket); // bucket can be either a Bucket (L2) or a CfnBucket (L1)
```

Le classi Grants forniscono metodi per concedere autorizzazioni specifiche per accedere alle rispettive risorse. Ad esempio, `BucketGrants` ha metodi `read` e `readWrite` (Python:`read`,`read_write`) per abilitare la lettura e read/write l'accesso, rispettivamente, da un'entità al bucket. L'entità non deve sapere esattamente quali autorizzazioni IAM di Amazon S3 sono necessarie per eseguire queste operazioni.

Il primo argomento dei metodi in una classe Grants (o i metodi **grant** nelle risorse stesse) è sempre di tipo. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.IGrantable.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.IGrantable.html) Questa interfaccia rappresenta le entità a cui possono essere concesse le autorizzazioni. Cioè, rappresenta risorse con ruoli, come gli oggetti IAM [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html), e [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Group.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Group.html).

Le autorizzazioni possono essere concesse anche ad altre entità. Ad esempio, più avanti in questo argomento, mostriamo come concedere a un CodeBuild progetto l'accesso a un bucket Amazon S3. In genere, il ruolo associato viene ottenuto tramite una `role` proprietà sull'entità a cui viene concesso l'accesso.

Anche le risorse che utilizzano ruoli di esecuzione, ad esempio [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html), implementano`IGrantable`, quindi è possibile concedere loro l'accesso diretto anziché concedere l'accesso al loro ruolo. Ad esempio, se `bucket` è un bucket Amazon S3 ed è `function` una funzione Lambda, il codice seguente concede alla funzione l'accesso in lettura al bucket.

Per comodità, i costrutti L2 offrono anche una `grants` proprietà che restituisce un'istanza della classe Grants corrispondente.

**Example**  

```
bucket.grants.read(function);
```

```
bucket.grants.read(function);
```

```
bucket.grants.read(function)
```

```
bucket.getGrants().read(function);
```

```
bucket.Grants.Read(function);
```

A volte è necessario applicare le autorizzazioni mentre lo stack viene distribuito. Uno di questi casi si verifica quando si concede a una risorsa AWS CloudFormation personalizzata l'accesso a un'altra risorsa. La risorsa personalizzata verrà richiamata durante la distribuzione, quindi deve disporre delle autorizzazioni specificate al momento della distribuzione.

Un altro caso si verifica quando un servizio verifica che al ruolo assegnato siano applicate le politiche corrette. (Alcuni AWS servizi eseguono questa operazione per assicurarsi che tu non abbia dimenticato di impostare le politiche.) In questi casi, la distribuzione potrebbe non riuscire se le autorizzazioni vengono applicate troppo tardi.

Per forzare l'applicazione delle autorizzazioni della concessione prima che venga creata un'altra risorsa, puoi aggiungere una dipendenza dalla concessione stessa, come mostrato qui. Sebbene il valore restituito dai metodi di concessione venga comunemente scartato, ogni metodo di concessione restituisce in effetti un oggetto. `iam.Grant`

**Example**  

```
const grant = bucket.grants.read(lambda);
const custom = new CustomResource(...);
custom.node.addDependency(grant);
```

```
const grant = bucket.grants.read(lambda);
const custom = new CustomResource(...);
custom.node.addDependency(grant);
```

```
grant = bucket.grants.read(function)
custom = CustomResource(...)
custom.node.add_dependency(grant)
```

```
Grant grant = bucket.getGrants().read(function);
CustomResource custom = new CustomResource(...);
custom.node.addDependency(grant);
```

```
var grant = bucket.Grants.Read(function);
var custom = new CustomResource(...);
custom.node.AddDependency(grant);
```

## Roles
<a name="permissions-roles"></a>

Il pacchetto IAM contiene un [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html)costrutto che rappresenta i ruoli IAM. Il codice seguente crea un nuovo ruolo, affidandosi al EC2 servizio Amazon.

**Example**  

```
import * as iam from 'aws-cdk-lib/aws-iam';

const role = new iam.Role(this, 'Role', {
  assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),   // required
});
```

```
const iam = require('aws-cdk-lib/aws-iam');

const role = new iam.Role(this, 'Role', {
  assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com')   // required
});
```

```
import aws_cdk.aws_iam as iam

role = iam.Role(self, "Role",
          assumed_by=iam.ServicePrincipal("ec2.amazonaws.com")) # required
```

```
import software.amazon.awscdk.services.iam.Role;
import software.amazon.awscdk.services.iam.ServicePrincipal;

Role role = Role.Builder.create(this, "Role")
        .assumedBy(new ServicePrincipal("ec2.amazonaws.com")).build();
```

```
using Amazon.CDK.AWS.IAM;

var role = new Role(this, "Role", new RoleProps
{
    AssumedBy = new ServicePrincipal("ec2.amazonaws.com"),   // required
});
```

Puoi aggiungere autorizzazioni a un ruolo chiamando il [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#addwbrtowbrpolicystatement](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#addwbrtowbrpolicystatement)metodo del ruolo (Python`add_to_policy`:), passando [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html)un che definisce la regola da aggiungere. L'istruzione viene aggiunta alla politica predefinita del ruolo; se non ne ha, ne viene creata una.

L'esempio seguente aggiunge una dichiarazione di `Deny` policy al ruolo per le azioni `ec2:SomeAction` e `s3:AnotherAction` sulle risorse `bucket` e `otherRole` (Python:`other_role`), a condizione che il servizio autorizzato sia. AWS CodeBuild

**Example**  

```
role.addToPolicy(new iam.PolicyStatement({
  effect: iam.Effect.DENY,
  resources: [bucket.bucketArn, otherRole.roleArn],
  actions: ['ec2:SomeAction', 's3:AnotherAction'],
  conditions: {StringEquals: {
    'ec2:AuthorizedService': 'codebuild.amazonaws.com',
}}}));
```

```
role.addToPolicy(new iam.PolicyStatement({
  effect: iam.Effect.DENY,
  resources: [bucket.bucketArn, otherRole.roleArn],
  actions: ['ec2:SomeAction', 's3:AnotherAction'],
  conditions: {StringEquals: {
    'ec2:AuthorizedService': 'codebuild.amazonaws.com'
}}}));
```

```
role.add_to_policy(iam.PolicyStatement(
    effect=iam.Effect.DENY,
    resources=[bucket.bucket_arn, other_role.role_arn],
    actions=["ec2:SomeAction", "s3:AnotherAction"],
    conditions={"StringEquals": {
        "ec2:AuthorizedService": "codebuild.amazonaws.com"}}
))
```

```
role.addToPolicy(PolicyStatement.Builder.create()
        .effect(Effect.DENY)
        .resources(Arrays.asList(bucket.getBucketArn(), otherRole.getRoleArn()))
        .actions(Arrays.asList("ec2:SomeAction", "s3:AnotherAction"))
        .conditions(java.util.Map.of(    // Map.of requires Java 9 or later
            "StringEquals", java.util.Map.of(
                "ec2:AuthorizedService", "codebuild.amazonaws.com")))
        .build());
```

```
role.AddToPolicy(new PolicyStatement(new PolicyStatementProps
{
    Effect = Effect.DENY,
    Resources = new string[] { bucket.BucketArn, otherRole.RoleArn },
    Actions = new string[] { "ec2:SomeAction", "s3:AnotherAction" },
    Conditions = new Dictionary<string, object>
    {
        ["StringEquals"] = new Dictionary<string, string>
        {
            ["ec2:AuthorizedService"] = "codebuild.amazonaws.com"
        }
    }
}));
```

Nell'esempio precedente, abbiamo creato un nuovo [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html)inline con la chiamata ([https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#addwbrtowbrpolicystatement](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#addwbrtowbrpolicystatement)Python:). `add_to_policy` Puoi anche inserire una dichiarazione politica esistente o una che hai modificato. L'[https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html)oggetto dispone di [numerosi metodi](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html#methods) per aggiungere principi, risorse, condizioni e azioni.

Se utilizzate un costrutto che richiede un ruolo per funzionare correttamente, potete effettuare una delle seguenti operazioni:
+ Assegnate un ruolo esistente quando istanziate l'oggetto di costruzione.
+ Lascia che il costrutto crei un nuovo ruolo per te, affidandoti al responsabile del servizio appropriato. L'esempio seguente utilizza un costrutto di questo tipo: un progetto. CodeBuild 

**Example**  

```
import * as codebuild from 'aws-cdk-lib/aws-codebuild';

// imagine roleOrUndefined is a function that might return a Role object
// under some conditions, and undefined under other conditions
const someRole: iam.IRole | undefined = roleOrUndefined();

const project = new codebuild.Project(this, 'Project', {
  // if someRole is undefined, the Project creates a new default role,
  // trusting the codebuild.amazonaws.com service principal
  role: someRole,
});
```

```
const codebuild = require('aws-cdk-lib/aws-codebuild');

// imagine roleOrUndefined is a function that might return a Role object
// under some conditions, and undefined under other conditions
const someRole = roleOrUndefined();

const project = new codebuild.Project(this, 'Project', {
  // if someRole is undefined, the Project creates a new default role,
  // trusting the codebuild.amazonaws.com service principal
  role: someRole
});
```

```
import aws_cdk.aws_codebuild as codebuild

# imagine role_or_none is a function that might return a Role object
# under some conditions, and None under other conditions
some_role = role_or_none();

project = codebuild.Project(self, "Project",
# if role is None, the Project creates a new default role,
# trusting the codebuild.amazonaws.com service principal
role=some_role)
```

```
import software.amazon.awscdk.services.iam.Role;
import software.amazon.awscdk.services.codebuild.Project;

// imagine roleOrNull is a function that might return a Role object
// under some conditions, and null under other conditions
Role someRole = roleOrNull();

// if someRole is null, the Project creates a new default role,
// trusting the codebuild.amazonaws.com service principal
Project project = Project.Builder.create(this, "Project")
        .role(someRole).build();
```

```
using Amazon.CDK.AWS.CodeBuild;

// imagine roleOrNull is a function that might return a Role object
// under some conditions, and null under other conditions
var someRole = roleOrNull();

// if someRole is null, the Project creates a new default role,
// trusting the codebuild.amazonaws.com service principal
var project = new Project(this, "Project", new ProjectProps
{
    Role = someRole
});
```

Una volta creato l'oggetto, il ruolo (indipendentemente dal ruolo passato o da quello predefinito creato dal costrutto) è disponibile come proprietà. `role` Tuttavia, questa proprietà non è disponibile su risorse esterne. Pertanto, questi costrutti hanno un metodo `addToRolePolicy` (Python`add_to_role_policy`:).

Il metodo non fa nulla se il costrutto è una risorsa esterna e in caso contrario chiama il metodo `addToPolicy` (Python`add_to_policy`:) `role` della proprietà. Questo ti evita la fatica di gestire il caso indefinito in modo esplicito.

L'esempio seguente dimostra:

**Example**  

```
// project is imported into the CDK application
const project = codebuild.Project.fromProjectName(this, 'Project', 'ProjectName');

// project is imported, so project.role is undefined, and this call has no effect
project.addToRolePolicy(new iam.PolicyStatement({
  effect: iam.Effect.ALLOW,   // ... and so on defining the policy
}));
```

```
// project is imported into the CDK application
const project = codebuild.Project.fromProjectName(this, 'Project', 'ProjectName');

// project is imported, so project.role is undefined, and this call has no effect
project.addToRolePolicy(new iam.PolicyStatement({
  effect: iam.Effect.ALLOW   // ... and so on defining the policy
}));
```

```
# project is imported into the CDK application
project = codebuild.Project.from_project_name(self, 'Project', 'ProjectName')

# project is imported, so project.role is undefined, and this call has no effect
project.add_to_role_policy(iam.PolicyStatement(
  effect=iam.Effect.ALLOW,   # ... and so on defining the policy
  )
)
```

```
// project is imported into the CDK application
Project project = Project.fromProjectName(this, "Project", "ProjectName");

// project is imported, so project.getRole() is null, and this call has no effect
project.addToRolePolicy(PolicyStatement.Builder.create()
        .effect(Effect.ALLOW)   // .. and so on defining the policy
        .build();
)
```

```
// project is imported into the CDK application
var project = Project.FromProjectName(this, "Project", "ProjectName");

// project is imported, so project.role is null, and this call has no effect
project.AddToRolePolicy(new PolicyStatement(new PolicyStatementProps
{
    Effect = Effect.ALLOW, // ... and so on defining the policy
}));
```

## Policy delle risorse
<a name="permissions-resource-policies"></a>

Alcune risorse AWS, come i bucket Amazon S3 e i ruoli IAM, hanno anche una politica delle risorse. Questi costrutti hanno un `addToResourcePolicy` metodo (Python`add_to_resource_policy`:), che accetta [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html)a come argomento. Ogni dichiarazione politica aggiunta a una politica delle risorse deve specificare almeno un principio.

Nell'esempio seguente, il [bucket Amazon S3](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html) `bucket` concede un ruolo con l'`s3:SomeAction`autorizzazione a se stesso.

**Example**  

```
bucket.addToResourcePolicy(new iam.PolicyStatement({
  effect: iam.Effect.ALLOW,
  actions: ['s3:SomeAction'],
  resources: [bucket.bucketArn],
  principals: [role]
}));
```

```
bucket.addToResourcePolicy(new iam.PolicyStatement({
  effect: iam.Effect.ALLOW,
  actions: ['s3:SomeAction'],
  resources: [bucket.bucketArn],
  principals: [role]
}));
```

```
bucket.add_to_resource_policy(iam.PolicyStatement(
    effect=iam.Effect.ALLOW,
    actions=["s3:SomeAction"],
    resources=[bucket.bucket_arn],
    principals=role))
```

```
bucket.addToResourcePolicy(PolicyStatement.Builder.create()
        .effect(Effect.ALLOW)
        .actions(Arrays.asList("s3:SomeAction"))
        .resources(Arrays.asList(bucket.getBucketArn()))
        .principals(Arrays.asList(role))
        .build());
```

```
bucket.AddToResourcePolicy(new PolicyStatement(new PolicyStatementProps
{
    Effect = Effect.ALLOW,
    Actions = new string[] { "s3:SomeAction" },
    Resources = new string[] { bucket.BucketArn },
    Principals = new IPrincipal[] { role }
}));
```

## Utilizzo di oggetti IAM esterni
<a name="permissions-existing"></a>

Se hai definito un utente, un principale, un gruppo o un ruolo IAM al di fuori dell'app AWS CDK, puoi utilizzare quell'oggetto IAM nell'app AWS CDK. A tale scopo, create un riferimento ad esso utilizzando il suo ARN o il suo nome. (Usa il nome per utenti, gruppi e ruoli). Il riferimento restituito può quindi essere utilizzato per concedere autorizzazioni o per creare dichiarazioni politiche come spiegato in precedenza.
+ Per gli utenti, chiama [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.User.html#static-fromwbruserwbrarnscope-id-userarn](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.User.html#static-fromwbruserwbrarnscope-id-userarn)o. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.User.html#static-fromwbruserwbrnamescope-id-username](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.User.html#static-fromwbruserwbrnamescope-id-username) `User.fromUserAttributes()`è anche disponibile, ma attualmente offre le stesse funzionalità di`User.fromUserArn()`.
+ Per i principali, crea un'istanza di un oggetto. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ArnPrincipal.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ArnPrincipal.html)
+ Per gruppi, chiama o. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Group.html#static-fromwbrgroupwbrarnscope-id-grouparn](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Group.html#static-fromwbrgroupwbrarnscope-id-grouparn)
+ Per ruoli, chiama [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#static-fromwbrrolewbrarnscope-id-rolearn-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#static-fromwbrrolewbrarnscope-id-rolearn-options)o [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#static-fromwbrrolewbrnamescope-id-rolename](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#static-fromwbrrolewbrnamescope-id-rolename).

Le politiche (incluse le politiche gestite) possono essere utilizzate in modo simile utilizzando i seguenti metodi. È possibile utilizzare riferimenti a questi oggetti ovunque sia richiesta una policy IAM.
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Policy.html#static-fromwbrpolicywbrnamescope-id-policyname](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Policy.html#static-fromwbrpolicywbrnamescope-id-policyname) 
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ManagedPolicy.html#static-fromwbrmanagedwbrpolicywbrarnscope-id-managedpolicyarn](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ManagedPolicy.html#static-fromwbrmanagedwbrpolicywbrarnscope-id-managedpolicyarn) 
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ManagedPolicy.html#static-fromwbrmanagedwbrpolicywbrnamescope-id-managedpolicyname](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ManagedPolicy.html#static-fromwbrmanagedwbrpolicywbrnamescope-id-managedpolicyname) 
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ManagedPolicy.html#static-fromwbrawswbrmanagedwbrpolicywbrnamemanagedpolicyname](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ManagedPolicy.html#static-fromwbrawswbrmanagedwbrpolicywbrnamemanagedpolicyname) 

**Nota**  
Come per tutti i riferimenti a AWS risorse esterne, non è possibile modificare oggetti IAM esterni nell'app CDK.

# I valori di contesto e il CDK AWS
<a name="context"></a>

I valori di contesto sono coppie chiave-valore che possono essere associate a un'app, uno stack o un costrutto. Possono essere forniti all'app da un file (di solito o `cdk.context.json` nella directory del progetto) `cdk.json` o dalla riga di comando.

Il CDK Toolkit utilizza il contesto per memorizzare nella cache i valori recuperati dall' AWS account durante la sintesi. I valori includono le zone di disponibilità nel tuo account o gli ID Amazon Machine Image (AMI) attualmente disponibili per le istanze Amazon EC2. Poiché questi valori sono forniti dal tuo AWS account, possono cambiare tra le esecuzioni dell'applicazione CDK. Ciò li rende una potenziale fonte di cambiamenti involontari. Il comportamento di memorizzazione nella cache di CDK Toolkit «blocca» questi valori per l'app CDK finché non decidi di accettare i nuovi valori.

Immaginate lo scenario seguente senza la memorizzazione nella cache del contesto. Supponiamo che tu abbia specificato «la versione più recente di Amazon Linux» come AMI per le tue istanze Amazon EC2 e che sia stata rilasciata una nuova versione di questa AMI. Quindi, la prossima volta che distribuisci lo stack CDK, le istanze già distribuite utilizzeranno l'AMI obsoleta («sbagliata») e dovranno essere aggiornate. L'aggiornamento comporterebbe la sostituzione di tutte le istanze esistenti con altre nuove, il che sarebbe probabilmente inaspettato e indesiderato.

Invece, il CDK registra i dati disponibili dell'account AMIs nel `cdk.context.json` file del progetto e utilizza il valore memorizzato per future operazioni di sintesi. In questo modo, l'elenco di non AMIs è più una potenziale fonte di cambiamento. Puoi anche essere sicuro che i tuoi stack vengano sempre sintetizzati negli stessi modelli. AWS CloudFormation 

Non tutti i valori di contesto sono valori memorizzati nella cache del tuo ambiente. AWS AWS I [flag di funzionalità CDK sono anche valori](featureflags.md) di contesto. Puoi anche creare valori di contesto personalizzati da utilizzare con le tue app o costrutti.

Le chiavi di contesto sono stringhe. I valori possono essere di qualsiasi tipo supportato da JSON: numeri, stringhe, matrici o oggetti.

**Suggerimento**  
Se i tuoi costrutti creano i propri valori di contesto, incorpora il nome del pacchetto della libreria nelle sue chiavi in modo che non entrino in conflitto con i valori di contesto di altri pacchetti.

Molti valori di contesto sono associati a un particolare AWS ambiente e una determinata app CDK può essere distribuita in più di un ambiente. La chiave per tali valori include l' AWS account e la regione, in modo che i valori di ambienti diversi non siano in conflitto.

La seguente chiave di contesto illustra il formato utilizzato dal AWS CDK, inclusi l'account e la regione.

```
availability-zones:account=123456789012:region=eu-central-1
```

**Importante**  
I valori di contesto memorizzati nella cache sono gestiti dal AWS CDK e dai suoi costrutti, inclusi i costrutti che è possibile scrivere. Non aggiungete o modificate i valori di contesto memorizzati nella cache modificando manualmente i file. Può essere utile, tuttavia, rivedere di `cdk.context.json` tanto in tanto per vedere quali valori vengono memorizzati nella cache. I valori di contesto che non rappresentano i valori memorizzati nella cache devono essere archiviati sotto la `context` chiave di. `cdk.json` In questo modo, non verranno cancellati quando i valori memorizzati nella cache vengono cancellati.

## Fonti di valori contestuali
<a name="context-construct"></a>

I valori di contesto possono essere forniti all'app AWS CDK in sei modi diversi:
+ Automaticamente dall' AWS account corrente.
+ Tramite l'`--context`opzione al `cdk` comando. (Questi valori sono sempre stringhe.)
+ Nel `cdk.context.json` file del progetto.
+ Nella `context` chiave del `cdk.json` file del progetto.
+ Nella `context` chiave del tuo `~/.cdk.json` file.
+ Nella tua app AWS CDK usando il `construct.node.setContext()` metodo.

Il file di progetto `cdk.context.json` è dove il AWS CDK memorizza nella cache i valori di contesto recuperati dal tuo account. AWS Questa pratica evita modifiche impreviste alle distribuzioni quando, ad esempio, viene introdotta una nuova zona di disponibilità. Il AWS CDK non scrive dati contestuali in nessuno degli altri file elencati.

**Importante**  
Perché fanno parte dello stato dell'applicazione `cdk.json` e `cdk.context.json` devono essere sottoposti al controllo del codice sorgente insieme al resto del codice sorgente dell'app. In caso contrario, le implementazioni in altri ambienti (ad esempio, una pipeline CI) potrebbero produrre risultati incoerenti.

I valori di contesto rientrano nell'ambito del costrutto che li ha creati; sono visibili ai costrutti figli, ma non ai genitori o ai fratelli. I valori di contesto impostati da AWS CDK Toolkit (il `cdk` comando) possono essere impostati automaticamente, da un file o dall'opzione. `--context` I valori di contesto di queste fonti sono impostati implicitamente nel costrutto. `App` Pertanto, sono visibili a tutti i costrutti in ogni stack dell'app.

La tua app può leggere un valore di contesto utilizzando il `construct.node.tryGetContext` metodo. Se la voce richiesta non viene trovata nel costrutto corrente o in uno dei suoi genitori, il risultato è`undefined`. (In alternativa, il risultato potrebbe essere l'equivalente della tua lingua, ad esempio `None` in Python.)

## Metodi del contesto
<a name="context-methods"></a>

Il AWS CDK supporta diversi metodi contestuali che consentono alle app AWS CDK di ottenere informazioni contestuali dall'ambiente. AWS Ad esempio, è possibile ottenere un elenco delle zone di disponibilità disponibili in un determinato AWS account e regione, utilizzando il metodo. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#availabilityzones](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#availabilityzones)

Di seguito sono riportati i metodi contestuali:

 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_route53.HostedZone.html#static-fromwbrlookupscope-id-query](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_route53.HostedZone.html#static-fromwbrlookupscope-id-query)   
Ottiene le zone ospitate nel tuo account.

 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#availabilityzones](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#availabilityzones)   
Ottiene le zone di disponibilità supportate.

 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ssm.StringParameter.html#static-valuewbrfromwbrlookupscope-parametername](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ssm.StringParameter.html#static-valuewbrfromwbrlookupscope-parametername)   
Ottiene un valore dall'Amazon EC2 Systems Manager Parameter Store della regione corrente.

 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.Vpc.html#static-fromwbrlookupscope-id-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.Vpc.html#static-fromwbrlookupscope-id-options)   
Acquisisce gli Amazon Virtual Private Cloud esistenti nei tuoi account.

 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.LookupMachineImage.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.LookupMachineImage.html)   
Cerca l'immagine di una macchina da utilizzare con un'istanza NAT in un Amazon Virtual Private Cloud.

Se un valore di contesto richiesto non è disponibile, l'app AWS CDK notifica al CDK Toolkit che le informazioni di contesto sono mancanti. Successivamente, la CLI interroga l' AWS account corrente per le informazioni e memorizza le informazioni di contesto risultanti nel file. `cdk.context.json` Quindi, esegue nuovamente l'app AWS CDK con i valori di contesto.

## Visualizzazione e gestione del contesto
<a name="context-viewing"></a>

Usa il `cdk context` comando per visualizzare e gestire le informazioni nel tuo `cdk.context.json` file. Per visualizzare queste informazioni, usa il `cdk context` comando senza alcuna opzione. L'output dovrebbe essere simile al seguente.

```
Context found in cdk.json:

┌───┬─────────────────────────────────────────────────────────────┬─────────────────────────────────────────────────────────┐
│ # │ Key                                                         │ Value                                                   │
├───┼─────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────┤
│ 1 │ availability-zones:account=123456789012:region=eu-central-1 │ [ "eu-central-1a", "eu-central-1b", "eu-central-1c" ]   │
├───┼─────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────┤
│ 2 │ availability-zones:account=123456789012:region=eu-west-1    │ [ "eu-west-1a", "eu-west-1b", "eu-west-1c" ]            │
└───┴─────────────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────┘

Run

  cdk context --reset KEY_OR_NUMBER

 to remove a context key. If it is a cached value, it will be refreshed on the next

  cdk synth

.
```

Per rimuovere un valore di contesto, esegui`cdk context --reset`, specificando la chiave o il numero corrispondente al valore. L'esempio seguente rimuove il valore che corrisponde alla seconda chiave dell'esempio precedente. Questo valore rappresenta l'elenco delle zone di disponibilità nella regione Europa (Irlanda).

```
cdk context --reset 2
```

```
Context value
availability-zones:account=123456789012:region=eu-west-1
reset. It will be refreshed on the next SDK synthesis run.
```

Pertanto, se desideri eseguire l'aggiornamento all'ultima versione dell'AMI Amazon Linux, utilizza l'esempio precedente per eseguire un aggiornamento controllato del valore di contesto e reimpostarlo. Quindi, sintetizza e distribuisci nuovamente l'app.

```
$ cdk synth
```

Per cancellare tutti i valori di contesto memorizzati per la tua app`cdk context --clear`, esegui come segue.

```
$ cdk context --clear
```

Solo i valori di contesto memorizzati in `cdk.context.json` possono essere ripristinati o cancellati. Il AWS CDK non tocca altri valori di contesto. Pertanto, per proteggere un valore di contesto dalla reimpostazione mediante questi comandi, è possibile copiare il valore in`cdk.json`.

## AWS Bandiera CDK Toolkit `--context`
<a name="context-cli"></a>

Utilizzate l'opzione `--context` (in breve) `-c` per passare i valori del contesto di runtime all'app CDK durante la sintesi o la distribuzione.

```
$ cdk synth --context key=value MyStack
```

Per specificare più valori di contesto, ripetete l'`--context`opzione un numero qualsiasi di volte, fornendo ogni volta una coppia chiave-valore.

```
$ cdk synth --context key1=value1 --context key2=value2 MyStack
```

Quando si sintetizzano più stack, i valori di contesto specificati vengono passati a tutti gli stack. Per fornire valori di contesto diversi ai singoli stack, utilizzate chiavi diverse per i valori oppure utilizzate più comandi o. `cdk synth` `cdk deploy`

I valori di contesto passati dalla riga di comando sono sempre stringhe. Se un valore è in genere di un altro tipo, il codice deve essere preparato per convertire o analizzare il valore. È possibile che i valori di contesto non stringhe vengano forniti in altri modi (ad esempio, in`cdk.context.json`). Per assicurarti che questo tipo di valore funzioni come previsto, verifica che il valore sia una stringa prima di convertirlo.

## Esempio
<a name="context-example"></a>

Di seguito è riportato un esempio di utilizzo di un Amazon VPC esistente utilizzando il contesto AWS CDK.

**Example**  

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

export class ExistsVpcStack extends cdk.Stack {

  constructor(scope: Construct, id: string, props?: cdk.StackProps) {

    super(scope, id, props);

    const vpcid = this.node.tryGetContext('vpcid');
    const vpc = ec2.Vpc.fromLookup(this, 'VPC', {
      vpcId: vpcid,
    });

    const pubsubnets = vpc.selectSubnets({subnetType: ec2.SubnetType.PUBLIC});

    new cdk.CfnOutput(this, 'publicsubnets', {
      value: pubsubnets.subnetIds.toString(),
    });
  }
}
```

```
const cdk = require('aws-cdk-lib');
const ec2 = require('aws-cdk-lib/aws-ec2');

class ExistsVpcStack extends cdk.Stack {

  constructor(scope, id, props) {

    super(scope, id, props);

    const vpcid = this.node.tryGetContext('vpcid');
    const vpc = ec2.Vpc.fromLookup(this, 'VPC', {
      vpcId: vpcid
    });

    const pubsubnets = vpc.selectSubnets({subnetType: ec2.SubnetType.PUBLIC});

    new cdk.CfnOutput(this, 'publicsubnets', {
      value: pubsubnets.subnetIds.toString()
    });
  }
}

module.exports = { ExistsVpcStack }
```

```
import aws_cdk as cdk
import aws_cdk.aws_ec2 as ec2
from constructs import Construct

class ExistsVpcStack(cdk.Stack):

    def __init__(scope: Construct, id: str, **kwargs):

        super().__init__(scope, id, **kwargs)

        vpcid = self.node.try_get_context("vpcid")
        vpc = ec2.Vpc.from_lookup(self, "VPC", vpc_id=vpcid)

        pubsubnets = vpc.select_subnets(subnetType=ec2.SubnetType.PUBLIC)

        cdk.CfnOutput(self, "publicsubnets",
            value=pubsubnets.subnet_ids.to_string())
```

```
import software.amazon.awscdk.CfnOutput;

import software.amazon.awscdk.services.ec2.Vpc;
import software.amazon.awscdk.services.ec2.VpcLookupOptions;
import software.amazon.awscdk.services.ec2.SelectedSubnets;
import software.amazon.awscdk.services.ec2.SubnetSelection;
import software.amazon.awscdk.services.ec2.SubnetType;
import software.constructs.Construct;

public class ExistsVpcStack extends Stack {
    public ExistsVpcStack(Construct context, String id) {
        this(context, id, null);
    }

    public ExistsVpcStack(Construct context, String id, StackProps props) {
        super(context, id, props);

        String vpcId = (String)this.getNode().tryGetContext("vpcid");
        Vpc vpc = (Vpc)Vpc.fromLookup(this, "VPC", VpcLookupOptions.builder()
                .vpcId(vpcId).build());

        SelectedSubnets pubSubNets = vpc.selectSubnets(SubnetSelection.builder()
                .subnetType(SubnetType.PUBLIC).build());

        CfnOutput.Builder.create(this, "publicsubnets")
                .value(pubSubNets.getSubnetIds().toString()).build();
    }
}
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.EC2;
using Constructs;

class ExistsVpcStack : Stack
{
    public ExistsVpcStack(Construct scope, string id, StackProps props) : base(scope, id, props)
    {
        var vpcId = (string)this.Node.TryGetContext("vpcid");
        var vpc = Vpc.FromLookup(this, "VPC", new VpcLookupOptions
        {
            VpcId = vpcId
        });

        SelectedSubnets pubSubNets = vpc.SelectSubnets([new SubnetSelection
        {
            SubnetType = SubnetType.PUBLIC
        }]);

        new CfnOutput(this, "publicsubnets", new CfnOutputProps {
            Value = pubSubNets.SubnetIds.ToString()
        });
    }
}
```

Puoi usarlo `cdk diff` per vedere gli effetti del passaggio di un valore di contesto sulla riga di comando:

```
$ cdk diff -c vpcid=vpc-0cb9c31031d0d3e22
```

```
Stack ExistsvpcStack
Outputs
[+] Output publicsubnets publicsubnets: {"Value":"subnet-06e0ea7dd302d3e8f,subnet-01fc0acfb58f3128f"}
```

I valori di contesto risultanti possono essere visualizzati come illustrato qui.

```
$ cdk context -j
```

```
{
  "vpc-provider:account=123456789012:filter.vpc-id=vpc-0cb9c31031d0d3e22:region=us-east-1": {
    "vpcId": "vpc-0cb9c31031d0d3e22",
    "availabilityZones": [
      "us-east-1a",
      "us-east-1b"
    ],
    "privateSubnetIds": [
      "subnet-03ecfc033225be285",
      "subnet-0cded5da53180ebfa"
    ],
    "privateSubnetNames": [
      "Private"
    ],
    "privateSubnetRouteTableIds": [
      "rtb-0e955393ced0ada04",
      "rtb-05602e7b9f310e5b0"
    ],
    "publicSubnetIds": [
      "subnet-06e0ea7dd302d3e8f",
      "subnet-01fc0acfb58f3128f"
    ],
    "publicSubnetNames": [
      "Public"
    ],
    "publicSubnetRouteTableIds": [
      "rtb-00d1fdfd823c82289",
      "rtb-04bb1969b42969bcb"
    ]
  }
}
```

# AWS Bandiere con funzionalità CDK
<a name="featureflags"></a>

Il AWS CDK utilizza i *flag di funzionalità* per abilitare comportamenti potenzialmente negativi in una versione. I flag vengono memorizzati come valori di [contesto e i valori AWS CDK](context.md) in (or). `cdk.json` `~/.cdk.json` Non vengono rimossi dai comandi `cdk context --reset` o`cdk context --clear`.

I flag delle funzionalità sono disabilitati per impostazione predefinita. I progetti esistenti che non specificano il flag continueranno a funzionare come prima con le versioni successive di AWS CDK. I nuovi progetti creati utilizzando i flag `cdk init` includono che abilitano tutte le funzionalità disponibili nella versione che ha creato il progetto. Modifica `cdk.json` per disabilitare tutti i flag per i quali preferisci il comportamento precedente. È inoltre possibile aggiungere flag per abilitare nuovi comportamenti dopo l'aggiornamento del CDK. AWS 

[Un elenco di tutti i flag di funzionalità correnti è disponibile nel repository CDK in Feature\$1flags.md. AWS GitHub ](https://github.com/aws/aws-cdk/blob/main/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md) Per una descrizione di tutte le `CHANGELOG` nuove funzionalità aggiunte in quella versione, consulta la sezione relativa a una determinata versione.

## Ripristino del comportamento v1
<a name="featureflags-disabling"></a>

In CDK v2, le impostazioni predefinite per alcuni flag di funzionalità sono state modificate rispetto alla v1. È possibile impostarli su per ripristinare il comportamento specifico di CDK `false` v1. AWS Utilizzate il `cdk diff` comando per controllare le modifiche al modello sintetizzato per vedere se qualcuno di questi flag è necessario.

 `@aws-cdk/core:newStyleStackSynthesis`   
Usa il nuovo metodo di sintesi dello stack, che presuppone risorse bootstrap con nomi noti. Richiede un [bootstrap moderno](bootstrapping.md), ma a sua volta consente la CI/CD tramite CDK Pipelines e le distribuzioni tra [account preconfigurate](cdk-pipeline.md).

 `@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId`   
Se la tua applicazione utilizza più chiavi API Amazon API Gateway e le associa a piani di utilizzo.

 `@aws-cdk/aws-rds:lowercaseDbIdentifier`   
Se la tua applicazione utilizza istanze di database Amazon RDS o cluster di database e specifica esplicitamente l'identificatore per questi.

 `@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021`   
Se la tua applicazione utilizza la politica di sicurezza TLS\$1V1\$12\$12019 con le distribuzioni Amazon. CloudFront CDK v2 utilizza la politica di sicurezza .2\$12021 per impostazione predefinita. TLSv1

 `@aws-cdk/core:stackRelativeExports`   
Se l'applicazione utilizza più stack e si fa riferimento alle risorse di uno stack all'altro, ciò determina se viene utilizzato un percorso assoluto o relativo per costruire le esportazioni. AWS CloudFormation 

 `@aws-cdk/aws-lambda:recognizeVersionProps`   
Se impostato su`false`, il CDK include i metadati quando rileva se una funzione Lambda è cambiata. Ciò può causare errori di distribuzione quando sono stati modificati solo i metadati, poiché non sono consentite versioni duplicate. Non è necessario ripristinare questo flag se hai apportato almeno una modifica a tutte le funzioni Lambda dell'applicazione.

La sintassi per ripristinare questi flag è mostrata qui. `cdk.json`

```
{
  "context": {
    "@aws-cdk/core:newStyleStackSynthesis": false,
    "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": false,
    "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": false,
    "@aws-cdk/aws-rds:lowercaseDbIdentifier": false,
    "@aws-cdk/core:stackRelativeExports": false,
    "@aws-cdk/aws-lambda:recognizeVersionProps": false
  }
}
```

# Aspetti e AWS CDK
<a name="aspects"></a>

Gli aspetti sono un modo per applicare un'operazione a tutti i costrutti in un determinato ambito. L'aspetto potrebbe modificare i costrutti, ad esempio aggiungendo tag. Oppure potrebbe verificare qualcosa sullo stato dei costrutti, ad esempio assicurarsi che tutti i bucket siano crittografati.

Per applicare un aspetto a un costrutto e a tutti i costrutti nello stesso ambito, chiamate ` [Aspects](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Aspects.html#static-ofscope).of(<SCOPE>).add()` con un nuovo aspetto, come mostrato nell'esempio seguente.

**Example**  

```
Aspects.of(myConstruct).add(new SomeAspect(...));
```

```
Aspects.of(myConstruct).add(new SomeAspect(...));
```

```
Aspects.of(my_construct).add(SomeAspect(...))
```

```
Aspects.of(myConstruct).add(new SomeAspect(...));
```

```
Aspects.Of(myConstruct).add(new SomeAspect(...));
```

```
awscdk.Aspects_Of(stack).Add(awscdk.NewTag(...))
```

Il AWS CDK utilizza gli aspetti per [etichettare le risorse](tagging.md), ma il framework può essere utilizzato anche per altri scopi. Ad esempio, potete usarlo per convalidare o modificare le AWS CloudFormation risorse definite per voi da costrutti di livello superiore.

## Aspects vs. Mixins
<a name="aspects-vs-mixins"></a>

Aspects e [Mixin](mixins.md) modificano entrambi i costrutti, ma differiscono nel momento e nel modo in cui vengono applicati:


| Funzionalità | Aspetti | Mixins | 
| --- | --- | --- | 
|   **Quando applicato**   |  Durante la sintesi, dopo che tutto l'altro codice è stato eseguito.  |  Immediatamente quando `.with()` viene chiamato.  | 
|   **Scope** (Ambito)   |  Tutti i costrutti in un determinato ambito, inclusi i costrutti aggiunti successivamente.  |  Solo i costrutti a cui li applichi esplicitamente.  | 
|   **Style** (Stile)   |  Dichiarativo: imposti una regola e il CDK la applica.  |  Imperativo: scegli tu cosa applicare e dove.  | 
|   **Ideale per**   |  Convalida, conformità, etichettatura, politiche generali.  |  Aggiungere funzionalità specifiche alle singole risorse.  | 

Usa Aspects quando desideri applicare le regole all'intera applicazione o verificare che i costrutti soddisfino determinati criteri. Usa Mixins quando vuoi aggiungere una funzionalità specifica a un costrutto specifico.

Aspects e Mixins possono essere usati insieme. Ad esempio, potreste utilizzare Mixins per configurare singole risorse e Aspects per verificare che tutte le risorse in uno stack soddisfino i requisiti di sicurezza dell'organizzazione.

## Aspetti in dettaglio
<a name="aspects-detail"></a>

Gli aspetti utilizzano lo [schema dei visitatori.](https://en.wikipedia.org/wiki/Visitor_pattern) Un aspetto è una classe che implementa la seguente interfaccia.

**Example**  

```
interface IAspect {
   visit(node: IConstruct): void;}
```
JavaScript non ha interfacce come funzionalità linguistica. Pertanto, un aspetto è semplicemente un'istanza di una classe con un `visit` metodo che accetta il nodo su cui operare.
Python non ha interfacce come funzionalità del linguaggio. Pertanto, un aspetto è semplicemente un'istanza di una classe con un `visit` metodo che accetta il nodo su cui operare.

```
public interface IAspect {
    public void visit(Construct node);
}
```

```
public interface IAspect
{
    void Visit(IConstruct node);
}
```

```
type IAspect interface {
  Visit(node constructs.IConstruct)
}
```

Quando si chiama`Aspects.of(<SCOPE>).add(…​)`, il costrutto aggiunge l'aspetto a un elenco interno di aspetti. È possibile ottenere l'elenco con`Aspects.of(<SCOPE>)`.

Durante la [fase di preparazione](deploy.md#deploy-how-synth-app), il AWS CDK chiama il `visit` metodo dell'oggetto per il costrutto e ciascuno dei suoi figli in ordine dall'alto verso il basso.

Il `visit` metodo è libero di modificare qualsiasi cosa nel costrutto. In linguaggi fortemente tipizzati, trasmetti il costrutto ricevuto a un tipo più specifico prima di accedere a proprietà o metodi specifici del costrutto.

Gli aspetti non si propagano oltre i confini del `Stage` costrutto, perché dopo la definizione `Stages` sono autonomi e immutabili. Applica gli aspetti sul `Stage` costrutto stesso (o inferiore) se vuoi che visitino i costrutti all'interno di. `Stage`

## Esempio
<a name="aspects-example"></a>

L'esempio seguente verifica che tutti i bucket creati nello stack abbiano il controllo delle versioni abilitato. L'aspetto aggiunge un'annotazione di errore ai costrutti che non superano la convalida. Ciò comporta il fallimento dell'`synth`operazione e impedisce la distribuzione dell'assemblaggio cloud risultante.

**Example**  

```
class BucketVersioningChecker implements IAspect {
  public visit(node: IConstruct): void {
    // See that we're dealing with a CfnBucket
    if (node instanceof s3.CfnBucket) {

      // Check for versioning property, exclude the case where the property
      // can be a token (IResolvable).
      if (!node.versioningConfiguration
        || (!Tokenization.isResolvable(node.versioningConfiguration)
            && node.versioningConfiguration.status !== 'Enabled')) {
        Annotations.of(node).addError('Bucket versioning is not enabled');
      }
    }
  }
}

// Later, apply to the stack
Aspects.of(stack).add(new BucketVersioningChecker());
```

```
class BucketVersioningChecker {
   visit(node) {
    // See that we're dealing with a CfnBucket
    if ( node instanceof s3.CfnBucket) {

      // Check for versioning property, exclude the case where the property
      // can be a token (IResolvable).
      if (!node.versioningConfiguration
        || !Tokenization.isResolvable(node.versioningConfiguration)
            && node.versioningConfiguration.status !== 'Enabled')) {
        Annotations.of(node).addError('Bucket versioning is not enabled');
      }
    }
  }
}

// Later, apply to the stack
Aspects.of(stack).add(new BucketVersioningChecker());
```

```
@jsii.implements(cdk.IAspect)
class BucketVersioningChecker:

  def visit(self, node):
    # See that we're dealing with a CfnBucket
    if isinstance(node, s3.CfnBucket):

      # Check for versioning property, exclude the case where the property
      # can be a token (IResolvable).
      if (not node.versioning_configuration or
              not Tokenization.is_resolvable(node.versioning_configuration)
                  and node.versioning_configuration.status != "Enabled"):
          Annotations.of(node).add_error('Bucket versioning is not enabled')

# Later, apply to the stack
Aspects.of(stack).add(BucketVersioningChecker())
```

```
public class BucketVersioningChecker implements IAspect
{
    @Override
    public void visit(Construct node)
    {
        // See that we're dealing with a CfnBucket
        if (node instanceof CfnBucket)
        {
            CfnBucket bucket = (CfnBucket)node;
            Object versioningConfiguration = bucket.getVersioningConfiguration();
            if (versioningConfiguration == null ||
                    !Tokenization.isResolvable(versioningConfiguration.toString()) &&
                    !versioningConfiguration.toString().contains("Enabled"))
                Annotations.of(bucket.getNode()).addError("Bucket versioning is not enabled");
        }
    }
}

// Later, apply to the stack
Aspects.of(stack).add(new BucketVersioningChecker());
```

```
class BucketVersioningChecker : Amazon.Jsii.Runtime.Deputy.DeputyBase, IAspect
{
    public void Visit(IConstruct node)
    {
        // See that we're dealing with a CfnBucket
        if (node is CfnBucket)
        {
            var bucket = (CfnBucket)node;
            if (bucket.VersioningConfiguration is null ||
                    !Tokenization.IsResolvable(bucket.VersioningConfiguration) &&
                    !bucket.VersioningConfiguration.ToString().Contains("Enabled"))
                Annotations.Of(bucket.Node).AddError("Bucket versioning is not enabled");
        }
    }
}

// Later, apply to the stack
Aspects.Of(stack).add(new BucketVersioningChecker());
```