AWS CDK, L’Infrastructure as Real Code sur AWS

Lors du Re-invent 2018, AWS a annoncé la sortie d’AWS CDK (Cloud development Kit) en version preview, un framework opensource qui permet d’utiliser des langages de programmation modernes pour définir et provisionner de l’infrastructure AWS (connu sous Infrastructure as Code).

Tandis que d’autres solutions d’infrastructure as Code utilisent des fichiers de configuration JSON/YAML ou d’autres languages spécifique comme HCL terraform, AWS CDK nous permet d'écrire de l’infrastructure programmable avec des vrais langages qu’on utilise au quotidien dans une approche impérative.

AWS CDK est écrit en Typescript et utilise JSII afin de créer des clients pour d’autres langages. Aujourd'hui, AWS CDK supporte TypeScript, JavaScript, Python, Java et C#/.NET.

# Quelques notions de base

AWS CDK permet aux développeurs d’adopter le concept d’infrastructure programmable à l’aide d’un modèle objet, puis de le synthétiser dans des templates CloudFormation afin d'approvisionner les ressources en toute fluidité.

Dans le contexte CDK, on utilise la notion de construct qui représente un composant Cloud et encapsule tout ce dont AWS CloudFormation a besoin pour créer la ressource. C’est le composant de base pour construire une application AWS CDK.

Un Construct peut représenter une ressource (un bucket S3 ou une queue SQS) ou un composant de haut-niveau qui consiste en plusieurs ressources CDK.

archi_aws_cdk

AWS CDK inclut une AWS Construct Library qui contient les constructs représentant les ressources AWS. Dans cette librairie, il existe différents niveaux de constructs :

Les constructs de bas niveau nommés ressources CFN (en référence à CloudFormation) représentent toutes les ressources AWS disponibles dans AWS CloudFormation. Leurs noms commencent par Cfn suivi du nom de la ressource. Par exemple, s3.CfnBucket représente la ressource Cloudformation AWS::S3::Bucket. En utilisant, les ressources CFN, on doit explicitement configurer toutes les propriétés de la ressource.

Un deuxième niveau de construct plus élevé représente également des ressources AWS mais gère les détails et la logique d'agrégation demandés par les constructs CFN. Il n’y pas besoin de connaître tous les détails de la ressource. Ces constructs fournissent des valeurs par défaut à tous les paramètres non remplis et des méthodes pour pouvoir manipuler la ressource assez facilement.

Enfin, un niveau de construct encore plus haut appelé patterns. Ce sont des constructs qui permettent de réaliser des tâches complexes impliquant plusieurs ressources AWS à la fois. Par exemple, le construct aws-apigateway.LambdaRestApi représente une Amazon API Gateway + une lambda avec toutes les configurations nécessaires.

Toutefois, il est toujours possible que vous ne retrouvez pas l’une des propriétés ou fonctionnalités spécifique à un service AWS dans les constructs de base ou de haut niveau. Ceci peut s’expliquer par l’une des raisons suivantes:

  • La propriété est disponible sur CloudFormation, mais la classe du construct n’est pas encore disponible.

  • La propriété est disponible sur CloudFormation, les classes du construct sont aussi disponibles, mais la propriété n’est pas exposé.

  • Le service n’est pas encore disponible sur CloudFormation

# Structure d’une app AWS CDK

Dans le contexte AWS CDK, un construct de très haut niveau peut être composé de plusieurs constructs de bas niveau qui à leur tour, peuvent être composés de plusieurs constructs de niveau plus bas. En conséquence, on peut se retrouver avec une hiérarchie de constructs encapsulés entre eux nommée construct tree. La racine de ce construct tree représente votre application AWS CDK.

Une application peut être composée d’une ou plusieurs stacks. Par analogie avec les stacks CloudFormation, ce sont des unités de déploiement qui définissent des ressources par le biais des constructs comme représenté ci dessous.

app_tree

Regardons ce que ça donne maintenant au niveau du code. L’exemple suivant montre la création d’une API Gateway + une Lambda + une table DynamoDB et avec toutes les configurations nécessaires en 42 lignes.

import apigateway = require('@aws-cdk/aws-apigateway'); 
import dynamodb = require('@aws-cdk/aws-dynamodb');
import lambda = require('@aws-cdk/aws-lambda');
import cdk = require('@aws-cdk/core');

export class ApiLambdaAddItemDynamoDBStack extends cdk.Stack {
  constructor(app: cdk.App, id: string) {
    super(app, id);

    const dynamoTable = new dynamodb.Table(this, 'items', {
      partitionKey: {
        name: 'itemId',
        type: dynamodb.AttributeType.STRING
      },
      tableName: 'items'
      });

    const createItem = new lambda.Function(this, 'createItemFunction', {
      code: new lambda.AssetCode('src'),
      handler: 'create.handler',
      runtime: lambda.Runtime.NODEJS_10_X,
      environment: {
        TABLE_NAME: dynamoTable.tableName,
        PRIMARY_KEY: 'itemId'
      }
    });

    dynamoTable.grantReadWriteData(createItem);

    const api = new apigateway.RestApi(this, 'itemsApi', {
      restApiName: 'Items Service'
    });

    const items = api.root.addResource('items');
    const createOneIntegration = new apigateway.LambdaIntegration(createItem);
    items.addMethod('POST', createOneIntegration);
  }
}

const app = new cdk.App();
new ApiLambdaAddItemDynamoDBStack(app, 'ApiLambdaAddItemDynamoDBExample');
app.synth();

A partir de ça, on génére un template Cloudformation de 337 lignes.

# Quelques avantages d’AWS CDK

Moins de lignes de code
Avec AWS CDK, vous pouvez écrire beaucoup moins de lignes comparé à CloudFormation par exemple. Si vous essayez d'écrire un VPC avec toutes les configurations requises, vous n’êtes pas loin de 1000 lignes en JSON/YAML alors que vous pouvez faire la même chose en 50 lignes avec AWS CDK.

Votre langage préféré
AWS CDK supporte votre langage préféré : TypeScript, JavaScript, Python, Java et C#/.NET. Ceci dit, on peut utiliser toutes les techniques de programmation classique dans une approche orienté-objet pour écrire de l'infrastructure, sans avoir besoin d’apprendre une nouvelle syntaxe spécifique (comme pour Terraform). De plus, on peut tester, modulariser notre code et réutiliser nos constructs ou ceux de la communauté pour une meilleure productivité.

Utilisation des boucles
Avec d’autres outils d'infra-as-code, c'est très compliqué de définir des conditions/boucles (if, for ...) pour définir notre infrastructure (surtout avec CloudFormation). Maintenant avec AWS CDK, ca devient trivial grâce à votre langage de programmation préféré.

Une CLI très pratique
AWS CDK débarque avec une interface en ligne de commande assez puissante pour faciliter toutes nos manipulations. Avec AWS CDK CLI, vous pouvez générer des templates Cloudformation, suivre et afficher les différences avec les anciens déploiements, initialiser/déployer/détruire votre application.

Les tests
L’une des bonnes pratiques aujourd'hui est d'écrire des tests de notre infrastructure programmable. Avec AWS CDK, vous pouvez exécuter différentes classes de tests de votre infrastructure et avec des outils de tests qu’on utilise d’habitude (Jest par exemple si vous utilisez JS/TS). La seule chose qui diffère par rapport aux tests classiques sont les assertions. AWS CDK débarque avec sa propre libraire d’assertions @aws-cdk/Assert afin de faciliter les assertions sur votre infrastructure, et vous pouvez très bien intégrer ces tests à votre pipeline CI/CD.
D’autres outils d’infra-as-code permettent aussi de faire des tests de votre code, Par exemple TaskCat pour Cloudformation ou TerraTest pour Terraform. Mais ceci implique l’ajout et l'apprentissage d’un outil supplémentaire.

Extensibilité
L’extensibilité est l’une des forces majeures d’AWS CDK. Le fait de modulariser, créer des composants réutilisables constitue un avantage majeur dans le monde de l’IaC.
De plus, on peut définir naturellement nos propres règles de compliance adaptées à nos entreprises ou de bonne pratiques (exemple buckets S3 cryptés par défaut avec la bonne clé KMS). Si on veut aussi aller plus loin, on peut écrire des constructs de haut niveau qui définissent des use cases précis, des règles de compliance ou des design patterns cloud-native et les partager très facilement avec les équipes de développement.

# AWS CDK vs Autres Outils

AWS CDK n’est pas la première solution qui permet d’utiliser un langage de programmation classique pour générer des templates Cloudformation. Des outils comme Pulumi ou Troposphere permettent également de le faire.
Mais ce qui différencie AWS CDK par rapport à ces outils, c’est le fort niveau d’abstraction. AWS CDK s'intègre complètement avec les ressources AWS et synthétise automatiquement des configurations de ressources clés comme les policies IAM, les groupes de sécurité ou les configurations réseau. Par exemple, pour ajouter un VPC à votre infrastructure, vous avez seulement à ajouter cette simple ligne dans votre code

new ec2.VpcNetwork(this, ‘MyVPC’)

Après compilation, vous générez un template CloudFormation avec tous les détails renseignés (sous-réseaux, tables routages, régions, zones de disponibilités …). et si l’une des valeurs ne vous convient pas, vous avez des méthodes pour la paramétrer assez facilement.

# Conclusion

AWS CDK nous offre de nouvelles perspectives dans l'écriture de l’infrastructure AWS. Le fait d’utiliser son langage préféré, écrire des tests d’infrastructure et écrire des lignes de code facilement réutilisables constitue un avantage remarquable pour écrire votre infrastructure sur AWS.
Sachant que AWS CDK est toujours en évolution, Il est important de noter que quelques classes de constructs AWS ne sont pas encore disponibles (ou en version preview) sur l’AWS Construct Library. Donc si vous êtes convaincu, essayez-le et comparez-le avec votre expérience sur d’autres outils d’IaC.

# Pour bien commencer

Quelques références pour bien commencer son expérience AWS CDK.