概要
AWS CDK v2.227.0では、IAM権限管理の一貫性を大幅に向上させる新しいGrantsパターンが導入されました。Step Functions、DynamoDB、S3の各サービスに専用のGrantsクラスが追加され、L1とL2コンストラクトの両方で統一された方法で権限を付与できるようになりました。また、L1コンストラクト(CloudFormation生成リソース)が既知のリソース関係でL2コンストラクトを直接パラメータとして受け入れられるようになり、コードの簡潔性が向上しています。
新機能
Step Functions: StateMachineGrantsクラスの追加
Step Functionsに新しいStateMachineGrantsクラスが追加され、ステートマシンへの権限付与をより柔軟に管理できるようになりました。
主な特徴:
- L1とL2の両方のステートマシンで統一された権限付与インターフェース
- 既存の
StateMachineクラスのgrant*()メソッドは内部的にこのクラスを使用
使用例:
import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
import * as iam from 'aws-cdk-lib/aws-iam';
// L2コンストラクトの場合
const stateMachine = new sfn.StateMachine(this, 'MyStateMachine', {
definitionBody: sfn.DefinitionBody.fromChainable(
new sfn.Pass(this, 'PassState')
),
});
const role = new iam.Role(this, 'MyRole', {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
});
// 従来の方法(引き続き利用可能)
stateMachine.grantStartExecution(role);
// 新しいGrantsクラスを直接使用する方法
StateMachineGrants._fromStateMachine(stateMachine).grantStartExecution(role);
// L1コンストラクトの場合も同様に使用可能
const cfnStateMachine = new sfn.CfnStateMachine(this, 'MyCfnStateMachine', {
roleArn: '...',
definitionString: '...',
});
StateMachineGrants._fromStateMachine(cfnStateMachine).grantStartExecution(role);
DynamoDB: TableGrantsとStreamGrantsクラスの追加
DynamoDBテーブルとストリームに対する権限管理のための新しいクラスが追加されました。
主な特徴:
TableGrants: テーブルへの読み取り/書き込み権限を統一的に管理StreamGrants: DynamoDB Streamsへの権限を管理- グローバルセカンダリインデックス(GSI)やローカルセカンダリインデックス(LSI)への権限も自動的に付与
- グローバルテーブルの複数リージョンに対応
IIndexableRegionalTableインターフェース:
export interface IIndexableRegionalTable extends ITableRef {
/**
* テーブルがレプリケートされている追加のリージョン
* @default リージョンなし
*/
readonly regions?: string[];
/**
* このテーブルがインデックスを持つかどうか
* trueの場合、すべてのテーブルインデックスにも権限が付与されます
* @default false
*/
readonly hasIndex?: boolean;
}
使用例:
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
import * as iam from 'aws-cdk-lib/aws-iam';
// L2コンストラクトの場合
const table = new dynamodb.Table(this, 'MyTable', {
partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
stream: dynamodb.StreamViewType.NEW_AND_OLD_IMAGES,
});
const role = new iam.Role(this, 'MyRole', {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
});
// 新しいGrantsクラスを使用した権限付与
// テーブルの読み取り権限を付与
table.grants.readData(role);
// テーブルの書き込み権限を付与
table.grants.writeData(role);
// テーブルの読み取り/書き込み両方の権限を付与
table.grants.readWriteData(role);
// DynamoDB Streamsへの権限を付与
table.streamGrants?.read(role); // streamが有効な場合のみ利用可能
// L1コンストラクトの場合
const cfnTable = new dynamodb.CfnTable(this, 'MyCfnTable', {
keySchema: [{ attributeName: 'id', keyType: 'HASH' }],
attributeDefinitions: [{ attributeName: 'id', attributeType: 'S' }],
billingMode: 'PAY_PER_REQUEST',
});
// L1でもGrantsクラスを使用可能
dynamodb.TableGrants._fromTable(cfnTable).readData(role);
グローバルテーブルとインデックスへの対応:
// グローバルテーブルの場合、複数リージョンに権限を付与
const globalTable = new dynamodb.Table(this, 'GlobalTable', {
partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
replicationRegions: ['us-west-2', 'eu-west-1'],
});
// 全リージョンのテーブルに対して権限が付与される
globalTable.grants.readData(role);
// GSIを持つテーブルの場合
const tableWithGSI = new dynamodb.Table(this, 'TableWithGSI', {
partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
});
tableWithGSI.addGlobalSecondaryIndex({
indexName: 'GSI1',
partitionKey: { name: 'gsi1pk', type: dynamodb.AttributeType.STRING },
});
// テーブルとすべてのインデックスに権限が付与される
tableWithGSI.grants.readData(role);
S3: BucketGrantsクラスの追加
S3バケットへの権限管理のための新しいBucketGrantsクラスが追加されました。
主な特徴:
- バケットへの読み取り/書き込み権限を統一的に管理
- L1とL2の両方のバケットで統一されたインターフェース
- パブリックアクセスの制御にも対応
使用例:
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as iam from 'aws-cdk-lib/aws-iam';
// L2コンストラクトの場合
const bucket = new s3.Bucket(this, 'MyBucket');
const role = new iam.Role(this, 'MyRole', {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
});
// 新しいGrantsクラスを使用した権限付与
// バケットの読み取り権限を付与
s3.BucketGrants._fromBucket(bucket).read(role);
// バケットの書き込み権限を付与
s3.BucketGrants._fromBucket(bucket).write(role);
// バケットの読み取り/書き込み両方の権限を付与
s3.BucketGrants._fromBucket(bucket).readWrite(role);
// 特定のオブジェクトキーパターンへの権限付与
s3.BucketGrants._fromBucket(bucket).read(role, 'prefix/*');
// バケットの削除権限を付与
s3.BucketGrants._fromBucket(bucket).delete(role);
// L1コンストラクトの場合
const cfnBucket = new s3.CfnBucket(this, 'MyCfnBucket');
// L1でもGrantsクラスを使用可能
s3.BucketGrants._fromBucket(cfnBucket).read(role);
// パブリックアクセスの付与
// 注: blockPublicAccessがfalseの場合のみ許可される
const publicBucket = new s3.Bucket(this, 'PublicBucket', {
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ACLS,
});
s3.BucketGrants._fromBucket(publicBucket).grantPublicAccess();
Core: L1コンストラクトでのL2コンストラクトパラメータサポート
L1コンストラクト(CloudFormation生成リソース)が、既知のリソース関係でL2コンストラクトを直接パラメータとして受け入れられるようになりました。これにより、L1とL2を混在させたコードがより自然に書けるようになります。
対応例:
import * as iam from 'aws-cdk-lib/aws-iam';
import * as lambda from 'aws-cdk-lib/aws-lambda';
// L2でロールを作成
const role = new iam.Role(this, 'MyRole', {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
});
// L1コンストラクトでL2のロールを直接使用可能
const cfnFunction = new lambda.CfnFunction(this, 'MyFunction', {
functionName: 'my-function',
runtime: 'nodejs20.x',
handler: 'index.handler',
// L2のRoleオブジェクトを直接指定できる
// 内部的にrole.roleArnに変換される
role: role, // 従来は role.roleArn を指定する必要があった
code: {
zipFile: 'exports.handler = async () => { return "Hello"; }',
},
});
// L2のLayerVersionを直接配列で指定
const layer = new lambda.LayerVersion(this, 'MyLayer', {
code: lambda.Code.fromAsset('layer'),
compatibleRuntimes: [lambda.Runtime.NODEJS_20_X],
});
const cfnFunction2 = new lambda.CfnFunction(this, 'MyFunction2', {
functionName: 'my-function-2',
runtime: 'nodejs20.x',
handler: 'index.handler',
role: role,
code: {
zipFile: 'exports.handler = async () => { return "Hello"; }',
},
// LayerVersionオブジェクトを直接配列で指定できる
layers: [layer], // 従来は [layer.layerVersionArn] を指定する必要があった
});
対応しているリソース関係の例:
- Lambda Function:
role(IAM Role)、layers(Layer Versions) - Lambda Function Code:
s3Bucket(S3 Bucket) - EventBridge Rule:
roleArn(IAM Role) - その他多数のCloudFormationリソースタイプ
内部動作:
// 生成されるコードの例(非ネストプロパティ)
this.role = (props.role as IamIRoleRef)?.roleRef?.roleArn ??
cdk.ensureStringOrUndefined(props.role, "role", "iam.IRoleRef | string");
// 複数の可能なリソースタイプがある場合
this.targetArn = (props.targetArn as SqsIQueueRef)?.queueRef?.queueArn ??
(props.targetArn as SnsITopicRef)?.topicRef?.topicArn ??
cdk.ensureStringOrUndefined(props.targetArn, "targetArn", "sqs.IQueueRef | sns.ITopicRef | string");
// 配列の場合
this.layers = (props.layers?.forEach((item, i, arr) => {
arr[i] = (item as ILayerVersionRef)?.layerVersionRef?.layerVersionArn ??
cdk.ensureStringOrUndefined(item, "layers", "lambda.ILayerVersionRef | string");
}), props.layers as Array<string>);
RDS: 新しいCloudWatchログエクスポートオプションのサポート
Amazon Aurora(MySQLおよびPostgreSQL)で新しく追加されたCloudWatchログエクスポートオプションがサポートされました。
追加されたログタイプ:
- Aurora MySQL:
instance、iam-db-auth-error - Aurora PostgreSQL:
instance、iam-db-auth-error
使用例:
import * as rds from 'aws-cdk-lib/aws-rds';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
const vpc = new ec2.Vpc(this, 'VPC');
// Aurora MySQLクラスタ
const mysqlCluster = new rds.DatabaseCluster(this, 'MySQLCluster', {
engine: rds.DatabaseClusterEngine.auroraMysql({
version: rds.AuroraMysqlEngineVersion.VER_3_05_2,
}),
writer: rds.ClusterInstance.provisioned('writer'),
vpc,
// 新しいログタイプを含むCloudWatchログエクスポート
cloudwatchLogsExports: [
'error', // エラーログ
'general', // 一般ログ
'slowquery', // スロークエリログ
'audit', // 監査ログ
'instance', // 新機能: インスタンスログ
'iam-db-auth-error', // 新機能: IAMデータベース認証エラーログ
],
cloudwatchLogsRetention: logs.RetentionDays.ONE_MONTH,
});
// Aurora PostgreSQLクラスタ
const postgresCluster = new rds.DatabaseCluster(this, 'PostgresCluster', {
engine: rds.DatabaseClusterEngine.auroraPostgres({
version: rds.AuroraPostgresEngineVersion.VER_15_4,
}),
writer: rds.ClusterInstance.provisioned('writer'),
vpc,
// PostgreSQL用のログエクスポート
cloudwatchLogsExports: [
'postgresql', // PostgreSQLログ
'instance', // 新機能: インスタンスログ
'iam-db-auth-error', // 新機能: IAMデータベース認証エラーログ
],
cloudwatchLogsRetention: logs.RetentionDays.ONE_MONTH,
});
ログタイプの詳細:
- instance: インスタンスレベルのログ(起動、シャットダウン、設定変更など)
- iam-db-auth-error: IAMデータベース認証の失敗ログ(セキュリティ監査に有用)
ファクトリメソッドを持つGrantsクラスの公開
各サービスのGrantsクラスのファクトリメソッドが公開され、より柔軟な権限管理が可能になりました。
対象クラス:
StateMachineGrants._fromStateMachine()TableGrants._fromTable()StreamGrants(コンストラクタ経由)BucketGrants._fromBucket()
これらのメソッドにより、L1とL2の両方のコンストラクトに対して統一されたインターフェースで権限を付与できます。
Alphaモジュールの新機能
Bedrock Agent Core: Gateway L2コンストラクト
Bedrock Agent CoreにGatewayとGateway Targetの新しいL2コンストラクトが追加されました。
主な機能:
- API GatewayとLambdaをBedrockエージェントのゲートウェイとして構成
- OpenAPI、Smithyスキーマのサポート
- 認証設定(IAM、OAuth、APIキー)
- 送信認証のクレデンシャルプロバイダー
使用例:
import * as bedrock from '@aws-cdk/aws-bedrock-agentcore-alpha';
import * as lambda from 'aws-cdk-lib/aws-lambda';
// Lambda関数を作成
const targetFunction = new lambda.Function(this, 'TargetFunction', {
runtime: lambda.Runtime.NODEJS_20_X,
handler: 'index.handler',
code: lambda.Code.fromAsset('lambda'),
});
// Bedrock Agent Core Gatewayを作成
const gateway = new bedrock.Gateway(this, 'MyGateway', {
gatewayName: 'my-api-gateway',
// 説明
description: 'API Gateway for Bedrock Agent',
// タグ
tags: {
Environment: 'production',
},
});
// Lambda関数をターゲットとして追加
gateway.addLambdaTarget('LambdaTarget', {
function: targetFunction,
// ツールスキーマを定義
toolSchema: {
name: 'getUserInfo',
description: 'Get user information by user ID',
inputSchema: {
type: 'object',
properties: {
userId: {
type: 'string',
description: 'The user ID',
},
},
required: ['userId'],
},
},
});
// OpenAPIスキーマを使用したターゲット
gateway.addOpenApiTarget('OpenApiTarget', {
apiSchemaPath: './schemas/user-api.json', // OpenAPI 3.0スキーマのパス
endpoint: 'https://api.example.com', // APIエンドポイント
// 認証設定
credentialProvider: bedrock.ApiKeyCredentialProvider.fromSecretsManager(
apiKeySecret, // Secrets ManagerシークレットARN
'api-key', // キー名
),
});
Image Builder: Component L2コンストラクト
EC2 Image BuilderのComponentコンストラクトが追加され、AMIビルドパイプラインのコンポーネントを定義できるようになりました。
主な機能:
- インライン、S3、ローカルアセットからのコンポーネントデータの読み込み
- ビルドとテストの両方のコンポーネントタイプをサポート
- 複数のOSバージョンとプラットフォームに対応
- KMS暗号化のサポート
使用例:
import * as imagebuilder from '@aws-cdk/aws-imagebuilder-alpha';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as kms from 'aws-cdk-lib/aws-kms';
// インラインでコンポーネントを定義
const inlineComponent = new imagebuilder.Component(this, 'InlineComponent', {
platform: imagebuilder.Platform.LINUX, // プラットフォーム
displayName: 'Install Docker', // 表示名
description: 'Install Docker on Amazon Linux 2', // 説明
version: '1.0.0', // バージョン
// インラインのYAMLコンポーネント定義
data: `
name: InstallDocker
description: Install Docker
schemaVersion: 1.0
phases:
- name: build
steps:
- name: InstallDocker
action: ExecuteBash
inputs:
commands:
- sudo yum update -y
- sudo amazon-linux-extras install docker -y
- sudo systemctl start docker
- sudo systemctl enable docker
`,
// サポートするOSバージョン
supportedOsVersions: [
imagebuilder.AmazonLinuxVersion.AMAZON_LINUX_2,
imagebuilder.AmazonLinuxVersion.AMAZON_LINUX_2023,
],
});
// S3からコンポーネントを読み込む
const bucket = s3.Bucket.fromBucketName(this, 'Bucket', 'my-component-bucket');
const s3Component = new imagebuilder.Component(this, 'S3Component', {
platform: imagebuilder.Platform.LINUX,
displayName: 'Install Security Tools',
description: 'Install security monitoring tools',
version: '1.0.0',
// S3バケットからデータを読み込む
dataUri: `s3://${bucket.bucketName}/components/security-tools.yaml`,
// KMS暗号化
kmsKey: new kms.Key(this, 'ComponentKey', {
enableKeyRotation: true,
}),
});
// ローカルアセットからコンポーネントを読み込む
const assetComponent = new imagebuilder.Component(this, 'AssetComponent', {
platform: imagebuilder.Platform.WINDOWS, // Windowsプラットフォーム
displayName: 'Configure Windows Settings',
description: 'Apply company Windows policies',
version: '2.0.0',
// ローカルファイルからアセットとして読み込む
dataUri: './components/windows-config.yaml',
// サポートするWindowsバージョン
supportedOsVersions: [
imagebuilder.WindowsVersion.WINDOWS_SERVER_2019,
imagebuilder.WindowsVersion.WINDOWS_SERVER_2022,
],
});
// テストコンポーネント
const testComponent = new imagebuilder.Component(this, 'TestComponent', {
platform: imagebuilder.Platform.LINUX,
displayName: 'Security Test',
description: 'Run security compliance tests',
version: '1.0.0',
data: `
name: SecurityTest
description: Test security compliance
schemaVersion: 1.0
phases:
- name: test
steps:
- name: CheckFirewall
action: ExecuteBash
inputs:
commands:
- sudo firewall-cmd --list-all
- test $(sudo firewall-cmd --query-service=ssh) = "yes"
`,
// 変更を不可能にする
changeDescription: 'Initial security test component',
});
サポートされるOSバージョン:
- Amazon Linux 2, 2023
- Ubuntu 18.04, 20.04, 22.04
- RHEL 7, 8, 9
- Windows Server 2012, 2016, 2019, 2022
Image Builder: Distribution Configuration L2コンストラクト
EC2 Image BuilderのDistribution Configurationコンストラクトが追加され、ビルドしたAMIやコンテナイメージの配布設定を定義できるようになりました。
主な機能:
- 複数リージョンへのAMI配布
- AMIの起動権限設定(アカウント、組織単位、組織全体)
- AMIタグとコピー時のタグ設定
- コンテナイメージのECR配布
- KMS暗号化のサポート
使用例:
import * as imagebuilder from '@aws-cdk/aws-imagebuilder-alpha';
import * as kms from 'aws-cdk-lib/aws-kms';
// KMSキーを作成
const kmsKey = new kms.Key(this, 'AMIKey', {
enableKeyRotation: true,
description: 'KMS key for AMI encryption',
});
// Distribution Configurationを作成
const distribution = new imagebuilder.DistributionConfiguration(
this,
'MyDistribution',
{
distributionConfigurationName: 'multi-region-distribution',
description: 'Distribute AMI to multiple regions',
// 配布設定の配列
distributions: [
{
// プライマリリージョン(us-east-1)
region: 'us-east-1',
// AMI配布設定
amiDistributionConfiguration: {
name: 'MyApp-{{ imagebuilder:buildDate }}', // AMI名(変数使用可能)
description: 'My application AMI', // AMI説明
// AMIタグ
amiTags: {
Application: 'MyApp',
Environment: 'production',
BuildDate: '{{ imagebuilder:buildDate }}',
},
// KMS暗号化
kmsKeyId: kmsKey.keyId,
// 起動権限: 特定のAWSアカウントに許可
launchPermissionConfiguration: {
userIds: ['123456789012', '234567890123'], // アカウントID
},
// ターゲットアカウントへのコピー設定
targetAccountIds: ['123456789012'],
},
},
{
// セカンダリリージョン(us-west-2)
region: 'us-west-2',
amiDistributionConfiguration: {
name: 'MyApp-{{ imagebuilder:buildDate }}',
description: 'My application AMI - West region',
amiTags: {
Application: 'MyApp',
Environment: 'production',
Region: 'us-west-2',
},
kmsKeyId: kmsKey.keyId,
// 組織全体に起動権限を付与
launchPermissionConfiguration: {
organizationArns: ['arn:aws:organizations::123456789012:organization/o-xxxxx'],
},
},
},
{
// ヨーロッパリージョン(eu-west-1)
region: 'eu-west-1',
amiDistributionConfiguration: {
name: 'MyApp-EU-{{ imagebuilder:buildDate }}',
description: 'My application AMI - EU region',
amiTags: {
Application: 'MyApp',
Environment: 'production',
Region: 'eu-west-1',
Compliance: 'GDPR',
},
// 組織単位に起動権限を付与
launchPermissionConfiguration: {
organizationalUnitArns: [
'arn:aws:organizations::123456789012:ou/o-xxxxx/ou-xxxxx',
],
},
},
},
],
}
);
// コンテナイメージの配布設定
const containerDistribution = new imagebuilder.DistributionConfiguration(
this,
'ContainerDistribution',
{
distributionConfigurationName: 'ecr-distribution',
description: 'Distribute container images to ECR',
distributions: [
{
region: 'us-east-1',
// コンテナ配布設定
containerDistributionConfiguration: {
targetRepository: {
repositoryName: 'my-app', // ECRリポジトリ名
service: 'ECR', // サービスタイプ
},
description: 'My containerized application',
// コンテナイメージタグ
containerTags: [
'latest',
'v1.0',
'{{ imagebuilder:buildDate }}',
],
},
},
],
}
);
// パブリックに公開する設定
const publicDistribution = new imagebuilder.DistributionConfiguration(
this,
'PublicDistribution',
{
distributionConfigurationName: 'public-distribution',
description: 'Public AMI distribution',
distributions: [
{
region: 'us-east-1',
amiDistributionConfiguration: {
name: 'PublicApp-{{ imagebuilder:buildDate }}',
description: 'Publicly available AMI',
amiTags: {
Public: 'true',
},
// パブリックに公開
launchPermissionConfiguration: {
userGroups: ['all'], // 全ユーザーに起動権限
},
},
},
],
}
);
起動権限の設定オプション:
userIds: 特定のAWSアカウントIDuserGroups: ユーザーグループ(allでパブリック)organizationArns: AWS Organizations全体organizationalUnitArns: 組織単位(OU)
AMI名で使用可能な変数:
{{ imagebuilder:buildDate }}: ビルド日時- その他のImage Builder変数
バグ修正
Bedrock Agent Core: Tokenプロパティの検証エラー修正
プロパティがTokenの場合に発生していた予期しない検証エラーが修正されました。CDKのTokenシステムを使用して動的な値を渡す際に問題が発生していましたが、この修正により正常に動作するようになりました。
破壊的変更
L1リソースの変更
aws-backup: AWS::Backup::LogicallyAirGappedBackupVaultのEncryptionKeyArn属性が削除されました。
この変更は、CloudFormationリソーススキーマの更新に伴うものです。Logically Air-Gapped Backup Vaultを使用している場合は、この属性への参照を削除する必要があります。
影響を受けるコード:
const vault = new backup.CfnLogicallyAirGappedBackupVault(this, 'Vault', {
// ... その他のプロパティ
});
// この属性は削除されました
// const keyArn = vault.attrEncryptionKeyArn; // エラー
移行方法:
EncryptionKeyArn属性への参照を削除し、必要に応じて別の方法でKMSキーARNを取得してください。
まとめ
AWS CDK v2.227.0は、IAM権限管理の一貫性と使いやすさを大幅に向上させるリリースです。新しいGrantsパターンにより、L1とL2コンストラクトの両方で統一されたインターフェースを使用できるようになりました。また、L1コンストラクトでL2コンストラクトを直接パラメータとして使用できるようになったことで、コードがより簡潔で読みやすくなります。
RDSの新しいCloudWatchログエクスポートオプションは、セキュリティ監査とトラブルシューティングに役立ちます。Alphaモジュールでは、Bedrock Agent CoreとEC2 Image Builderの新しいL2コンストラクトが追加され、これらのサービスをより簡単に利用できるようになりました。
既存のgrant*()メソッドは引き続き動作しますが、将来的に非推奨となる可能性があるため、新しいGrantsクラスの使用を検討することをお勧めします。L1リソースの破壊的変更は限定的ですが、AWS Backupのリソースを使用している場合は注意が必要です。