

Esta es la guía para desarrolladores de AWS CDK v2. La primera versión del CDK pasó a la etapa de mantenimiento el 1.° de junio de 2022 y no cuenta con soporte desde el 1.° de junio de 2023.

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Los identificadores y la CDK AWS
<a name="identifiers"></a>

Al crear aplicaciones del AWS Cloud Development Kit (AWS CDK), utilizará muchos tipos de identificadores y nombres. Para utilizar el AWS CDK de forma eficaz y evitar errores, es importante entender los tipos de identificadores.

Los identificadores deben ser únicos dentro del ámbito en el que se crean; no es necesario que sean únicos a nivel mundial en su AWS aplicación de CDK.

Si intenta crear un identificador con el mismo valor dentro del mismo ámbito, la AWS CDK genera una excepción.

## Construye IDs
<a name="identifiers-construct-ids"></a>

El identificador más común, `id`, es el identificador que se pasa como segundo argumento al crear una instancia de un objeto de constructo. Este identificador, como todos los identificadores, solo debe ser único dentro del ámbito en el que se creó, que es el primer argumento al crear una instancia un objeto de constructo.

**nota**  
El `id` de una pila es también el identificador que se utiliza para hacer referencia a ella en la [referencia de la CLI de AWS CDK](cli.md).

Veamos un ejemplo en el que tenemos dos constructos con el identificador `MyBucket` en nuestra aplicación. El primero se define en el ámbito de la pila con el identificador `Stack1`. El segundo se define en el ámbito de una pila con el identificador `Stack2`. Como se definen en ámbitos diferentes, esto no genera ningún conflicto y pueden coexistir en la misma aplicación sin problemas.

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

## Rutas
<a name="identifiers-paths"></a>

Los constructos de una aplicación de AWS CDK forman una jerarquía basada en la `App` clase. *Nos referimos a la colección IDs de un constructo dado, su constructo padre, su antepasado, etc., hasta la raíz del árbol del constructo, como ruta.*

La AWS CDK normalmente muestra las rutas de las plantillas en forma de cadena. Los niveles están separados por barras diagonales, empezando por el nodo situado inmediatamente debajo de la `App` instancia raíz, que suele ser una pila. IDs Por ejemplo, las rutas de los dos recursos de bucket de Amazon S3 del ejemplo de código anterior son `Stack1/MyBucket` y `Stack2/MyBucket`.

Puede proporcionar la ruta de cualquier constructo mediante programación, como se muestra en el siguiente ejemplo. Esto obtiene la ruta `myConstruct` (o `my_construct`, como lo escribirían los desarrolladores de Python). Como IDs deben ser únicas dentro del ámbito en el que se crean, sus rutas siempre son únicas dentro de una aplicación de 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;
```

## Únicas IDs
<a name="identifiers-unique-ids"></a>

 AWS CloudFormation requiere que toda la lógica IDs de una plantilla sea única. Por ello, la AWS CDK debe poder generar un identificador único para cada construcción de una aplicación. Los recursos tienen rutas que son únicas a nivel mundial (los nombres de todos los ámbitos de la pila hasta un recurso específico). Por lo tanto, la AWS CDK genera los identificadores únicos necesarios concatenando los elementos de la ruta y añadiendo un hash de 8 dígitos. (El hash es necesario para distinguir rutas distintas, como `A/B/C` y`A/BC`, que darían como resultado el mismo identificador. AWS CloudFormation AWS CloudFormation los identificadores son alfanuméricos y no pueden contener barras ni otros caracteres separadores.) El AWS CDK llama a esta cadena el *identificador único de la construcción.*

En general, tu aplicación AWS CDK no debería necesitar información sobre Unique. IDs Sin embargo, es posible acceder al ID único de cualquier constructo mediante programación, como se muestra en el ejemplo siguiente.

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

La *dirección* es otro tipo de identificador único que distingue de forma única los recursos de CDK. Derivado del hash SHA-1 de la ruta, no es legible por humanos. Sin embargo, su longitud constante y relativamente corta (siempre 42 caracteres hexadecimales) la hace útil en situaciones en las que el ID único “tradicional” puede ser demasiado largo. Algunas construcciones pueden usar la dirección de la AWS CloudFormation plantilla sintetizada en lugar del identificador único. De nuevo, por lo general, la aplicación no debería necesitar conocer las direcciones de sus constructos, pero puede recuperar la dirección de un componente de la siguiente manera.

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

## Lógico IDs
<a name="identifiers-logical-ids"></a>

Cuando el AWS CDK sintetiza tu aplicación en una AWS CloudFormation plantilla, genera un *ID lógico* para cada recurso. AWS CloudFormation utiliza la lógica IDs para identificar los recursos de una plantilla y realizar un seguimiento de los mismos en todas las implementaciones. Comprender cómo IDs se genera la lógica le ayuda a evitar la sustitución involuntaria de recursos al refactorizar el código CDK.

### ¿Cómo se genera la lógica IDs
<a name="identifiers-logical-id-generation"></a>

La AWS CDK genera la lógica IDs a partir de la ruta de construcción mediante el siguiente algoritmo:

1. Concatene los componentes de la ruta del árbol de construcción, excluyendo la propia pila.

1. Aplique la heurística para mejorar la legibilidad (consulte Heurística de los componentes de rutas de ID [lógicos](#identifiers-logical-id-heuristics)).

1. Añada un hash de 8 caracteres a la ruta completa para garantizar su unicidad.

El formato resultante es:

```
<human-readable-portion><8-character-hash>
```

Por ejemplo, una tabla de enrutamiento de subred privada de VPC podría generar el ID lógico. `VPCPrivateSubnet2RouteTable0A19E10E`

Las siguientes reglas se aplican a la generación de ID lógicos:
+ La longitud máxima es de 255 caracteres. La parte legible por humanos tiene un límite de 240 caracteres.
+ El hash de 8 caracteres garantiza que las rutas como `A/B/C` y`A/BC`, que se concatenan en la misma cadena, produzcan una lógica diferente. IDs
+ Los recursos que son elementos secundarios directos de la pila (rutas de un solo componente) utilizan su nombre directamente sin un hash, siempre que el nombre tenga 255 caracteres o menos.

### Ruta de identificación lógica: heurística de componentes
<a name="identifiers-logical-id-heuristics"></a>

El AWS CDK aplica la siguiente heurística a los componentes de la ruta cuando genera la parte lógica legible por humanos. IDs

 `Default`— eliminado por completo  
Si un componente de ruta lo es`Default`, la CDK lo elimina tanto de la parte legible por humanos como de la entrada del hash. Esto significa que al incluir una construcción existente dentro de una nueva construcción (y asignar un nombre a la construcción interna) se `Default` obtiene exactamente el mismo identificador lógico que la construcción original sin empaquetar. Este es el mecanismo clave para refactorizar de forma segura el código plano en construcciones de nivel superior sin cambiar las identidades de los recursos desplegados.

 `Resource`— oculto solo en la parte legible por humanos  
Si un componente de ruta lo es`Resource`, la CDK lo omite de la parte legible por humanos, pero aun así lo incluye en el cálculo del hash. Por convención, las construcciones L1 (CloudFormation) se utilizan `Resource` como ID de construcción. Esto IDs acorta la lógica sin perder su singularidad.

Componentes consecutivos duplicados: deduplicados  
Si el nombre del componente de la ruta anterior termina con el nombre del componente actual, la CDK omite el componente actual. Esto evita la repetición redundante en la lógica. IDs

### Se utiliza `Default` para conservar la lógica IDs al refactorizar
<a name="identifiers-logical-id-refactoring"></a>

Al refactorizar una pila plana en construcciones de nivel superior, puede utilizarla `Default` como ID de construcción del recurso principal para conservar su ID lógico. Esto AWS CloudFormation impide reemplazar el recurso durante la implementación.

El siguiente ejemplo muestra una pila con recursos que se definen directamente:

**Example**  

```
export class MyStack extends cdk.Stack {
  constructor(scope: Construct, id: string) {
    super(scope, id);
    new s3.Bucket(this, 'DataBucket');
    new lambda.Function(this, 'ProcessFunction', { /* ... */ });
  }
}
```

```
class MyStack extends cdk.Stack {
  constructor(scope, id) {
    super(scope, id);
    new s3.Bucket(this, 'DataBucket');
    new lambda.Function(this, 'ProcessFunction', { /* ... */ });
  }
}
```

```
from aws_cdk import (
    Stack,
    aws_s3 as s3,
    aws_lambda as _lambda,
)
from constructs import Construct

class MyStack(Stack):
    def __init__(self, scope: Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)
        s3.Bucket(self, "DataBucket")
        _lambda.Function(self, "ProcessFunction", # ...
        )
```

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

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, "DataBucket");
        Function.Builder.create(this, "ProcessFunction")
            // ...
            .build();
    }
}
```

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

namespace MyApp
{
    public class MyStack : Stack
    {
        public MyStack(Construct scope, string id, StackProps props = null) : base(scope, id, props)
        {
            new Bucket(this, "DataBucket");
            new Function(this, "ProcessFunction", new FunctionProps
            {
                // ...
            });
        }
    }
}
```

```
package main

import (
	"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 MyStackProps struct {
	awscdk.StackProps
}

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

	awss3.NewBucket(stack, jsii.String("DataBucket"), &awss3.BucketProps{})
	awslambda.NewFunction(stack, jsii.String("ProcessFunction"), &awslambda.FunctionProps{
		// ...
	})

	return stack
}
```

La ruta del depósito es`MyStack/DataBucket/Resource`, lo que produce un identificador lógico de`DataBucket<hash>`.

Puede extraer el depósito en una construcción de nivel superior y conservar el mismo ID lógico asignando un nombre a la construcción `Default` interna:

**Example**  

```
class DataPipeline extends Construct {
  constructor(scope: Construct, id: string) {
    super(scope, id);
    new s3.Bucket(this, 'Default');  // 'Default' is hidden from logical ID
    new lambda.Function(this, 'ProcessFunction', { /* ... */ });
  }
}

export class MyStack extends cdk.Stack {
  constructor(scope: Construct, id: string) {
    super(scope, id);
    new DataPipeline(this, 'DataBucket');
  }
}
```

```
class DataPipeline extends Construct {
  constructor(scope, id) {
    super(scope, id);
    new s3.Bucket(this, 'Default');  // 'Default' is hidden from logical ID
    new lambda.Function(this, 'ProcessFunction', { /* ... */ });
  }
}

class MyStack extends cdk.Stack {
  constructor(scope, id) {
    super(scope, id);
    new DataPipeline(this, 'DataBucket');
  }
}
```

```
from aws_cdk import (
    Stack,
    aws_s3 as s3,
    aws_lambda as _lambda,
)
from constructs import Construct

class DataPipeline(Construct):
    def __init__(self, scope: Construct, id: str) -> None:
        super().__init__(scope, id)
        s3.Bucket(self, "Default")  # 'Default' is hidden from logical ID
        _lambda.Function(self, "ProcessFunction", # ...
        )

class MyStack(Stack):
    def __init__(self, scope: Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)
        DataPipeline(self, "DataBucket")
```

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

public class DataPipeline extends Construct {
    public DataPipeline(final Construct scope, final String id) {
        super(scope, id);
        new Bucket(this, "Default");  // 'Default' is hidden from logical ID
        Function.Builder.create(this, "ProcessFunction")
            // ...
            .build();
    }
}

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 DataPipeline(this, "DataBucket");
    }
}
```

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

namespace MyApp
{
    public class DataPipeline : Construct
    {
        public DataPipeline(Construct scope, string id) : base(scope, id)
        {
            new Bucket(this, "Default");  // 'Default' is hidden from logical ID
            new Function(this, "ProcessFunction", new FunctionProps
            {
                // ...
            });
        }
    }

    public class MyStack : Stack
    {
        public MyStack(Construct scope, string id, StackProps props = null) : base(scope, id, props)
        {
            new DataPipeline(this, "DataBucket");
        }
    }
}
```

```
package main

import (
	"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 DataPipeline struct {
	constructs.Construct
}

func NewDataPipeline(scope constructs.Construct, id string) constructs.Construct {
	this := constructs.NewConstruct(scope, &id)

	// 'Default' is hidden from logical ID
	awss3.NewBucket(this, jsii.String("Default"), &awss3.BucketProps{})
	awslambda.NewFunction(this, jsii.String("ProcessFunction"), &awslambda.FunctionProps{
		// ...
	})

	return this
}

type MyStackProps struct {
	awscdk.StackProps
}

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

	NewDataPipeline(stack, "DataBucket")

	return stack
}
```

La ruta del cubo es ahora`MyStack/DataBucket/Default/Resource`. Como `Default` se elimina tanto de la parte legible por humanos como de la entrada hash, el identificador lógico permanece `DataBucket<hash>` idéntico al original.

**importante**  
Solo puede tener un hijo con el ID `Default` por ámbito de construcción. Si necesita varios recursos al mismo nivel, indíquelos de forma descriptiva IDs. El `Default` patrón funciona mejor con construcciones de responsabilidad única que tienen un recurso principal.

### Limitaciones y consideraciones
<a name="identifiers-logical-id-considerations"></a>

Tenga en cuenta lo siguiente cuando trabaje con la lógica: IDs
+ Solo puede asignar el ID de `Default` construcción a un elemento secundario por ámbito.
+ Si cambia el identificador de una construcción después del despliegue, el identificador lógico cambia, lo AWS CloudFormation que provoca la sustitución del recurso. Se utiliza `cdk diff` para comprobar los cambios antes de la implementación.
+ En los casos en los que la lógica ya IDs haya cambiado, puede usar el `cdk refactor` comando para asignar la lógica antigua IDs a la nueva. Para obtener más información, consulte [Conserve los recursos implementados al refactorizar el código del CDK](refactor.md).
+ Para obtener más información sobre cómo IDs aparece la lógica en las plantillas sintetizadas, consulte La [lógica generada IDs en la AWS CloudFormation plantilla](configure-synth.md#how-synth-default-logical-ids).

### Estabilidad de ID lógico
<a name="identifiers-logical-id-stability"></a>

Evite cambiar el identificador lógico de un recurso una vez creado. AWS CloudFormation identifica los recursos por su identificador lógico. Por lo tanto, si cambia el identificador lógico de un recurso, AWS CloudFormation crea un nuevo recurso con el nuevo identificador lógico y, a continuación, elimina el existente. Según el tipo de recurso, esto puede provocar la interrupción del servicio, la pérdida de datos o ambas cosas.