如何用CDK实现TypeScript Lambda跨账号调用DynamoDB表
用AWS CDK实现跨账号Lambda访问DynamoDB表
账号A(拥有DDB表)的CDK实现
在账号A的CDK项目中,创建允许账号B扮演的IAM角色,并赋予其访问目标DDB表的权限:
import * as cdk from 'aws-cdk-lib'; import * as iam from 'aws-cdk-lib/aws-iam'; import * as dynamodb from 'aws-cdk-lib/aws-dynamodb'; import { Construct } from 'constructs'; export class AccountADdbStack extends cdk.Stack { // 暴露角色ARN给账号B使用 public readonly crossAccountRoleArn: string; constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // 关联已存在的DDB表,也可在此直接创建新表 const targetDdbTable = dynamodb.Table.fromTableArn(this, 'TargetDdbTable', 'arn:aws:dynamodb:us-east-1:ACCOUNT_A_ID:table/YourTableName' ); // 创建跨账号信任角色 const crossAccountRole = new iam.Role(this, 'CrossAccountDdbAccessRole', { assumedBy: new iam.AccountPrincipal('ACCOUNT_B_ID'), // 替换为账号B的实际ID description: '授权账号B的Lambda访问账号A的DDB表', // 不限制会话访问权限,因此不添加任何会话相关条件 }); // 为角色添加DDB操作权限(可按需调整为只读/只写等) crossAccountRole.addToPolicy(new iam.PolicyStatement({ actions: [ 'dynamodb:GetItem', 'dynamodb:PutItem', 'dynamodb:Scan', 'dynamodb:Query' ], resources: [targetDdbTable.tableArn], })); this.crossAccountRoleArn = crossAccountRole.roleArn; } }
账号B(部署Lambda)的CDK实现
在账号B的CDK项目中,创建Lambda函数并配置其可扮演账号A的角色:
1. Lambda执行角色配置
确保Lambda的执行角色拥有sts:AssumeRole权限,用于获取账号A角色的临时凭证:
import * as cdk from 'aws-cdk-lib'; import * as iam from 'aws-cdk-lib/aws-iam'; import * as lambda from 'aws-cdk-lib/aws-lambda'; import { Construct } from 'constructs'; export class AccountBLambdaStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // 替换为账号A中创建的跨账号角色ARN const accountACrossRoleArn = 'arn:aws:iam::ACCOUNT_A_ID:role/CrossAccountDdbAccessRole'; // 创建Lambda执行角色 const lambdaExecutionRole = new iam.Role(this, 'LambdaExecutionRole', { assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), managedPolicies: [ iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole') ] }); // 允许Lambda执行角色扮演账号A的角色 lambdaExecutionRole.addToPolicy(new iam.PolicyStatement({ actions: ['sts:AssumeRole'], resources: [accountACrossRoleArn] })); // 创建Lambda函数 const ddbAccessLambda = new lambda.Function(this, 'DdbAccessLambda', { runtime: lambda.Runtime.NODEJS_20_X, handler: 'index.handler', code: lambda.Code.fromAsset('lambda'), role: lambdaExecutionRole, environment: { CROSS_ACCOUNT_ROLE_ARN: accountACrossRoleArn, DDB_TABLE_NAME: 'YourTableName', DDB_REGION: 'us-east-1' } }); } }
2. Lambda业务代码示例
在Lambda代码包(lambda/index.js)中,通过STS获取临时凭证后访问账号A的DDB表:
const { STS, DynamoDB } = require('aws-sdk'); const sts = new STS(); const ddbRegion = process.env.DDB_REGION; exports.handler = async (event) => { // 扮演账号A的角色获取临时凭证 const assumeRoleResponse = await sts.assumeRole({ RoleArn: process.env.CROSS_ACCOUNT_ROLE_ARN, RoleSessionName: 'LambdaCrossAccountSession' }).promise(); // 使用临时凭证初始化DDB客户端 const ddb = new DynamoDB({ region: ddbRegion, accessKeyId: assumeRoleResponse.Credentials.AccessKeyId, secretAccessKey: assumeRoleResponse.Credentials.SecretAccessKey, sessionToken: assumeRoleResponse.Credentials.SessionToken }); // 示例:查询DDB表数据 const params = { TableName: process.env.DDB_TABLE_NAME, Key: { 'id': { S: 'example-id' } } }; const result = await ddb.getItem(params).promise(); return { statusCode: 200, body: JSON.stringify(result) }; };
关键注意事项
- 替换代码中的
ACCOUNT_A_ID、ACCOUNT_B_ID、YourTableName、us-east-1为实际值 - 需先部署账号A的CDK栈,获取角色ARN后再部署账号B的栈
- 可根据业务需求调整DDB的操作权限,比如仅保留
dynamodb:GetItem实现只读访问 - 因不限制会话访问权限,信任策略未添加
sts:SessionTag或sts:ExternalId等条件,请确保账号B的身份可信
内容的提问来源于stack exchange,提问作者kay
相关产品推荐
相关产品推荐

