使用TS CDK配置跨账号SES:DEV账号Lambda无法调用ROOT账号SES问题
跨AWS账号使用SES服务的解决方案
问题根源
DEV账号的Lambda虽然附加了AmazonSESFullAccess托管策略,但该策略仅允许操作当前账号内的SES资源。由于你的SES身份托管在ROOT账号下,必须在ROOT账号的SES资源上显式授权DEV账号的Lambda角色,才能实现跨账号访问。
步骤1:在ROOT账号的SesStack中添加跨账号权限
修改SesStack代码,给SES Email Identity添加资源策略,允许DEV账号的Lambda角色调用SES发送邮件等核心操作:
import * as cdk from 'aws-cdk-lib'; import * as ses from 'aws-cdk-lib/aws-ses'; import * as iam from 'aws-cdk-lib/aws-iam'; import { Construct } from 'constructs'; import { ROOT_DOMAIN } from '../../iamphoto.constants'; export class SesStack extends cdk.Stack { public constructor(scope: Construct, props: cdk.StackProps) { super(scope, SesStack.name, props); const emailIdentity = new ses.EmailIdentity(this, 'Identity', { identity: ses.Identity.domain(ROOT_DOMAIN) }); // 替换为实际的DEV账号ID和Lambda角色ARN const devAccountId = 'YOUR_DEV_ACCOUNT_ID'; const devLambdaRoleArn = `arn:aws:iam::${devAccountId}:role/emails-function-role-xxx`; // 给SES身份添加跨账号访问权限 emailIdentity.addToResourcePolicy(new iam.PolicyStatement({ effect: iam.Effect.ALLOW, principals: [new iam.ArnPrincipal(devLambdaRoleArn)], actions: [ 'ses:SendEmail', 'ses:SendRawEmail', 'ses:SendTemplatedEmail' // 根据业务需求添加其他需要的SES操作 ], resources: [emailIdentity.identityArn] })); } }
步骤2:优化DEV账号Lambda的权限(可选但推荐)
AmazonSESFullAccess权限范围过大,建议替换为自定义策略,仅允许访问ROOT账号的目标SES资源,降低权限风险:
// 移除原有的托管策略添加代码,替换为以下自定义策略 nodejsFunction.addToRolePolicy(new iam.PolicyStatement({ effect: iam.Effect.ALLOW, actions: [ 'ses:SendEmail', 'ses:SendRawEmail', 'ses:SendTemplatedEmail' ], resources: [`arn:aws:ses:eu-central-1:YOUR_ROOT_ACCOUNT_ID:identity/${ROOT_DOMAIN}`] }));
步骤3:验证Lambda调用逻辑
确保Lambda代码中调用SES时,指定的区域与SES身份所在区域一致,且发件地址是ROOT账号中已验证的身份:
// Lambda核心代码示例 import { SESClient, SendEmailCommand } from "@aws-sdk/client-ses"; const sesClient = new SESClient({ region: process.env.SES_REGION }); export const handler = async () => { const params = { Source: process.env.SES_EMAIL_FROM, Destination: { ToAddresses: ['recipient@example.com'] }, Message: { Subject: { Data: '跨账号SES测试邮件' }, Body: { Text: { Data: '这是来自DEV账号Lambda的跨账号SES邮件' } } } }; try { const response = await sesClient.send(new SendEmailCommand(params)); console.log('邮件发送成功:', response); return { statusCode: 200, body: '邮件发送成功' }; } catch (error) { console.error('邮件发送失败:', error); return { statusCode: 500, body: '邮件发送失败' }; } };
内容的提问来源于stack exchange,提问作者Juraj Zovinec
相关产品推荐
相关产品推荐

