Personnalisation des constructions à partir de la AWS bibliothèque de constructions - AWS Cloud Development Kit (AWS CDK) v2

Ceci est le guide du AWS CDK développeur de la version 2. L'ancien CDK v1 est entré en maintenance le 1er juin 2022 et a pris fin le 1er juin 2023.

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Personnalisation des constructions à partir de la AWS bibliothèque de constructions

Personnalisez les constructions de la bibliothèque de constructions AWS à l'aide de trappes d'évacuation, de remplacements bruts et de ressources personnalisées.

Utilisation de trappes d'évacuation

La AWS bibliothèque de constructions fournit des constructions de différents niveaux d'abstraction.

Au plus haut niveau, votre AWS CDK application et les éléments qu'elle contient sont eux-mêmes des abstractions de l'ensemble de votre infrastructure cloud, ou de parties importantes de celle-ci. Ils peuvent être paramétrés pour les déployer dans différents environnements ou pour différents besoins.

Les abstractions sont de puissants outils de conception et de mise en œuvre d'applications cloud. AWS CDK Cela vous donne le pouvoir non seulement de construire avec ses abstractions, mais également de créer de nouvelles abstractions. En utilisant les structures L2 et L3 open source existantes comme guide, vous pouvez créer vos propres structures L2 et L3 afin de refléter les meilleures pratiques et opinions de votre propre organisation.

Aucune abstraction n'est parfaite, et même de bonnes abstractions ne peuvent pas couvrir tous les cas d'utilisation possibles. Au cours du développement, il se peut que vous trouviez une construction qui correspond presque à vos besoins, nécessitant une petite ou une grande personnalisation.

Pour cette raison, il AWS CDK fournit des moyens de sortir du modèle de construction. Cela inclut le passage à une abstraction de niveau inférieur ou à un modèle complètement différent. Les trappes d'évacuation vous permettent d'échapper au AWS CDK paradigme et de le personnaliser en fonction de vos besoins. Vous pouvez ensuite intégrer vos modifications dans une nouvelle construction pour éliminer la complexité sous-jacente et fournir une API propre aux autres développeurs.

Voici des exemples de situations dans lesquelles vous pouvez utiliser des trappes d'évacuation :

  • Une fonctionnalité AWS de service est disponible via AWS CloudFormation, mais il n'existe aucune construction L2 pour elle.

  • Une fonctionnalité de AWS service est disponible via AWS CloudFormation, et il existe des constructions L2 pour le service, mais celles-ci n'exposent pas encore la fonctionnalité. Comme les constructions L2 sont conçues par l'équipe du CDK, il est possible qu'elles ne soient pas immédiatement disponibles pour les nouvelles fonctionnalités.

  • La fonctionnalité n'est pas encore disponible AWS CloudFormation du tout.

    Pour déterminer si une fonctionnalité est disponible via AWS CloudFormation, consultez la section Référence des types de AWS ressources et de propriétés.

Développez des trappes d'évacuation pour les constructions L1

Si les constructions L2 ne sont pas disponibles pour le service, vous pouvez utiliser les constructions L1 générées automatiquement. Ces ressources peuvent être reconnues par leur nom commençant parCfn, tel que CfnBucket ouCfnRole. Vous les instanciez exactement comme vous utiliseriez la ressource équivalente AWS CloudFormation .

Par exemple, pour instancier un bucket Amazon S3 L1 de bas niveau avec l'analyse activée, vous devez écrire quelque chose comme ceci.

TypeScript
new s3.CfnBucket(this, 'MyBucket', { analyticsConfigurations: [ { id: 'Config', // ... } ] });
JavaScript
new s3.CfnBucket(this, 'MyBucket', { analyticsConfigurations: [ { id: 'Config' // ... } ] });
Python
s3.CfnBucket(self, "MyBucket", analytics_configurations: [ dict(id="Config", # ... ) ] )
Java
CfnBucket.Builder.create(this, "MyBucket") .analyticsConfigurations(Arrays.asList(java.util.Map.of( // Java 9 or later "id", "Config", // ... ))).build();
C#
new CfnBucket(this, 'MyBucket', new CfnBucketProps { AnalyticsConfigurations = new Dictionary<string, string> { ["id"] = "Config", // ... } });

Dans de rares cas, il peut arriver que vous souhaitiez définir une ressource qui n'a pas de CfnXxx classe correspondante. Il peut s'agir d'un nouveau type de ressource qui n'a pas encore été publié dans la spécification de la AWS CloudFormation ressource. Dans de tels cas, vous pouvez les instancier cdk.CfnResource directement et spécifier le type et les propriétés de la ressource. Voici un exemple :

TypeScript
new cdk.CfnResource(this, 'MyBucket', { type: 'AWS::S3::Bucket', properties: { // Note the PascalCase here! These are CloudFormation identifiers. AnalyticsConfigurations: [ { Id: 'Config', // ... } ] } });
JavaScript
new cdk.CfnResource(this, 'MyBucket', { type: 'AWS::S3::Bucket', properties: { // Note the PascalCase here! These are CloudFormation identifiers. AnalyticsConfigurations: [ { Id: 'Config' // ... } ] } });
Python
cdk.CfnResource(self, 'MyBucket', type="AWS::S3::Bucket", properties=dict( # Note the PascalCase here! These are CloudFormation identifiers. "AnalyticsConfigurations": [ { "Id": "Config", # ... } ] } )
Java
CfnResource.Builder.create(this, "MyBucket") .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, "MyBucket", 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" } } } });

Développez des trappes d'évacuation pour les constructions L2

S'il manque une fonctionnalité à une construction L2 ou si vous essayez de contourner un problème, vous pouvez modifier la construction L1 encapsulée par la construction L2.

Toutes les constructions L2 contiennent la construction L1 correspondante. Par exemple, la construction de haut niveau enveloppe la Bucket construction de bas niveau. CfnBucket Comme il CfnBucket correspond directement à la AWS CloudFormation ressource, il expose toutes les fonctionnalités disponibles via AWS CloudFormation.

L'approche de base pour accéder à la construction L1 consiste à utiliser construct.node.defaultChild (Python :default_child), à la convertir dans le bon type (si nécessaire) et à modifier ses propriétés. Encore une fois, prenons l'exemple d'unBucket.

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", // ... } };

Vous pouvez également utiliser cet objet pour modifier AWS CloudFormation des options telles que Metadata etUpdatePolicy.

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

Trappes UN-Escape

AWS CDK Il permet également d'augmenter un niveau d'abstraction, ce que nous pourrions appeler une trappe « unescape ». Si vous avez une construction L1, par exempleCfnBucket, vous pouvez créer une nouvelle construction L2 (Bucketdans ce cas) pour encapsuler la construction L1.

C'est pratique lorsque vous créez une ressource L1 mais que vous souhaitez l'utiliser avec une construction qui nécessite une ressource L2. C'est également utile lorsque vous souhaitez utiliser des méthodes pratiques telles .grantXxxxx() que celles qui ne sont pas disponibles sur la construction L1.

Vous passez au niveau d'abstraction supérieur à l'aide d'une méthode statique sur la classe L2 appelée, par exemple, .fromCfnXxxxx() Bucket.fromCfnBucket() pour les buckets Amazon S3. La ressource L1 est le seul paramètre.

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

Les constructions L2 créées à partir des constructions L1 sont des objets proxy qui font référence à la ressource L1, similaires à ceux créés à partir de noms de ressources, d'ARN ou de recherches. Les modifications apportées à ces constructions n'affectent pas le AWS CloudFormation modèle synthétisé final (puisque vous disposez de la ressource L1, vous pouvez toutefois la modifier à la place). Pour plus d'informations sur les objets proxy, consultezRéférencement des ressources de votre compte AWS.

Pour éviter toute confusion, ne créez pas plusieurs constructions L2 faisant référence à la même construction L1. Par exemple, si vous extrayez le fichier CfnBucket d'un Bucket en utilisant la technique décrite dans la section précédente, vous ne devez pas créer une deuxième Bucket instance en appelant Bucket.fromCfnBucket() avec cette techniqueCfnBucket. Cela fonctionne réellement comme prévu (un seul AWS::S3::Bucket est synthétisé) mais cela rend votre code plus difficile à maintenir.

Dérogations brutes

Si certaines propriétés sont absentes de la construction L1, vous pouvez éviter toute saisie en utilisant des remplacements bruts. Cela permet également de supprimer des propriétés synthétisées.

Utilisez l'une des addOverride méthodes (Python :add_override), comme indiqué dans l'exemple suivant.

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

Ressources personnalisées

Si la fonctionnalité n'est pas disponible via un appel d'API direct AWS CloudFormation, mais uniquement via un appel d'API, vous devez écrire une ressource AWS CloudFormation personnalisée pour effectuer l'appel d'API dont vous avez besoin. Vous pouvez utiliser le AWS CDK pour écrire des ressources personnalisées et les intégrer dans une interface de construction normale. Du point de vue d'un consommateur de votre produit, l'expérience semblera native.

La création d'une ressource personnalisée implique l'écriture d'une fonction Lambda qui répond aux événements liés à une ressource et à son DELETE cycle de CREATE vie. UPDATE Si votre ressource personnalisée ne doit effectuer qu'un seul appel d'API, pensez à utiliser le AwsCustomResource. Cela permet d'effectuer des appels au SDK arbitraires lors d'un AWS CloudFormation déploiement. Sinon, vous devez écrire votre propre fonction Lambda pour effectuer le travail dont vous avez besoin.

Le sujet est trop vaste pour être traité dans son intégralité ici, mais les liens suivants devraient vous aider à démarrer :