Esta es la guía para AWS CDK desarrolladores de la versión 2. La CDK versión anterior entró en mantenimiento el 1 de junio de 2022 y finalizó el soporte 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.
Personalice los constructos desde la Biblioteca de constructos de AWS
Personalice los constructos desde la Biblioteca de constructos de AWS mediante escotillas de escape, anulaciones sin procesar y recursos personalizados.
Utilice escotillas de escape
La Biblioteca de constructos de AWS proporciona constructos de distintos niveles de abstracción.
En el nivel más alto, su aplicación AWS CDK y las pilas que contiene son abstracciones de toda su infraestructura en la nube, o de partes significativas de ella. Se pueden parametrizar para implementarlas en diferentes entornos o para diferentes necesidades.
Las abstracciones son herramientas potentes para diseñar e implementar aplicaciones en la nube. AWS CDK le permite no solo crear con sus abstracciones, sino también crear nuevas. A partir de los constructos L2 y L3 de código abierto existentes, puede crear sus propios constructos L2 y L3 para reflejar las prácticas recomendadas y las opiniones de su propia organización.
Ninguna abstracción es perfecta, e incluso aquellas que son buenas no pueden abarcar todos los casos de uso posibles. Durante el desarrollo, es posible que encuentre un constructo que casi se adapte a sus necesidades, pero que requiera una pequeña o gran personalización.
Por esta razón, AWS CDK proporciona formas para romper con el modelo del constructo. Esto incluye pasar a una abstracción de bajo nivel o a un modelo completamente diferente. Las escotillas de escape le permiten salir del paradigma de AWS CDK y personalizarlo de forma que se adapte a sus necesidades. Luego, puede agrupar los cambios en un nuevo constructo para abstraer la complejidad subyacente y proporcionar una API limpia para otros desarrolladores.
Los siguientes son ejemplos de situaciones en las que puede utilizar escotillas de escape:
-
Hay una característica de servicio de AWS disponible a través de AWS CloudFormation, pero no hay constructos L2 para ello.
-
Hay una característica de servicio de AWS disponible a través de AWS CloudFormation y hay constructos L2 para el servicio, pero aún no se exponen a la característica. Como los constructos L2 los selecciona el equipo CDK, es posible que no estén disponibles de forma inmediata para las características.
-
La característica todavía no está disponible a través de AWS CloudFormation en absoluto.
Para determinar si una característica está disponible a través de AWS CloudFormation, consulte la Referencia de tipos de recursos y propiedades de AWS.
Desarrolle escotillas de escape para los constructos L1
Si los constructos L2 no están disponibles para el servicio, puede utilizar constructos L1 generados automáticamente. Estos recursos se pueden reconocer por su nombre que comienza con Cfn
, como CfnBucket
o CfnRole
. Se instancian exactamente igual que el recurso equivalente de AWS CloudFormation.
Por ejemplo, para instanciar un bucket L1 de Amazon S3 de bajo nivel con el análisis habilitado, deber escribir algo similar a lo siguiente.
- TypeScript
-
new s3.CfnBucket(this, 'amzn-s3-demo-bucket', {
analyticsConfigurations: [
{
id: 'Config',
// ...
}
]
});
- JavaScript
-
new s3.CfnBucket(this, 'amzn-s3-demo-bucket', {
analyticsConfigurations: [
{
id: 'Config'
// ...
}
]
});
- Python
-
s3.CfnBucket(self, "amzn-s3-demo-bucket",
analytics_configurations: [
dict(id="Config",
# ...
)
]
)
- Java
-
CfnBucket.Builder.create(this, "amzn-s3-demo-bucket")
.analyticsConfigurations(Arrays.asList(java.util.Map.of( // Java 9 or later
"id", "Config", // ...
))).build();
- C#
-
new CfnBucket(this, 'amzn-s3-demo-bucket', new CfnBucketProps {
AnalyticsConfigurations = new Dictionary<string, string>
{
["id"] = "Config",
// ...
}
});
En raras ocasiones, puede que desee definir un recurso que no tenga una clase CfnXxx
correspondiente. Podría tratarse de un tipo de recurso nuevo que aún no se haya publicado en la especificación del recurso AWS CloudFormation. En estos casos, puede instanciar el cdk.CfnResource
directamente y especificar el tipo y las propiedades del recurso. Esto se muestra en el siguiente ejemplo.
- TypeScript
-
new cdk.CfnResource(this, 'amzn-s3-demo-bucket', {
type: 'AWS::S3::Bucket',
properties: {
// Note the PascalCase here! These are CloudFormation identifiers.
AnalyticsConfigurations: [
{
Id: 'Config',
// ...
}
]
}
});
- JavaScript
-
new cdk.CfnResource(this, 'amzn-s3-demo-bucket', {
type: 'AWS::S3::Bucket',
properties: {
// Note the PascalCase here! These are CloudFormation identifiers.
AnalyticsConfigurations: [
{
Id: 'Config'
// ...
}
]
}
});
- Python
-
cdk.CfnResource(self, 'amzn-s3-demo-bucket',
type="AWS::S3::Bucket",
properties=dict(
# Note the PascalCase here! These are CloudFormation identifiers.
"AnalyticsConfigurations": [
{
"Id": "Config",
# ...
}
]
}
)
- Java
-
CfnResource.Builder.create(this, "amzn-s3-demo-bucket")
.type("AWS::S3::Bucket")
.properties(java.util.Map.of( // Map.of requires Java 9 or later
// Note the PascalCase here! These are CloudFormation identifiers
"AnalyticsConfigurations", Arrays.asList(
java.util.Map.of("Id", "Config", // ...
))))
.build();
- C#
-
new CfnResource(this, "amzn-s3-demo-bucket", new CfnResourceProps
{
Type = "AWS::S3::Bucket",
Properties = new Dictionary<string, object>
{ // Note the PascalCase here! These are CloudFormation identifiers
["AnalyticsConfigurations"] = new Dictionary<string, string>[]
{
new Dictionary<string, string> {
["Id"] = "Config"
}
}
}
});
Desarrolle escotillas de escape para los constructos L2
Si a un constructo L2 le falta una característica o está tratando de solucionar un problema, puede modificar el constructo L1 que está encapsulado por el constructo L2.
Todos los constructos L2 contienen el constructo L1 correspondiente. Por ejemplo, el constructo Bucket
de alto nivel contiene el constructo CfnBucket
de bajo nivel. Como CfnBucket
corresponde directamente al recurso AWS CloudFormation, expone todas las características que están disponibles a través de AWS CloudFormation.
El enfoque básico para acceder al constructo L1 es usar construct.node.defaultChild
(Python: default_child
), convertirlo en el tipo correcto (si es necesario) y modificar sus propiedades. Volvamos a tomar el ejemplo de un Bucket
.
- TypeScript
-
// Get the CloudFormation resource
const cfnBucket = bucket.node.defaultChild as s3.CfnBucket;
// Change its properties
cfnBucket.analyticsConfiguration = [
{
id: 'Config',
// ...
}
];
- JavaScript
-
// Get the CloudFormation resource
const cfnBucket = bucket.node.defaultChild;
// Change its properties
cfnBucket.analyticsConfiguration = [
{
id: 'Config'
// ...
}
];
- Python
-
# Get the CloudFormation resource
cfn_bucket = bucket.node.default_child
# Change its properties
cfn_bucket.analytics_configuration = [
{
"id": "Config",
# ...
}
]
- Java
-
// Get the CloudFormation resource
CfnBucket cfnBucket = (CfnBucket)bucket.getNode().getDefaultChild();
cfnBucket.setAnalyticsConfigurations(
Arrays.asList(java.util.Map.of( // Java 9 or later
"Id", "Config", // ...
));
- C#
-
// Get the CloudFormation resource
var cfnBucket = (CfnBucket)bucket.Node.DefaultChild;
cfnBucket.AnalyticsConfigurations = new List<object> {
new Dictionary<string, string>
{
["Id"] = "Config",
// ...
}
};
También puede usar este objeto para cambiar las opciones de AWS CloudFormation como Metadata
y UpdatePolicy
.
- TypeScript
-
cfnBucket.cfnOptions.metadata = {
MetadataKey: 'MetadataValue'
};
- JavaScript
-
cfnBucket.cfnOptions.metadata = {
MetadataKey: 'MetadataValue'
};
- Python
-
cfn_bucket.cfn_options.metadata = {
"MetadataKey": "MetadataValue"
}
- Java
-
cfnBucket.getCfnOptions().setMetadata(java.util.Map.of( // Java 9+
"MetadataKey", "Metadatavalue"));
- C#
-
cfnBucket.CfnOptions.Metadata = new Dictionary<string, object>
{
["MetadataKey"] = "Metadatavalue"
};
Utilice escotillas sin escape
AWS CDK también proporciona la capacidad de subir un nivel de abstracción, a lo que podríamos referirnos como escotilla “sin escape”. Si tiene un constructo L1, por ejemplo CfnBucket
, puede crear un constructo L2 nuevo (Bucket
en este caso) para incluir el constructo L1.
Esto resulta práctico cuando se crea un recurso L1, pero se quiere utilizar con un constructo que requiere un recurso L2. También resulta útil cuando se quieren utilizar métodos prácticos como .grantXxxxx()
, que no están disponibles en el constructo L1.
Se pasa al nivel superior de abstracción mediante un método estático en la clase L2 denominado .fromCfnXxxxx()
, por ejemplo: Bucket.fromCfnBucket()
para los buckets de Amazon S3. El recurso L1 es el único parámetro.
- TypeScript
-
b1 = new s3.CfnBucket(this, "buck09", { ... });
b2 = s3.Bucket.fromCfnBucket(b1);
- JavaScript
-
b1 = new s3.CfnBucket(this, "buck09", { ...} );
b2 = s3.Bucket.fromCfnBucket(b1);
- Python
-
b1 = s3.CfnBucket(self, "buck09", ...)
b2 = s3.from_cfn_bucket(b1)
- Java
-
CfnBucket b1 = CfnBucket.Builder.create(this, "buck09")
// ....
.build();
IBucket b2 = Bucket.fromCfnBucket(b1);
- C#
-
var b1 = new CfnBucket(this, "buck09", new CfnBucketProps { ... });
var v2 = Bucket.FromCfnBucket(b1);
Los constructos L2 creados a partir de constructos L1 son objetos proxy que hacen referencia al recurso L1, similares a los que se crean a partir de nombres de recursos, ARN o búsquedas. Las modificaciones de estos constructos no afectan a la plantilla sintetizada AWS CloudFormation final (sin embargo, dado que tiene el recurso L1, puede modificarla desde aquí). Para obtener más información sobre los objetos proxy, consulte Haciendo referencia a los recursos de tu cuenta AWS.
Para evitar confusiones, no cree varios constructos L2 que hagan referencia al mismo constructo L1. Por ejemplo, si extrae el CfnBucket
de un Bucket
mediante la técnica de la sección anterior, no debería crear una segunda instancia Bucket
llamando a Bucket.fromCfnBucket()
con ese CfnBucket
. De hecho, funciona como era de esperar (se sintetiza solo un AWS::S3::Bucket
), pero dificulta el mantenimiento del código.
Use anulaciones sin procesar
Si faltan propiedades en el constructo L1, puede omitir todo tipo de escritura mediante anulaciones sin procesar. Esto también permite eliminar las propiedades sintetizadas.
Use uno de los métodos addOverride
(Python: add_override
), como se muestra en el siguiente ejemplo.
- TypeScript
-
// Get the CloudFormation resource
const cfnBucket = bucket.node.defaultChild as s3.CfnBucket;
// Use dot notation to address inside the resource template fragment
cfnBucket.addOverride('Properties.VersioningConfiguration.Status', 'NewStatus');
cfnBucket.addDeletionOverride('Properties.VersioningConfiguration.Status');
// use index (0 here) to address an element of a list
cfnBucket.addOverride('Properties.Tags.0.Value', 'NewValue');
cfnBucket.addDeletionOverride('Properties.Tags.0');
// addPropertyOverride is a convenience function for paths starting with "Properties."
cfnBucket.addPropertyOverride('VersioningConfiguration.Status', 'NewStatus');
cfnBucket.addPropertyDeletionOverride('VersioningConfiguration.Status');
cfnBucket.addPropertyOverride('Tags.0.Value', 'NewValue');
cfnBucket.addPropertyDeletionOverride('Tags.0');
- JavaScript
-
// Get the CloudFormation resource
const cfnBucket = bucket.node.defaultChild ;
// Use dot notation to address inside the resource template fragment
cfnBucket.addOverride('Properties.VersioningConfiguration.Status', 'NewStatus');
cfnBucket.addDeletionOverride('Properties.VersioningConfiguration.Status');
// use index (0 here) to address an element of a list
cfnBucket.addOverride('Properties.Tags.0.Value', 'NewValue');
cfnBucket.addDeletionOverride('Properties.Tags.0');
// addPropertyOverride is a convenience function for paths starting with "Properties."
cfnBucket.addPropertyOverride('VersioningConfiguration.Status', 'NewStatus');
cfnBucket.addPropertyDeletionOverride('VersioningConfiguration.Status');
cfnBucket.addPropertyOverride('Tags.0.Value', 'NewValue');
cfnBucket.addPropertyDeletionOverride('Tags.0');
- Python
-
# Get the CloudFormation resource
cfn_bucket = bucket.node.default_child
# Use dot notation to address inside the resource template fragment
cfn_bucket.add_override("Properties.VersioningConfiguration.Status", "NewStatus")
cfn_bucket.add_deletion_override("Properties.VersioningConfiguration.Status")
# use index (0 here) to address an element of a list
cfn_bucket.add_override("Properties.Tags.0.Value", "NewValue")
cfn_bucket.add_deletion_override("Properties.Tags.0")
# addPropertyOverride is a convenience function for paths starting with "Properties."
cfn_bucket.add_property_override("VersioningConfiguration.Status", "NewStatus")
cfn_bucket.add_property_deletion_override("VersioningConfiguration.Status")
cfn_bucket.add_property_override("Tags.0.Value", "NewValue")
cfn_bucket.add_property_deletion_override("Tags.0")
- Java
-
// Get the CloudFormation resource
CfnBucket cfnBucket = (CfnBucket)bucket.getNode().getDefaultChild();
// Use dot notation to address inside the resource template fragment
cfnBucket.addOverride("Properties.VersioningConfiguration.Status", "NewStatus");
cfnBucket.addDeletionOverride("Properties.VersioningConfiguration.Status");
// use index (0 here) to address an element of a list
cfnBucket.addOverride("Properties.Tags.0.Value", "NewValue");
cfnBucket.addDeletionOverride("Properties.Tags.0");
// addPropertyOverride is a convenience function for paths starting with "Properties."
cfnBucket.addPropertyOverride("VersioningConfiguration.Status", "NewStatus");
cfnBucket.addPropertyDeletionOverride("VersioningConfiguration.Status");
cfnBucket.addPropertyOverride("Tags.0.Value", "NewValue");
cfnBucket.addPropertyDeletionOverride("Tags.0");
- C#
-
// Get the CloudFormation resource
var cfnBucket = (CfnBucket)bucket.node.defaultChild;
// Use dot notation to address inside the resource template fragment
cfnBucket.AddOverride("Properties.VersioningConfiguration.Status", "NewStatus");
cfnBucket.AddDeletionOverride("Properties.VersioningConfiguration.Status");
// use index (0 here) to address an element of a list
cfnBucket.AddOverride("Properties.Tags.0.Value", "NewValue");
cfnBucket.AddDeletionOverride("Properties.Tags.0");
// addPropertyOverride is a convenience function for paths starting with "Properties."
cfnBucket.AddPropertyOverride("VersioningConfiguration.Status", "NewStatus");
cfnBucket.AddPropertyDeletionOverride("VersioningConfiguration.Status");
cfnBucket.AddPropertyOverride("Tags.0.Value", "NewValue");
cfnBucket.AddPropertyDeletionOverride("Tags.0");
Utilice recursos personalizados
Si la característica no está disponible a través de AWS CloudFormation, sino que solo a través de una llamada a la API directa, debe escribir un recurso personalizado de AWS CloudFormation para realizar la llamada a la API que necesita. Puede utilizar AWS CDK para escribir recursos personalizados y agruparlos en una interfaz de constructos normal. Desde la perspectiva de un consumidor de su constructo, la experiencia será nativa.
La creación de un recurso personalizado implica escribir una función de Lambda que responda a los eventos del ciclo de vida CREATE
, UPDATE
y DELETE
de un recurso. Si su recurso personalizado necesita realizar solo una llamada a la API, considere la posibilidad de utilizar AwsCustomResource. Esto permite realizar llamadas arbitrarias al SDK durante una implementación de AWS CloudFormation. De lo contrario, deberá escribir su propia función de Lambda para realizar el trabajo que necesita.
El tema es demasiado extenso para abarcarlo por completo aquí, pero puede empezar por los siguientes enlaces: