Aller au contenu

Infrastructure CDK

AWS CDK est un framework permettant de définir une infrastructure cloud via du code et de la déployer via AWS CloudFormation.

Le générateur d’infrastructure TypeScript crée une application d’infrastructure AWS CDK écrite en TypeScript. L’application générée intègre des bonnes pratiques de sécurité grâce aux vérifications de Checkov.

Vous pouvez générer un nouveau projet d’infrastructure de deux manières :

  1. Installez le Nx Console VSCode Plugin si ce n'est pas déjà fait
  2. Ouvrez la console Nx dans VSCode
  3. Cliquez sur Generate (UI) dans la section "Common Nx Commands"
  4. Recherchez @aws/nx-plugin - ts#infra
  5. Remplissez les paramètres requis
    • Cliquez sur Generate
    Paramètre Type Par défaut Description
    name Requis string - The name of the application.
    directory string packages The directory of the new application.
    enableStageConfig boolean Enable centralized stage configuration (credentials, account, region) for multi-environment CDK deployments.

    Le générateur créera la structure de projet suivante dans le répertoire <directory>/<name> :

    • Répertoiresrc
      • main.ts Point d’entrée de l’application instanciant les stages CDK à déployer
      • Répertoirestages Définitions des stages CDK
        • application-stage.ts Définit un ensemble de stacks à déployer dans un stage
      • Répertoirestacks Définitions des stacks CDK
        • application-stack.ts Stack principale de l’application
    • cdk.json Configuration CDK
    • project.json Configuration du projet et cibles de build
    • checkov.yml Fichier de configuration Checkov

    Si vous activez l’option enableStageConfig, le générateur crée également deux packages partagés pour la gestion centralisée des credentials (s’ils n’existent pas déjà) :

    • Répertoirepackages/common
      • Répertoireinfra-config Types de configuration de stage et mappages de credentials
        • Répertoiresrc
          • stages.types.ts Définitions de types pour les credentials et config de stage
          • stages.config.ts Vos mappages stage-vers-credentials (à éditer)
          • index.ts Ré-exports pour l’import depuis d’autres packages
      • Répertoirescripts Scripts de déploiement/destruction centralisés
        • Répertoiresrc
          • infra-deploy.ts Script bin de déploiement
          • infra-destroy.ts Script bin de destruction
          • Répertoirestage-credentials/ Logique partagée (recherche de credentials, construction de commandes CDK)

    Vous pouvez commencer à écrire votre infrastructure CDK dans src/stacks/application-stack.ts, par exemple :

    src/stacks/application-stack.ts
    import { Stack, StackProps } from 'aws-cdk-lib';
    import { Bucket } from 'aws-cdk-lib/aws-s3'
    import { Construct } from 'constructs';
    export class ApplicationStack extends Stack {
    constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);
    // Déclarez votre infrastructure ici
    new Bucket(this, 'MyBucket');
    }
    }

    CDK utilise des Stages pour regrouper les stacks qui doivent être déployées ensemble dans un environnement spécifique. Le fichier src/main.ts généré crée un stage sandbox pour vos propres développements et tests :

    src/main.ts
    new ApplicationStage(app, 'my-app-sandbox', {
    env: {
    account: process.env.CDK_DEFAULT_ACCOUNT,
    region: process.env.CDK_DEFAULT_REGION,
    },
    });

    La propriété env indique à CDK vers quel compte AWS et quelle région déployer. CDK_DEFAULT_ACCOUNT et CDK_DEFAULT_REGION sont résolus automatiquement par la CLI CDK à partir de vos credentials AWS actifs. Consultez la documentation CDK sur les environnements pour plus de détails.

    Si vous avez généré avec enableStageConfig, le main.ts lit le compte et la région depuis un fichier de configuration centralisé, avec un repli sur les variables d’environnement lorsqu’aucune config n’est définie :

    src/main.ts (avec enableStageConfig)
    import stagesConfig from ':my-scope/common-infra-config';
    const projectStages = stagesConfig.projects?.['packages/infra']?.stages ?? {};
    const sandboxConfig = projectStages['my-app-sandbox'];
    new ApplicationStage(app, 'my-app-sandbox', {
    env: {
    account: sandboxConfig?.account ?? process.env.CDK_DEFAULT_ACCOUNT,
    region: sandboxConfig?.region ?? process.env.CDK_DEFAULT_REGION,
    },
    });

    Vous pouvez ajouter d’autres stages pour déployer vers différents environnements. Par exemple, des stages beta et prod ciblant des comptes AWS distincts :

    src/main.ts
    new ApplicationStage(app, 'project-beta', {
    env: {
    account: '123456789012',
    region: 'us-west-2',
    },
    });
    new ApplicationStage(app, 'project-prod', {
    env: {
    account: '098765432109',
    region: 'us-west-2',
    },
    });

    Un Stage regroupe une ou plusieurs stacks. Vous pouvez ajouter autant de stacks que nécessaire dans un stage :

    src/stages/application-stage.ts
    import { Stage, StageProps } from 'aws-cdk-lib';
    import { Construct } from 'constructs';
    import { BackendStack } from '../stacks/backend-stack.js';
    import { FrontendStack } from '../stacks/frontend-stack.js';
    export class ApplicationStage extends Stage {
    constructor(scope: Construct, id: string, props?: StageProps) {
    super(scope, id, props);
    new BackendStack(this, 'Backend', {
    crossRegionReferences: true,
    })
    new FrontendStack(this, 'Frontend', {
    crossRegionReferences: true,
    });
    }
    }

    Lorsque vous avez plusieurs stages ciblant différents comptes AWS, la gestion manuelle des credentials peut être source d’erreurs, en particulier à mesure que le nombre de stages augmente.

    L’option enableStageConfig résout ce problème en générant deux packages partagés :

    • packages/common/infra-config — Un fichier de configuration unique où vous mappez chaque stage à ses credentials AWS, compte et région. Il est importable depuis n’importe quel package de votre workspace, permettant à votre main.ts CDK de lire le compte et la région depuis la même source de vérité.
    • packages/common/scripts — Les commandes infra-deploy et infra-destroy qui encapsulent CDK avec une résolution automatique des credentials. Lorsque vous exécutez deploy, le script lit la configuration, définit les bonnes variables d’environnement AWS pour le processus enfant CDK, et exécute cdk deploy. Votre environnement shell n’est jamais modifié.

    Éditez packages/common/infra-config/src/stages.config.ts pour mapper vos stages aux credentials AWS :

    packages/common/infra-config/src/stages.config.ts
    import type { StagesConfig } from './stages.types.js';
    const config: StagesConfig = {
    projects: {
    // La clé est le chemin du projet relatif à la racine du workspace.
    // Cela correspond au chemin dans project.json et dans les commandes de déploiement.
    'packages/infra': {
    stages: {
    // Les noms de stage doivent correspondre aux identifiants de stage CDK dans main.ts
    // (le premier argument de `new ApplicationStage(app, 'my-app-dev', ...)`).
    'my-app-dev': {
    credentials: { type: 'profile', profile: 'dev-account' },
    region: 'us-east-1',
    },
    'my-app-prod': {
    credentials: {
    type: 'assumeRole',
    assumeRole: 'arn:aws:iam::123456789012:role/DeployRole',
    },
    region: 'us-west-2',
    account: '123456789012',
    },
    },
    },
    },
    shared: {
    // Les stages partagés sont disponibles pour tous les projets d'infrastructure.
    // Les entrées spécifiques au projet ont priorité sur les entrées partagées.
    stages: {
    sandbox: {
    credentials: { type: 'profile', profile: 'personal-sandbox' },
    region: 'us-east-1',
    },
    },
    },
    };
    export default config;

    Lorsque vous déployez, par exemple :

    Terminal window
    pnpm nx run infra:deploy my-app-dev/*

    Le script de déploiement :

    1. Extrait le nom du stage my-app-dev des arguments de la commande
    2. Recherche les credentials dans la config : d’abord sous projects['packages/infra'], puis sous shared
    3. S’ils sont trouvés, définit AWS_PROFILE (ou assume le rôle IAM) uniquement pour le processus enfant CDK
    4. S’ils ne sont pas trouvés, se replie sur les credentials AWS présents dans votre environnement

    Cela signifie que les workflows existants sans aucune config continuent de fonctionner — le script n’applique les credentials que lorsqu’il trouve une entrée correspondante.

    Deux stratégies de credentials sont supportées :

    • profile — Utilise un profil AWS CLI nommé depuis ~/.aws/config. Le script définit AWS_PROFILE pour le processus CDK.
    • assumeRole — Appelle STS AssumeRole avec l’ARN de rôle spécifié et transmet les credentials temporaires à CDK. Vous pouvez optionnellement spécifier un profile comme credentials source pour l’appel AssumeRole, un externalId pour les politiques de confiance inter-comptes, et une sessionDuration en secondes.

    Chaque configuration de stage inclut une region requise et un account optionnel :

    • region (requis) — La région AWS vers laquelle déployer (par exemple, us-east-1, eu-west-2).
    • account (optionnel) — L’ID du compte AWS. S’il est omis, CDK le déduit des credentials actifs au moment du déploiement. Consultez la documentation CDK sur les environnements pour comprendre comment CDK résout le compte et la région.

    Le main.ts généré lit ces valeurs depuis la config afin que la synthèse et le déploiement CDK utilisent les mêmes paramètres d’environnement :

    src/main.ts
    const sandboxConfig = projectStages['my-app-sandbox'];
    new ApplicationStage(app, 'my-app-sandbox', {
    env: {
    account: sandboxConfig?.account ?? process.env.CDK_DEFAULT_ACCOUNT,
    region: sandboxConfig?.region ?? process.env.CDK_DEFAULT_REGION,
    },
    });

    Les stages partagés (sous shared.stages) s’appliquent à n’importe quel projet d’infrastructure dans le workspace. C’est utile lorsque plusieurs projets déploient vers le même compte sandbox — vous définissez les credentials une seule fois au lieu de les répéter pour chaque projet.

    Les stages spécifiques au projet (sous projects['packages/infra'].stages) ne s’appliquent qu’à ce projet. Lorsque les deux existent pour le même nom de stage, l’entrée spécifique au projet a priorité.

    Si vous avez utilisé les générateurs tRPC API ou FastAPI pour créer des APIs, vous remarquerez que des constructs sont déjà disponibles dans packages/common/constructs pour les déployer.

    Si, par exemple, vous avez créé une API tRPC nommée my-api, vous pouvez simplement importer et instancier le construct pour ajouter toute l’infrastructure nécessaire pour la déployer :

    src/stacks/application-stack.ts
    import * as cdk from 'aws-cdk-lib';
    import { Construct } from 'constructs';
    import { MyApi } from ':my-scope/common-constructs';
    export class ApplicationStack extends cdk.Stack {
    constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    // Ajoutez l'infrastructure pour votre API
    new MyApi(this, 'MyApi', {
    integrations: MyApi.defaultIntegrations(this).build(),
    });
    }
    }

    Si vous avez utilisé le générateur site web CloudScape, vous remarquerez qu’un construct est déjà disponible dans packages/common/constructs pour le déployer. Par exemple :

    src/stacks/application-stack.ts
    import * as cdk from 'aws-cdk-lib';
    import { Construct } from 'constructs';
    import { MyWebsite } from ':my-scope/common-constructs';
    export class ApplicationStack extends cdk.Stack {
    constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    // Ajoutez l'infrastructure pour votre site web
    new MyWebsite(this, 'MyWebsite');
    }
    }

    Il est important de s’assurer que le site web est déclaré après les constructs d’API afin que la Configuration d’exécution du site web inclue toute la configuration des API.

    Dans le cadre de votre cible build, en plus de l’exécution des cibles par défaut de compilation, lint et test, votre projet d’infrastructure est synthétisé en CloudFormation. Cela peut également être exécuté de manière autonome, en exécutant la cible synth :

    Terminal window
    pnpm nx run <my-infra>:synth

    Vous trouverez votre assembly cloud synthétisée dans le dossier dist racine, sous dist/packages/<my-infra-project>/cdk.out.

    Une cible checkov est ajoutée à votre projet qui exécute des vérifications de sécurité sur votre infrastructure en utilisant Checkov.

    Terminal window
    pnpm nx run <my-infra>:checkov

    Vous trouverez les résultats de vos tests de sécurité dans le dossier dist racine, sous dist/packages/<my-infra-project>/checkov.

    Il peut y avoir des cas où vous souhaitez supprimer certaines règles sur des ressources. Vous pouvez le faire de deux manières :

    import { suppressRules } from ':my-scope/common-constructs';
    // supprime la règle CKV_AWS_XXX pour le construct donné.
    suppressRules(construct, ['CKV_AWS_XXX'], 'Raison');
    import { suppressRules } from ':my-scope/common-constructs';
    // Supprime la règle CKV_AWS_XXX pour le construct ou l'un de ses descendants s'il est une instance de Bucket
    suppressRules(construct, ['CKV_AWS_XXX'], 'Raison', (construct) => construct instanceof Bucket);

    Si vous déployez une application CDK sur un compte AWS pour la première fois, celui-ci devra être bootstrappé. Le bootstrap crée les ressources dont CDK a besoin pour gérer les déploiements (un bucket S3 pour les assets, des rôles IAM, etc.).

    Tout d’abord, assurez-vous d’avoir configuré les credentials pour votre compte AWS.

    Ensuite, exécutez la commande bootstrap pour chaque compte et région vers lesquels vous prévoyez de déployer :

    Fenêtre de terminal
    npx cdk bootstrap aws://<account-id>/<region>

    Pour plus de détails, veuillez vous référer à la documentation CDK sur le bootstrapping.

    Après un build, vous pouvez déployer votre infrastructure sur AWS en utilisant la cible deploy.

    Tout d’abord, assurez-vous d’avoir configuré les credentials AWS. Si vous avez généré avec enableStageConfig et avez configuré les credentials de stage dans packages/common/infra-config/src/stages.config.ts, la commande de déploiement résoudra et appliquera automatiquement les credentials corrects pour le stage cible. Sinon, assurez-vous que vos credentials AWS sont définis dans votre environnement (par exemple, via AWS_PROFILE ou des variables d’environnement). Consultez la documentation AWS sur les credentials pour les options disponibles.

    Ensuite, exécutez la cible de déploiement :

    Terminal window
    pnpm nx run <my-infra>:deploy <my-infra>-sandbox/*

    Utilisez la cible deploy-ci si vous déployez sur AWS dans le cadre d’un pipeline CI/CD.

    Terminal window
    pnpm nx run <my-infra>:deploy-ci my-stage/*

    Cette cible diffère légèrement de la cible deploy classique en ce qu’elle déploie une assembly cloud pré-synthétisée plutôt que de synthétiser à la volée. Cela évite un potentiel non-déterminisme dû aux changements de versions de packages, garantissant que chaque étape du pipeline déploie en utilisant la même assembly cloud.

    Utilisez la cible destroy pour supprimer vos ressources :

    Terminal window
    pnpm nx run <my-infra>:destroy <my-infra>-sandbox/*

    Pour plus d’informations sur CDK, veuillez vous référer au Guide développeur CDK et à la Référence API.