Salta ai contenuti

Infrastruttura CDK

AWS CDK è un framework per definire infrastrutture cloud tramite codice e provisionarle attraverso AWS CloudFormation.

Il generatore di infrastruttura TypeScript crea un’applicazione AWS CDK scritta in TypeScript. L’applicazione generata include best practice di sicurezza attraverso controlli Checkov.

Puoi generare un nuovo progetto di infrastruttura in due modi:

  1. Installa il Nx Console VSCode Plugin se non l'hai già fatto
  2. Apri la console Nx in VSCode
  3. Clicca su Generate (UI) nella sezione "Common Nx Commands"
  4. Cerca @aws/nx-plugin - ts#infra
  5. Compila i parametri richiesti
    • Clicca su Generate
    Parametro Tipo Predefinito Descrizione
    name Obbligatorio 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.

    Il generatore creerà la seguente struttura del progetto nella directory <directory>/<name>:

    • Directorysrc
      • main.ts Punto d’ingresso dell’applicazione che istanzia gli stage CDK da deployare
      • Directorystages Definizioni degli stage CDK
        • application-stage.ts Definisce una collezione di stack da deployare in uno stage
      • Directorystacks Definizioni degli stack CDK
        • application-stack.ts Stack applicativo principale
    • cdk.json Configurazione CDK
    • project.json Configurazione del progetto e target di build
    • checkov.yml File di configurazione Checkov

    Se imposti l’opzione enableStageConfig, il generatore crea anche due pacchetti condivisi per la gestione centralizzata delle credenziali (se non esistono già):

    • Directorypackages/common
      • Directoryinfra-config Tipi di configurazione degli stage e mappature delle credenziali
        • Directorysrc
          • stages.types.ts Definizioni dei tipi per credenziali e configurazione degli stage
          • stages.config.ts Le tue mappature stage-credenziali (modifica questo file)
          • index.ts Re-export per l’importazione da altri pacchetti
      • Directoryscripts Script centralizzati per deploy/destroy
        • Directorysrc
          • infra-deploy.ts Script bin per il deploy
          • infra-destroy.ts Script bin per il destroy
          • Directorystage-credentials/ Logica condivisa (ricerca credenziali, costruzione comandi CDK)

    Puoi iniziare a scrivere la tua infrastruttura CDK in src/stacks/application-stack.ts, ad esempio:

    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);
    // Dichiarare la propria infrastruttura qui
    new Bucket(this, 'MyBucket');
    }
    }

    CDK utilizza gli Stage per raggruppare stack che devono essere deployati insieme in un ambiente specifico. Il file src/main.ts generato crea uno stage sandbox per il tuo sviluppo e testing personale:

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

    La proprietà env indica a CDK su quale account AWS e regione eseguire il deploy. CDK_DEFAULT_ACCOUNT e CDK_DEFAULT_REGION vengono risolti automaticamente dalla CLI di CDK dalle tue credenziali AWS attive. Consulta la documentazione sugli ambienti CDK per maggiori dettagli.

    Se hai generato con enableStageConfig, il main.ts legge account e regione da un file di configurazione centralizzato, con fallback alle variabili d’ambiente quando non è impostata alcuna configurazione:

    src/main.ts (con 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,
    },
    });

    Puoi aggiungere altri stage per deployare su ambienti diversi. Ad esempio, stage beta e prod che puntano ad account AWS separati:

    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',
    },
    });

    Uno Stage raggruppa uno o più stack. Puoi aggiungere quanti stack desideri all’interno di uno 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,
    });
    }
    }

    Quando hai più stage che puntano a diversi account AWS, gestire le credenziali manualmente può essere soggetto a errori, specialmente man mano che il numero di stage cresce.

    L’opzione enableStageConfig risolve questo problema generando due pacchetti condivisi:

    • packages/common/infra-config — Un unico file di configurazione dove mappi ogni stage alle sue credenziali AWS, account e regione. Questo è importabile da qualsiasi pacchetto nel tuo workspace, quindi il tuo main.ts CDK può leggere account e regione dalla stessa fonte di verità.
    • packages/common/scripts — Comandi infra-deploy e infra-destroy che wrappano CDK con risoluzione automatica delle credenziali. Quando esegui deploy, lo script legge la configurazione, imposta le giuste variabili d’ambiente AWS per il processo figlio CDK ed esegue cdk deploy. Il tuo ambiente shell non viene mai modificato.

    Modifica packages/common/infra-config/src/stages.config.ts per mappare i tuoi stage alle credenziali AWS:

    packages/common/infra-config/src/stages.config.ts
    import type { StagesConfig } from './stages.types.js';
    const config: StagesConfig = {
    projects: {
    // La chiave è il path del progetto relativo alla root del workspace.
    // Questo corrisponde al path in project.json e nei comandi di deploy.
    'packages/infra': {
    stages: {
    // I nomi degli stage devono corrispondere agli identificatori degli stage CDK in main.ts
    // (il primo argomento di `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: {
    // Gli stage condivisi sono disponibili per tutti i progetti infra.
    // Le voci specifiche del progetto hanno priorità su quelle condivise.
    stages: {
    sandbox: {
    credentials: { type: 'profile', profile: 'personal-sandbox' },
    region: 'us-east-1',
    },
    },
    },
    };
    export default config;

    Quando esegui il deploy, ad esempio:

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

    Lo script di deploy:

    1. Estrae il nome dello stage my-app-dev dagli argomenti del comando
    2. Cerca le credenziali nella configurazione: prima sotto projects['packages/infra'], poi sotto shared
    3. Se trovate, imposta AWS_PROFILE (o assume il ruolo IAM) solo per il processo figlio CDK
    4. Se non trovate, ricade sulle credenziali AWS presenti nel tuo ambiente

    Questo significa che i workflow esistenti senza alcuna configurazione continuano a funzionare — lo script applica le credenziali solo quando trova una voce corrispondente.

    Sono supportate due strategie di credenziali:

    • profile — Utilizza un profilo AWS CLI denominato da ~/.aws/config. Lo script imposta AWS_PROFILE per il processo CDK.
    • assumeRole — Chiama STS AssumeRole con l’ARN del ruolo specificato e passa le credenziali temporanee a CDK. Puoi opzionalmente specificare un profile come credenziali sorgente per la chiamata AssumeRole, un externalId per policy di trust cross-account e una sessionDuration in secondi.

    Ogni configurazione di stage include una region obbligatoria e un account opzionale:

    • region (obbligatoria) — La regione AWS su cui deployare (es. us-east-1, eu-west-2).
    • account (opzionale) — L’ID dell’account AWS. Se omesso, CDK lo deduce dalle credenziali attive al momento del deploy. Consulta la documentazione sugli ambienti CDK per come CDK risolve account e regione.

    Il main.ts generato legge questi valori dalla configurazione in modo che sintesi e deployment CDK utilizzino le stesse impostazioni di ambiente:

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

    Gli stage condivisi (sotto shared.stages) si applicano a qualsiasi progetto infra nel workspace. Questo è utile quando più progetti deployano sullo stesso account sandbox — definisci le credenziali una volta invece di ripeterle per ogni progetto.

    Gli stage specifici del progetto (sotto projects['packages/infra'].stages) si applicano solo a quel progetto. Quando esistono entrambi per lo stesso nome di stage, la voce specifica del progetto ha priorità.

    Se hai usato i generatori tRPC API o FastAPI per creare API, noterai dei costrutti già disponibili in packages/common/constructs per deployarle.

    Se, ad esempio, hai creato un’API tRPC chiamata my-api, puoi semplicemente importare e istanziare il costrutto per aggiungere tutta l’infrastruttura necessaria per deployarla:

    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);
    // Aggiungi infrastruttura per la tua API
    new MyApi(this, 'MyApi', {
    integrations: MyApi.defaultIntegrations(this).build(),
    });
    }
    }

    Se hai usato il generatore CloudScape website, noterai di avere già un costrutto in packages/common/constructs per deployarlo. Ad esempio:

    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);
    // Aggiungi infrastruttura per il website
    new MyWebsite(this, 'MyWebsite');
    }
    }

    È importante assicurarsi che il website sia dichiarato dopo eventuali costrutti API in modo che il Runtime Config del website includa tutta la configurazione API.

    Come parte del target build, oltre all’esecuzione dei target predefiniti di compilazione, lint e test, il progetto di infrastruttura viene sintetizzato in CloudFormation. Questo può anche essere eseguito in modo autonomo, eseguendo il target synth:

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

    Troverai l’assembly cloud sintetizzato nella cartella dist principale, sotto dist/packages/<my-infra-project>/cdk.out.

    Un target checkov viene aggiunto al progetto che esegue controlli di sicurezza sull’infrastruttura usando Checkov.

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

    Troverai i risultati dei test di sicurezza nella cartella dist principale, sotto dist/packages/<my-infra-project>/checkov.

    Possono esserci casi in cui desideri sopprimere determinate regole su risorse specifiche. Puoi farlo in due modi:

    import { suppressRules } from ':my-scope/common-constructs';
    // sopprime la regola CKV_AWS_XXX per il costrutto dato.
    suppressRules(construct, ['CKV_AWS_XXX'], 'Motivazione');
    import { suppressRules } from ':my-scope/common-constructs';
    // Sopprime CKV_AWS_XXX per il costrutto o uno qualsiasi dei suoi discendenti se è un'istanza di Bucket
    suppressRules(construct, ['CKV_AWS_XXX'], 'Motivazione', (construct) => construct instanceof Bucket);

    Se stai deployando un’applicazione CDK su un account AWS per la prima volta, dovrà essere sottoposto a bootstrap. Il bootstrap crea le risorse di cui CDK ha bisogno per gestire i deployment (un bucket S3 per gli asset, ruoli IAM, ecc.).

    Prima, assicurati di aver configurato le credenziali per il tuo account AWS.

    Successivamente, esegui il comando bootstrap per ogni account e regione su cui intendi deployare:

    Terminal window
    npx cdk bootstrap aws://<account-id>/<region>

    Per maggiori dettagli, consulta la documentazione sul bootstrap di CDK.

    Dopo una build, puoi deployare la tua infrastruttura su AWS usando il target deploy.

    Prima, assicurati di avere le credenziali AWS configurate. Se hai generato con enableStageConfig e hai configurato le credenziali degli stage in packages/common/infra-config/src/stages.config.ts, il comando deploy risolverà e applicherà automaticamente le credenziali corrette per lo stage target. Altrimenti, assicurati che le tue credenziali AWS siano impostate nel tuo ambiente (ad esempio, tramite AWS_PROFILE o variabili d’ambiente). Consulta la documentazione sulle credenziali AWS per le opzioni disponibili.

    Poi esegui il target deploy:

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

    Usa il target deploy-ci se stai deployando su AWS come parte di una pipeline CI/CD.

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

    Questo target differisce leggermente dal normale target deploy in quanto deploya un assembly cloud pre-sintetizzato invece di sintetizzare al volo. Questo evita potenziali non-determinismi da cambiamenti nelle versioni dei pacchetti, assicurando che ogni fase della pipeline deploi usando lo stesso assembly cloud.

    Usa il target destroy per rimuovere le tue risorse:

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

    Per maggiori informazioni su CDK, consulta la CDK Developer Guide e l’API Reference.