AWS CDK でパラメーターストアから値を取得する 2 つのメソッド valueForStringParameter と valueFromLookup の挙動の違いを確認してみた

AWS CDK でパラメーターストアから値を取得する 2 つのメソッド valueForStringParameter と valueFromLookup の挙動の違いを確認してみた

Clock Icon2025.01.29

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

AWS CDK で Systems Manager Parameter Store から値を取得するメソッドには、valueForStringParametervalueFromLookup があります。

https://docs.aws.amazon.com/ja_jp/cdk/v2/guide/get_ssm_value.html

今回は、AWS CDK におけるこれら 2 つのメソッドの挙動の違いを確認してみた

やってみた

取得元のパラメーターストアの事前作成

次のように S3 バケットの ARN を保存するパラメーターストアを作成します。ARN をスタック間で受け渡すことを想定した実装です。

lib/main-2-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as ssm from 'aws-cdk-lib/aws-ssm';

export class Main2Stack extends cdk.Stack {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    // S3 バケット作成
    const bucket = new s3.Bucket(this, 'MyBucket');

    // SSM パラメータにバケット ARN を保存
    new ssm.StringParameter(this, 'MyBucketArn', {
      parameterName: '/myapp/mybucket-arn',
      stringValue: bucket.bucketArn,
    });
  }
}

valueForStringParameter で取得する場合

valueForStringParameter は、CDK のデプロイ時にパラメーターストアの値を取得します。

https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ssm.StringParameter.html#static-valuewbrforwbrstringwbrparameterscope-parametername-version

CDK コードは次のようになります。取得した値が解決できているか確認するため ARN を使用したバケットオブジェクトを取得まで行っています。

lib/main-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as ssm from 'aws-cdk-lib/aws-ssm';

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

    // SSM パラメータからバケット ARN を取得
    const bucketArn = ssm.StringParameter.valueForStringParameter(
      this,
      '/myapp/mybucket-arn'
    );

    // バケット ARN からバケットオブジェクトを取得
    const bucket = s3.Bucket.fromBucketArn(this, 'MyBucket', bucketArn);

    // 以下、バケットを使った処理
    // ...
  }
}

CDK Deploy を実行すると、正常にデプロイを行うことができました。

valueFromLookup で取得する場合

valueFromLookup は、CDK の合成(Synth)時にパラメーターストアの値を取得します。

https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ssm.StringParameter.html#static-valuewbrfromwbrlookupscope-parametername-defaultvalue

CDK コードは次のようになります。先程と同様に取得した ARN を使用したバケットオブジェクトを取得まで行っています。

lib/main-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as ssm from 'aws-cdk-lib/aws-ssm';

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

    // SSM パラメータからバケット ARN を取得
    const bucketArn = ssm.StringParameter.valueFromLookup(
      this,
      '/myapp/mybucket-arn'
    );

    // バケット ARN からバケットオブジェクトを取得
    const bucket = s3.Bucket.fromBucketArn(this, 'MyBucket', bucketArn);

    // 以下、バケットを使った処理
    // ...
  }
}

CDK Synth をするとまずは次のエラーが発生しました。合成時は通常はアカウントとリージョンの指定は必要ありませんが、合成時に値を決定する FromLookup 系の処理は指定をする必要があるからです。

Error: Cannot retrieve value from context provider ssm since account/region are not specified at the stack level. Configure "env" with an account and region when you define your stack.See https://docs.aws.amazon.com/cdk/latest/guide/environments.html for more details.

次のようにスタックの props で Environment を指定するようにします。

bin/cdk_sample_app.ts
new MainStack(app, 'Main', {
  // Environment を指定
  env: {
    account: process.env.CDK_DEFAULT_ACCOUNT,
    region: process.env.CDK_DEFAULT_REGION,
  },
});

再度 CDK Synth をすると今度は次のエラーが発生しました。fromBucketArn で ARN 形式でないダミー値が使われてしまっているようです。解決前の値が一時的に入ってしまうのでしょうか。

Error: ARNs must start with "arn:" and have at least 6 components: dummy-value-for-/myapp/mybucket-arn

デバッグのために取得した Bucket Arn を使用した処理 (fromBucketArn) を一時的にコメントアウトします。

diff --git a/lib/main-stack.ts b/lib/main-stack.ts
index 4e07c01..4279368 100644
--- a/lib/main-stack.ts
+++ b/lib/main-stack.ts
@@ -13,8 +13,8 @@ export class MainStack extends cdk.Stack {
       '/myapp/mybucket-arn'
     );

-    // バケット ARN からバケットオブジェクトを取得
-    const bucket = s3.Bucket.fromBucketArn(this, 'MyBucket', bucketArn);
+    // // バケット ARN からバケットオブジェクトを取得
+    // const bucket = s3.Bucket.fromBucketArn(this, 'MyBucket', bucketArn);

     // 以下、バケットを使った処理
     // ...

再度 CDK Synth をするとエラーなく実行されました。また cdk.context.json にパラメーターの値が保存されました。

cdk.context.json
{
  "ssm:account=XXXXXXXXXXXX:parameterName=/myapp/mybucket-arn:region=ap-northeast-1": "arn:aws:s3:::main2-mybucketf68f3ff0-xntujkq2kxig"
}

fromBucketArn のコメントアウトを解除します。

diff --git a/lib/main-stack.ts b/lib/main-stack.ts
index 4279368..4e07c01 100644
--- a/lib/main-stack.ts
+++ b/lib/main-stack.ts
@@ -13,8 +13,8 @@ export class MainStack extends cdk.Stack {
       '/myapp/mybucket-arn'
     );

-    // // バケット ARN からバケットオブジェクトを取得
-    // const bucket = s3.Bucket.fromBucketArn(this, 'MyBucket', bucketArn);
+    // バケット ARN からバケットオブジェクトを取得
+    const bucket = s3.Bucket.fromBucketArn(this, 'MyBucket', bucketArn);

     // 以下、バケットを使った処理
     // ...

再度 CDK Synth をするとエラーなく実行されました。cdk.context.json に保存された値が fromBucketArn で使われたようです。

おわりに

AWS CDK でパラメーターストアから値を取得する 2 つのメソッド valueForStringParameter と valueFromLookup の挙動の違いを確認してみました。

valueForStringParameter はデプロイのたびに値が決定されます。valueFromLookup は合成時に値を決定されますが、一度 cdk.context.json に値をキャッシュする必要がある場合があります。

パラメーターストアに保存した値のライフサイクルや、キャッシュの利用有無によって使い分けるようにすると良さそうです。

参考

https://dev.classmethod.jp/articles/aws-cdk-ssm-secrets-manager/

以上

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.