Skip to content

CDK Infrastructure

AWS CDKは、クラウドインフラストラクチャをコードで定義し、AWS CloudFormationを通じてプロビジョニングするためのフレームワークです。

TypeScriptインフラストラクチャジェネレーターは、TypeScriptで記述されたAWS CDKインフラストラクチャアプリケーションを作成します。生成されたアプリケーションには、Checkovセキュリティチェックを通じたセキュリティのベストプラクティスが含まれています。

インフラストラクチャプロジェクトの生成

Section titled “インフラストラクチャプロジェクトの生成”

新しいインフラストラクチャプロジェクトは2つの方法で生成できます:

Terminal window
pnpm nx g @aws/nx-plugin:ts#infra
変更されるファイルを確認するためにドライランを実行することもできます
Terminal window
pnpm nx g @aws/nx-plugin:ts#infra --dry-run
パラメータデフォルト説明
name 必須string-アプリケーションの名前。
directory stringpackages新しいアプリケーションのディレクトリ。
subDirectory string-プロジェクトが配置されるサブディレクトリ。デフォルトではプロジェクト名になります。
stageConfig booleanマルチ環境CDKデプロイメント用の集中ステージ設定(認証情報、アカウント、リージョン)を有効にします。
preferInstallDependencies booleantrueジェネレーター実行後に依存関係のインストールを優先するかどうか。複数のジェネレーターをバッチ処理する際にインストールを延期する場合はfalseに設定します(後続のジェネレーターがNxプロジェクトグラフを計算できるよう、必要に応じてインストールは実行されます)。最後に一度だけインストールします。

ジェネレーターは<directory>/<name>ディレクトリに以下のプロジェクト構造を作成します:

  • Directorysrc
    • main.ts Application entry point instantiating CDK stages to deploy
    • Directorystages CDK Stage definitions
      • application-stage.ts Defines a collection of stacks to deploy in a stage
    • Directorystacks 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

stageConfigオプションを設定すると、ジェネレーターは集中的な認証情報管理のための2つの共有パッケージも作成します(まだ存在しない場合):

  • Directorypackages/common
    • Directoryinfra-config Stage configuration types and credential mappings
      • Directorysrc
        • 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
    • Directoryscripts Centralized deploy/destroy scripts
      • Directorysrc
        • infra-deploy.ts Deploy bin script
        • infra-destroy.ts Destroy bin script
        • Directorystage-credentials/ Shared logic (credential lookup, CDK command building)

CDKインフラストラクチャの実装

Section titled “CDKインフラストラクチャの実装”

src/stacks/application-stack.ts内でCDKインフラストラクチャの記述を開始できます。例えば:

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はStagesを使用して、特定の環境に一緒にデプロイすべきスタックをグループ化します。生成されたsrc/main.tsは、独自の開発とテストのためのサンドボックスステージを作成します:

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

envプロパティは、CDKにどのAWSアカウントとリージョンにデプロイするかを指示します。CDK_DEFAULT_ACCOUNTCDK_DEFAULT_REGIONは、アクティブなAWS認証情報からCDK CLIによって自動的に解決されます。詳細については、CDK環境のドキュメントを参照してください。

サンドボックスステージは、deploy-sandboxターゲットがデプロイするステージです。

stageConfigを使用して生成した場合、main.tsは環境変数にフォールバックする代わりに、集中管理された設定ファイルからアカウントとリージョンを読み取ります:

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

異なる環境にデプロイするために、さらにステージを追加できます。例えば、別々のAWSアカウントをターゲットとするbetaprodステージ:

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

ステージは1つ以上のスタックをグループ化します。ステージ内に必要なだけスタックを追加できます:

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

異なるAWSアカウントをターゲットとする複数のステージがある場合、認証情報を手動で管理することはエラーが発生しやすく、特にステージの数が増えるにつれてその傾向が強まります。

stageConfigオプションは、2つの共有パッケージを生成することでこれを解決します:

  • packages/common/infra-config — 各ステージをそのAWS認証情報、アカウント、リージョンにマッピングする単一の設定ファイル。これはワークスペース内の任意のパッケージからインポート可能なので、CDKのmain.tsは同じ信頼できる情報源からアカウントとリージョンを読み取ることができます。
  • packages/common/scripts — 自動認証情報解決を備えたCDKをラップするinfra-deployinfra-destroyコマンド。deployを実行すると、スクリプトは設定を読み取り、CDK子プロセスに適切なAWS環境変数を設定し、cdk deployを実行します。シェル環境は変更されません。

packages/common/infra-config/src/stages.config.tsを編集して、ステージを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;

デプロイする際、例えば:

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

デプロイスクリプトは:

  1. コマンド引数からステージ名my-app-devを抽出します
  2. 設定内で認証情報を検索します:最初にprojects['packages/infra']の下、次にsharedの下
  3. 見つかった場合、CDK子プロセスのみにAWS_PROFILEを設定します(またはIAMロールを引き受けます)
  4. 見つからなかった場合、環境内の既存のAWS認証情報にフォールバックします

これは、設定のない既存のワークフローが引き続き機能することを意味します — スクリプトは一致するエントリを見つけた場合にのみ認証情報を適用します。

2つの認証情報戦略がサポートされています:

  • profile~/.aws/configから名前付きAWS CLIプロファイルを使用します。スクリプトはCDKプロセスにAWS_PROFILEを設定します。
  • assumeRole — 指定されたロールARNでSTS AssumeRoleを呼び出し、一時的な認証情報をCDKに渡します。オプションで、AssumeRole呼び出しのソース認証情報としてprofile、クロスアカウント信頼ポリシー用のexternalId、および秒単位のsessionDurationを指定できます。

各ステージ設定には、必須のregionとオプションのaccountが含まれます:

  • region(必須) — デプロイ先のAWSリージョン(例:us-east-1eu-west-2)。
  • account(オプション) — AWSアカウントID。省略した場合、CDKはデプロイ時にアクティブな認証情報から推測します。CDKがアカウントとリージョンをどのように解決するかについては、CDK環境のドキュメントを参照してください。

生成されたmain.tsは、CDKの合成とデプロイが同じ環境設定を使用するように、これらの値を設定から読み取ります:

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

共有ステージとプロジェクト固有のステージ

Section titled “共有ステージとプロジェクト固有のステージ”

共有ステージ(shared.stagesの下)は、ワークスペース内の任意のインフラストラクチャプロジェクトに適用されます。これは、複数のプロジェクトが同じサンドボックスアカウントにデプロイする場合に便利です — 各プロジェクトで繰り返す代わりに、認証情報を一度定義します。

プロジェクト固有のステージ(projects['packages/infra'].stagesの下)は、そのプロジェクトにのみ適用されます。同じステージ名に対して両方が存在する場合、プロジェクト固有のエントリが優先されます。

tRPC APIまたはFastAPIジェネレーターを使用してAPIを作成した場合、それらをデプロイするためのいくつかのコンストラクトがpackages/common/constructsで既に利用可能であることに気付くでしょう。

例えば、my-apiというtRPC APIを作成した場合、コンストラクトをインポートしてインスタンス化するだけで、それをデプロイするために必要なすべてのインフラストラクチャを追加できます:

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

Webサイトインフラストラクチャ

Section titled “Webサイトインフラストラクチャ”

React Websiteジェネレーターを使用した場合、それをデプロイするためのコンストラクトがpackages/common/constructsに既にあることに気付くでしょう。例えば:

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

buildターゲットの一部として、デフォルトのコンパイル、リント、テストターゲットの実行に加えて、インフラストラクチャプロジェクトはCloudFormationに_合成_されます。これは、synthターゲットを実行することで、スタンドアロンの方法でも実行できます:

Terminal window
pnpm nx synth <my-infra>

合成されたクラウドアセンブリは、ルートのdistフォルダー内のdist/packages/<my-infra-project>/cdk.outにあります。

プロジェクトには、Checkovを使用してインフラストラクチャのセキュリティチェックを実行するcheckovターゲットが追加されます。

Terminal window
pnpm nx checkov <my-infra>

セキュリティテストの結果は、ルートのdistフォルダー内のdist/packages/<my-infra-project>/checkovにあります。

リソースに対して特定のルールを抑制したい場合があります。これは2つの方法で行うことができます:

特定のコンストラクトでルールを抑制する

Section titled “特定のコンストラクトでルールを抑制する”
import { suppressRules } from '@my-scope/common-constructs';
// suppresses the CKV_AWS_XXX for the given construct.
suppressRules(construct, ['CKV_AWS_XXX'], 'Reason');

子孫コンストラクトでルールを抑制する

Section titled “子孫コンストラクトでルールを抑制する”
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);

AWSアカウントのブートストラップ

Section titled “AWSアカウントのブートストラップ”

初めてAWSアカウントにCDKアプリケーションをデプロイする場合、ブートストラップする必要があります。ブートストラップは、CDKがデプロイを管理するために必要なリソース(アセット用のS3バケット、IAMロールなど)を作成します。

まず、AWSアカウントの認証情報を設定していることを確認してください。

次に、デプロイする予定の各アカウントとリージョンに対してブートストラップコマンドを実行します:

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

詳細については、CDKブートストラップのドキュメントを参照してください。

プロジェクトには3つのデプロイターゲットがあり、それぞれ異なる状況に適しています:

ターゲット使用目的
deploy-sandbox開発中に独自のサンドボックスステージをデプロイする。ステージ引数は不要。
deploy任意のステージをデプロイする。デプロイしたいステージまたはスタックを指定する。
deploy-ciCI/CDパイプラインからデプロイする。事前に合成されたクラウドアセンブリを使用する。

まず、AWS認証情報が設定されていることを確認してください。stageConfigを使用して生成し、packages/common/infra-config/src/stages.config.tsでステージ認証情報を設定している場合、デプロイコマンドはターゲットステージの正しい認証情報を自動的に解決して適用します。それ以外の場合は、環境にAWS認証情報が設定されていることを確認してください(例:AWS_PROFILEまたは環境変数経由)。利用可能なオプションについては、AWS認証情報のドキュメントを参照してください。

サンドボックスステージのデプロイ

Section titled “サンドボックスステージのデプロイ”

deploy-sandboxターゲットは、main.tsが宣言するサンドボックスステージをデプロイするため、ステージ名を覚えておく必要はありません:

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

これは、開発中にAWSでアプリケーションの独自のコピーを実行する最も迅速な方法です。

deployターゲットは、指定したステージまたはスタックをデプロイします。サンドボックス以外のステージや、単一のスタックをデプロイする場合に使用します:

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

main.tsで定義されている限り、任意のステージを指定できます。個別のスタックをデプロイするには、完全なスタック名を指定します:

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

CI/CDパイプラインでのAWSへのデプロイ

Section titled “CI/CDパイプラインでのAWSへのデプロイ”

CI/CDパイプラインの一部としてAWSにデプロイする場合は、deploy-ciターゲットを使用します。

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

このターゲットは、通常のdeployターゲットとは少し異なり、その場で合成するのではなく、事前に合成されたクラウドアセンブリをデプロイします。これにより、パッケージバージョンの変更による潜在的な非決定性を回避し、すべてのパイプラインステージが同じクラウドアセンブリを使用してデプロイすることを保証します。

AWSインフラストラクチャの削除

Section titled “AWSインフラストラクチャの削除”

リソースを削除するには、destroyターゲットを使用します:

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

CDKの詳細については、CDK開発者ガイドAPIリファレンスを参照してください。