AWS CDK でパラメーターストアから値を取得する 2 つのメソッド valueForStringParameter と valueFromLookup の挙動の違いを確認してみた
こんにちは、製造ビジネステクノロジー部の若槻です。
AWS CDK で Systems Manager Parameter Store から値を取得するメソッドには、valueForStringParameter
と valueFromLookup
があります。
今回は、AWS CDK におけるこれら 2 つのメソッドの挙動の違いを確認してみた
やってみた
取得元のパラメーターストアの事前作成
次のように S3 バケットの ARN を保存するパラメーターストアを作成します。ARN をスタック間で受け渡すことを想定した実装です。
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 のデプロイ時にパラメーターストアの値を取得します。
CDK コードは次のようになります。取得した値が解決できているか確認するため ARN を使用したバケットオブジェクトを取得まで行っています。
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)時にパラメーターストアの値を取得します。
CDK コードは次のようになります。先程と同様に取得した ARN を使用したバケットオブジェクトを取得まで行っています。
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 を指定するようにします。
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
にパラメーターの値が保存されました。
{
"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 に値をキャッシュする必要がある場合があります。
パラメーターストアに保存した値のライフサイクルや、キャッシュの利用有無によって使い分けるようにすると良さそうです。
参考
以上