AWS RAM でクロスアカウント共有されたパラメーターストアを AWS CDK で簡単に参照可能になりました

AWS RAM でクロスアカウント共有されたパラメーターストアを AWS CDK で簡単に参照可能になりました

Clock Icon2024.08.28

こんにちは、製造ビジネステクノロジー部の若槻です。

AWS CDK の最近のリリースで、下記のアップデートが追加されていました。

https://github.com/aws/aws-cdk/releases/tag/v2.154.0

ssm: support cross-account sharing (#30646) (1eb1ea6), closes #29292

アップデート内容としては、AWS RAM(AWS Resource Access Manager) でクロスアカウント共有された SSM パラメーターストアの AWS CDK での参照が StringParameter.fromStringParameterArn により簡単に可能になった、というものです。

今回は、あまり馴染みのない AWS RAM の挙動をコンソール上で確認しつつ、CDK でのアップデート内容について実際に試してみたいと思います。

試してみた

共有する側での RAM による Share の作成

共有する側の AWS アカウントにログインし、RAM のコンソールからパラメーターストアを共有する Share を作成します。

共有する側のアカウントに作成済みの、下記のパラメーターストアをクロスアカウント共有したいとします。制限として RAM で共有するパラメーターストアの Tier は Advanced である必要があります。

Share resource として上記パラメーターストア、Shared principal として共有先の AWS アカウント ID を指定した Share を RAM で作成します。

共有される側での Share の招待の受け入れ

先ほど Shared principal として指定した AWS アカウント ID のアカウントにログインし、RAM のコンソールから Share の招待を受け入れます。

Shared with me: Resource shares にアクセスすると、Pending ステータスで Share が表示されています。

Share の招待を受け入れます。

共有の正体の受け入れが完了しました。

このとき一瞬一覧から消えたので混乱しましたが、すぐに表示されました。今度はステータスが Active となっています。

そして共有されているパラメーターストが Shared with me: Shared resources に表示されるようになりました。この Resource ID は CDK コードで使用するので控えておきます。

ここで一度共有する側のコンソールに戻ると、Share のプリンシパルのステータスが先ほどまでの Pending から Associated に更新されていました。

CDK コード、動作確認

共有されたパラメーターストアを使用する以下の CDK コードを作成します。sharingParameterArn では先程控えた Resource ID を使用します。

lib/cdk-sample-stack.ts
import { aws_ssm as ssm, Stack, StackProps, CfnOutput } from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class CdkSampleStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps) {
    super(scope, id, props);

    const sharingAWSAccountId = process.env.SHARING_AWS_ACCOUNT_ID;

    const sharingParameterArn = `arn:aws:ssm:ap-northeast-1:${sharingAWSAccountId}:parameter/My/Parameter`;

    const sharedParam = ssm.StringParameter.fromStringParameterArn(
      this,
      'SharedParam',
      sharingParameterArn
    );

    new CfnOutput(this, 'SharedParamOutput', {
      value: sharedParam.stringValue,
    });
  }
}

デプロイ先は共有された側のアカウントとなります。

ここでスタックデプロイ前に CDK Diff を確認すると次のようにパラメーター参照が追加されていることが確認できます。クロスアカウント参照の場合にもリソースは特に作成されないんですね。

$ npx cdk diff
Stack CdkSampleStack
Hold on while we create a read-only change set to get a diff with accurate replacement information (use --no-change-set to use a less accurate but faster template-only diff)
Could not create a change set, will base the diff on template differences (run again with -v to see the reason)
Parameters
[+] Parameter SharedParam.Parameter SharedParamParameter: {"Type":"AWS::SSM::Parameter::Value<String>","Default":"arn:aws:ssm:ap-northeast-1:undefined:parameter/My/Parameter"}

Outputs
[+] Output SharedParamOutput SharedParamOutput: {"Value":{"Ref":"SharedParamParameter"}}

✨  Number of stacks with differences: 1

CDK デプロイをして実行時の出力を確認すると、Output でパラメーターの Value (shared value)を取得できていることが確認できます。

$ npm run deploy

> cdk_sample_app@0.1.0 deploy
> cdk deploy --require-approval never --method=direct

(中略)

Outputs:
CdkSampleStack.SharedParamOutput = shared value

共有される側で Share の脱退しようとしたら、エラーが発生した

ここで、共有される側のアカウントで Share の脱退しようとしたら、次のようにエラーが発生しました。

You cannot leave resource share arn:aws:ram:ap-northeast-1:XXXXXXXXXXXX:resource-share/60f0aab5-c521-4330-9a47-43e85e27c6e1. The share contains resources of the following resource types, which don't support this action: [ssm:Parameter]. Contact the resource share owner to be removed from the share.

一度共有を受け入れたら、共有した側のみしか Share の削除ができないようです。

共有する側で Share を削除してみる

Share を共有する側のアカウントで Share を削除してみると、これは正常に削除できました。

すると削除後は共有される側でも Share が表示されなくなりました。

また先程の CDK の実装を再度デプロイをしてみると、ちゃんとパラメーターストアの取得権限が無い旨のエラーになりました。

npm run deploy

> cdk_sample_app@0.1.0 deploy
> cdk deploy --require-approval never --method=direct

✨  Synthesis time: 3.63s

CdkSampleStack: deploying... [1/1]
CdkSampleStack: updating stack...

 ❌  CdkSampleStack failed: Error [ValidationError]: User: arn:aws:sts::XXXXXXXXXXXX:assumed-role/cdk-hnb659fds-cfn-exec-role-XXXXXXXXXXXX-ap-northeast-1/AWSCloudFormation is not authorized to perform: ssm:GetParameters on resource: arn:aws:ssm:ap-northeast-1:XXXXXXXXXXXX:parameter/My/Parameter because no resource-based policy allows the ssm:GetParameters action (Service: AWSSimpleSystemsManagement; Status Code: 400; Error Code: AccessDeniedException; Request ID: e4ea08cd-ca3d-4158-b8c4-bf1ce1513058; Proxy: null)
    at Request.extractError (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/aws-cdk/lib/index.js:396:46717)
    at Request.callListeners (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/aws-cdk/lib/index.js:396:91771)
    at Request.emit (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/aws-cdk/lib/index.js:396:91219)
    at Request.emit (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/aws-cdk/lib/index.js:396:199820)
    at Request.transition (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/aws-cdk/lib/index.js:396:193373)
    at AcceptorStateMachine.runTo (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/aws-cdk/lib/index.js:396:158245)
    at /Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/aws-cdk/lib/index.js:396:158575
    at Request.<anonymous> (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/aws-cdk/lib/index.js:396:193665)
    at Request.<anonymous> (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/aws-cdk/lib/index.js:396:199895)
    at Request.callListeners (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/aws-cdk/lib/index.js:396:91939) {
  code: 'ValidationError',
  time: 2024-08-28T13:16:24.878Z,
  requestId: 'b22a00fe-e667-49c2-a416-fa1acb7c44cc',
  statusCode: 400,
  retryable: false,
  retryDelay: 382.3103595921336
}

おわりに

AWS RAM でクロスアカウント共有されたパラメーターストアを AWS CDK で簡単に参照可能になったので、実際に試してみました。

カスタムリソースを作り込むことなく、使い慣れたメソッドだけでパラメーターストアのクロスアカウント参照が可能になるのはなかなか嬉しいですね。

以上

この記事をシェアする

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.