Aller au contenu

Infrastructure CDK

AWS CDK est un framework permettant de définir l’infrastructure cloud en code et de la provisionner 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 inclut les meilleures pratiques de sécurité grâce aux vérifications de sécurité Checkov.

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

Terminal window
pnpm nx g @aws/nx-plugin:ts#infra
Vous pouvez également effectuer une simulation pour voir quels fichiers seraient modifiés
Terminal window
pnpm nx g @aws/nx-plugin:ts#infra --dry-run
ParamètreTypePar défautDescription
name Requisstring-Le nom de l'application.
directory stringpackagesLe répertoire de la nouvelle application.
subDirectory string-Le sous-répertoire dans lequel le projet est placé. Par défaut, il s'agit du nom du projet.
stageConfig booleanActive la configuration centralisée des stages (identifiants, compte, région) pour les déploiements CDK multi-environnements.
preferInstallDependencies booleantrueIndique s'il faut privilégier l'installation des dépendances après l'exécution du générateur. Définir sur false pour différer l'installation lors de l'exécution de plusieurs générateurs en lot (une installation s'exécute quand même si nécessaire pour que les générateurs suivants puissent calculer le graphe de projet Nx) ; installer une seule fois à la fin.

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

  • Répertoiresrc
    • main.ts Application entry point instantiating CDK stages to deploy
    • Répertoirestages CDK Stage definitions
      • application-stage.ts Defines a collection of stacks to deploy in a stage
    • Répertoirestacks CDK Stack definitions
      • application-stack.ts Main application stack
  • cdk.json CDK configuration
  • package.json Project manifest defining the project’s package name and dependencies
  • project.json Project configuration and build targets
  • checkov.yml Checkov configuration file

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

  • Répertoirepackages/common
    • Répertoireinfra-config Stage configuration types and credential mappings
      • Répertoiresrc
        • stages.types.ts Type definitions for stage credentials and config
        • stages.config.ts Your stage-to-credential mappings (edit this)
        • index.ts Re-exports for importing from other packages
    • Répertoirescripts Centralized deploy/destroy scripts
      • Répertoiresrc
        • infra-deploy.ts Deploy bin script
        • infra-destroy.ts Destroy bin script
        • Répertoirestage-credentials/ Shared logic (credential lookup, CDK command building)

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);
// Declare your infrastructure here
new Bucket(this, 'MyBucket');
}
}

CDK utilise les 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 votre propre développement et test :

src/main.ts
new ApplicationStage(app, 'my-app-sandbox', {
env: {
account: process.env.CDK_DEFAULT_ACCOUNT,
region: process.env.CDK_DEFAULT_REGION,
},
});
// Define other instances of stages, such as beta and prod, below

La propriété env indique à CDK dans 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 identifiants AWS actifs. Consultez la documentation sur les environnements CDK pour plus de détails.

Le stage sandbox est celui que la cible deploy-sandbox déploie.

Si vous avez généré avec stageConfig, le fichier main.ts lit le compte et la région à partir d’un fichier de configuration centralisé, en se repliant sur les variables d’environnement lorsqu’aucune configuration n’est définie :

src/main.ts (with stageConfig)
import { resolveStage } from '@my-scope/common-infra-config';
// Looks up the stage under this project (packages/infra), falling back to
// shared stages. Returns undefined when no config exists for the stage.
const sandboxConfig = resolveStage('packages/infra', '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 dans différents environnements. Par exemple, des stages beta et prod ciblant des comptes AWS séparés :

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 identifiants peut être sujette aux erreurs, surtout à mesure que le nombre de stages augmente.

L’option stageConfig 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 identifiants AWS, compte et région. Ceci est importable depuis n’importe quel package de votre workspace, de sorte que votre main.ts CDK peut lire le compte et la région à partir de 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 identifiants. 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é.

Modifiez packages/common/infra-config/src/stages.config.ts pour mapper vos stages aux identifiants AWS :

packages/common/infra-config/src/stages.config.ts
import type { StagesConfig } from './stages.types.js';
const config: StagesConfig = {
projects: {
// The key is the project path relative to the workspace root.
// This matches the path in project.json and in deploy commands.
'packages/infra': {
stages: {
// Stage names must match the CDK stage identifiers in main.ts
// (the first argument to `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: {
// Shared stages are available to all infra projects.
// Project-specific entries take priority over shared ones.
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 deploy infra 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 identifiants dans la configuration : 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 identifiants AWS présents dans votre environnement

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

Deux stratégies d’identifiants sont prises en charge :

  • 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 identifiants temporaires à CDK. Vous pouvez éventuellement spécifier un profile comme identifiants 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 identifiants actifs au moment du déploiement. Consultez la documentation sur les environnements CDK pour savoir comment CDK résout le compte et la région.

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

src/main.ts
const sandboxConfig = resolveStage('packages/infra', '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. Ceci est utile lorsque plusieurs projets déploient vers le même compte sandbox — vous définissez les identifiants une fois au lieu de les répéter pour chaque projet.

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

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

Si, par exemple, vous avez créé une API tRPC appelé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 { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { MyApi } from '@my-scope/common-constructs';
export class ApplicationStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// Add infrastructure for your API
new MyApi(this, 'MyApi', {
integrations: MyApi.defaultIntegrations(this).build(),
});
}
}

Si vous avez utilisé le générateur React Website, vous remarquerez que vous avez déjà un construct dans packages/common/constructs pour le déployer. Par exemple :

src/stacks/application-stack.ts
import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { MyWebsite } from '@my-scope/common-constructs';
export class ApplicationStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// Add infrastructure for your website
new MyWebsite(this, 'MyWebsite');
}
}

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

Terminal window
pnpm nx synth <my-infra>

Vous trouverez votre assemblage cloud synthétisé 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 checkov <my-infra>

Vous trouverez vos résultats de 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';
// suppresses the CKV_AWS_XXX for the given construct.
suppressRules(construct, ['CKV_AWS_XXX'], 'Reason');
import { suppressRules } from '@my-scope/common-constructs';
// Supresses the CKV_AWS_XXX for the construct or any of its descendants if it is an instance of Bucket
suppressRules(construct, ['CKV_AWS_XXX'], 'Reason', (construct) => construct instanceof Bucket);

Si vous déployez une application CDK vers un compte AWS pour la première fois, il devra être bootstrappé. Le bootstrapping 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 identifiants 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 sur le bootstrapping CDK.

Votre projet dispose de trois cibles de déploiement, chacune adaptée à une situation différente :

CibleUtilisez-la pour
deploy-sandboxDéployer votre propre stage sandbox pendant le développement. Aucun argument de stage nécessaire.
deployDéployer n’importe quel stage, en nommant le stage ou les stacks que vous voulez.
deploy-ciDéployer depuis un pipeline CI/CD, en utilisant un assemblage cloud pré-synthétisé.

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

La cible deploy-sandbox déploie le stage sandbox que main.ts déclare, vous n’avez donc pas besoin de vous souvenir de son nom de stage :

Terminal window
pnpm nx deploy-sandbox <my-infra>

C’est le moyen le plus rapide d’obtenir votre propre copie de l’application en cours d’exécution dans AWS pendant que vous développez.

La cible deploy déploie le stage ou les stacks que vous nommez. Utilisez-la pour les stages autres que votre sandbox, ou pour déployer une seule stack :

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

Vous pouvez spécifier n’importe quel stage tant qu’il est défini dans main.ts. Pour déployer une stack individuelle, donnez le nom complet de la stack :

Terminal window
pnpm nx deploy <my-infra> <my-infra>-sandbox/Application

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

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

Cette cible diffère légèrement de la cible deploy normale en ce qu’elle déploie un assemblage cloud pré-synthétisé plutôt que de synthétiser à la volée. Cela évite le non-déterminisme potentiel des changements de version de package, garantissant que chaque étape du pipeline déploie en utilisant le même assemblage cloud.

Utilisez la cible destroy pour détruire vos ressources :

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

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