You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

跨AWS账户共享SecureString类型SSM参数解密值的问题

跨账户传递SSM SecureString解密值解决方案

问题原因

你拿到的{{resolve:ssm-secure:/CodeBuild/key:1}}是CDK/CloudFormation的延迟解析占位符——CDK在合成模板阶段不会解密SSM参数,而是把解析任务留给CloudFormation部署时处理。但跨账户场景下,CloudFormation默认没有权限访问AccountA的SSM参数,导致无法解析出实际值。

解决步骤

1. 配置AccountA的权限,允许AccountB访问

1.1 给SSM SecureString参数添加资源策略

在AccountA的CDK代码中,为目标SSM参数添加跨账户访问策略,允许AccountB的部署角色执行ssm:GetParameter和kms:Decrypt操作:

import * as ssm from 'aws-cdk-lib/aws-ssm';
import * as iam from 'aws-cdk-lib/aws-iam';

// AccountA中创建的SecureString参数
const secureParam = new ssm.StringParameter(this, 'CodeBuildKey', {
  parameterName: '/CodeBuild/key',
  stringValue: 'your-actual-secret',
  type: ssm.ParameterType.SECURE_STRING,
});

// 添加跨账户访问策略
secureParam.addToResourcePolicy(new iam.PolicyStatement({
  actions: ['ssm:GetParameter', 'kms:Decrypt'],
  principals: [new iam.AccountPrincipal('ACCOUNT_B_ID')], // 替换为AccountB的实际ID
  resources: [secureParam.parameterArn],
}));

1.2 配置KMS密钥权限(如果用了自定义KMS密钥)

如果你的SSM参数是用自定义KMS密钥加密的,还需要给该KMS密钥添加权限,允许AccountB的角色解密:

import * as kms from 'aws-cdk-lib/aws-kms';

const customKmsKey = new kms.Key(this, 'CustomKey');
customKmsKey.addToResourcePolicy(new iam.PolicyStatement({
  actions: ['kms:Decrypt'],
  principals: [new iam.AccountPrincipal('ACCOUNT_B_ID')],
  resources: ['*'],
}));

2. 正确在Code Pipeline中传递参数

在AccountA的Code Pipeline部署Action中,直接传递SecretValue.ssmSecure类型的参数,不要试图提前解密:

import * as codepipeline_actions from 'aws-cdk-lib/aws-codepipeline-actions';
import * as cdk from 'aws-cdk-lib';

const deployToAccountB = new codepipeline_actions.CloudFormationCreateUpdateStackAction({
  actionName: 'Deploy_AccountB_Stack',
  stackName: 'AccountB-Target-Stack',
  templatePath: buildArtifact.atPath('cdk.out/AccountBStack.template.json'),
  parameterOverrides: {
    // 直接传递SecretValue,让CloudFormation在AccountB部署时解析
    SecretParam: cdk.SecretValue.ssmSecure('/CodeBuild/key', '1'),
  },
  account: 'ACCOUNT_B_ID',
  region: 'us-east-1',
  // 可指定自定义跨账户部署角色,确保权限足够
});

3. 在AccountB的栈中接收并使用解密值

在AccountB的CDK栈中,用SecretValue类型接收参数,在需要使用的地方通过unsafeUnwrap()传递(CloudFormation会在部署时替换为实际解密值):

import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';

export class AccountBStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props: cdk.StackProps & { secretValue: cdk.SecretValue }) {
    super(scope, id, props);

    // 示例:将解密值传递给Lambda环境变量
    new lambda.Function(this, 'SecretUsingLambda', {
      runtime: lambda.Runtime.NODEJS_18_X,
      handler: 'index.handler',
      code: lambda.Code.fromAsset('lambda-code'),
      environment: {
        SECRET_KEY: props.secretValue.unsafeUnwrap(),
      },
    });
  }
}

关键注意点

  • 不要在CDK代码中尝试提前解密(比如unsafeUnwrap()在CDK合成阶段不会得到实际值,只会保留占位符),必须让CloudFormation在部署阶段解析。
  • 确保Code Pipeline的执行角色或部署Action的角色,以及AccountB的CloudFormation部署角色,都有对应的权限访问AccountA的SSM参数和KMS密钥。

内容的提问来源于stack exchange,提问作者dossani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 09:25:06