はじめに
本記事は、私自身の備忘録を兼ねてAWS CDKをこれから始める方の一助になればと思い、AWS CDKの使い方等をまとめたものです。
今回は、AWS CDKを実行する際にCDKスタックにパラメータを渡してスタックやリソースの設定を制御する方法を確認しています。
なお、本記事は私自身の経験を基に記載していますが、間違いがあったらすみません。
CDKスタックにパラメータを渡したい状況
AWS CDKでリソースをデプロイする際にスタックにパラメータを渡したくなることがあります。
例えば、
・デプロイする環境を分けたい場合(例:dev、prodなど)
・デプロイするリージョンをパラメータで指定したい場合
などです。
もちろんコードにべた書きでも良いのですが、実行するたびにコードを書き換えるのも手間なので実行時にパラメータで渡せるようにする方法を確認します。
環境
本記事は以下の環境を使用して記載しています。
- AWS Cloud9
- AWS CDK:2.80.0
- Python: 3.10.11
- Node.js: 16.20.0
また、以下の記事に基づいてAWS CDKの環境を作成しています。
CDKスタックへパラメータを渡す方法
では、本題のCDKスタックへパラメータを渡す方法を確認します。今回は、環境を分けるパラメータとしてENV
を渡したいと思います。
スタックへパラメータを渡す方法は、2通りありますので、それぞれ確認していきます。
cdkコマンドで渡す方法
cdkコマンドでENV
を指定するのですが、まずはcdkコマンドで渡すパラメータをCDKのプログラムで受け取るところを確認します。
パラメータは、cdk.App().node.try_get_context("パラメータ名")
で受け取れます。
app.pyを以下のように変更してENV
パラメータを取得するようにしました。
取得したENV
パラメータをスタックをロードする際にスタック名に追加し、加えてスタックにパラメータとして渡すようにしています。
#!/usr/bin/env python3
import os
import aws_cdk as cdk
from cdk_app.cdk_app_stack import CdkAppStack
app = cdk.App()
# ↓↓ コマンドからパラメータを取得 ↓↓
param_env = app.node.try_get_context("ENV")
# ↑↑ コマンドからパラメータを取得 ↑↑
# ↓↓ スタック名に追加&パラメータで渡す ↓↓
CdkAppStack(app, "CdkAppStack-" + param_env,
param=param_env
)
# ↑↑ スタック名に追加&パラメータで渡す ↑↑
app.synth()
なお、スタックのプログラムは以下のようにS3バケットを作成するようになっていて、リソースの論理ID、S3バケットの名前にパラメータとして渡されたENV
パラメータを付けるようにしています。
from aws_cdk import (
Stack,
aws_s3 as s3,
RemovalPolicy
)
from constructs import Construct
class CdkAppStack(Stack):
def __init__(self, scope: Construct, construct_id: str, param_env, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
s3bucket = s3.Bucket(
self,
"MyS3Bucket-" + param_env,
bucket_name = "cdk-test-bucket-" + param_env,
removal_policy=RemovalPolicy.DESTROY
)
この状態でデプロイします。コマンドでパラメータを渡す際は-c パラメータ名=パラメータ値
を付けて実行します。ここでは、パラメータ値としてdev
を指定しました。
app.pyでENV
パラメータをスタックをロードする際にスタック名に追加したので、スタック名にdev
が付いていることが確認できます。
(.venv) user_name:~/environment/cdk-app (master) $ cdk deploy -c ENV=dev
✨ Synthesis time: 18.12s
(中略)
CdkAppStack-dev: deploying... [1/1]
CdkAppStack-dev: creating CloudFormation changeset...
✅ CdkAppStack-dev
✨ Deployment time: 36.81s
Stack ARN:
(中略)
✨ Total time: 54.93s
マネージメントコンソールでS3バケットを確認してみます。バケット名にもdev
が付いてますね。
今度は、パラメータ値としてprod
を指定して実行してみます。パラメータ値をスタック名に付けるようにしているので、先ほどとは別スタックとして起動することが確認できます。
(.venv) user_name:~/environment/cdk-app (master) $ cdk deploy -c ENV=prod
✨ Synthesis time: 17.4s
(中略)
CdkAppStack-prod: deploying... [1/1]
CdkAppStack-prod: creating CloudFormation changeset...
✅ CdkAppStack-prod
✨ Deployment time: 36.65s
Stack ARN:
(中略)
✨ Total time: 54.05s
再度、S3バケットを確認してみると、prod
が付いたバケットが追加されてました!
これで、cdkコマンドでパラメータを渡す方法が確認できました。次の確認をする前にS3バケットを削除しておきます。
(.venv) user_name:~/environment/cdk-app (master) $ cdk destroy -c ENV=dev
(.venv) user_name:~/environment/cdk-app (master) $ cdk destroy -c ENV=prod
コンテキスト変数で渡す方法
次にコンテキスト変数を利用してパラメータを取得します。コンテキスト変数は、CDKの設定ファイルであるcdk.jsonに設定します。cdk.json内の"context"
に"ENV": "dev"
を追加します。
{
"app": "python3 app.py",
"watch": {
"include": [
"**"
],
"exclude": [
"README.md",
"cdk*.json",
"requirements*.txt",
"source.bat",
"**/__init__.py",
"python/__pycache__",
"tests"
]
},
"context": {
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
"@aws-cdk/core:checkSecretUsage": true,
"@aws-cdk/core:target-partitions": [
"aws",
"aws-cn"
],
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
"@aws-cdk/aws-iam:minimizePolicies": true,
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
"@aws-cdk/core:enablePartitionLiterals": true,
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
"@aws-cdk/aws-iam:standardizedServicePrincipals": true,
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
"@aws-cdk/aws-route53-patters:useCertificate": true,
"@aws-cdk/customresources:installLatestAwsSdkDefault": false,
"@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
"@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
"@aws-cdk/aws-redshift:columnId": true,
"@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true,
"@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
"@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
"# comment": "# ↓↓ パラメータ追加 ↓↓",
"ENV": "dev",
"# comment": "# ↑↑ パラメータ追加 ↑↑"
}
}
コンテキスト変数で渡す場合もcdk.App().node.try_get_context("パラメータ名")
で受け取れるので、app.pyやcdk_app/cdk_app_stack.pyは先ほどのままです。
#!/usr/bin/env python3
import os
import aws_cdk as cdk
from cdk_app.cdk_app_stack import CdkAppStack
app = cdk.App()
# ↓↓ コマンドからパラメータを取得 ↓↓
param_env = app.node.try_get_context("ENV")
# ↑↑ コマンドからパラメータを取得 ↑↑
# ↓↓ スタック名に追加&パラメータで渡す ↓↓
CdkAppStack(app, "CdkAppStack-" + param_env,
param=param_env
)
# ↑↑ スタック名に追加&パラメータで渡す ↑↑
app.synth()
from aws_cdk import (
Stack,
aws_s3 as s3,
RemovalPolicy
)
from constructs import Construct
class CdkAppStack(Stack):
def __init__(self, scope: Construct, construct_id: str, param_env, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
s3bucket = s3.Bucket(
self,
"MyS3Bucket-" + param_env,
bucket_name = "cdk-test-bucket-" + param_env,
removal_policy=RemovalPolicy.DESTROY
)
この状態でデプロイします。
(.venv) user_name:~/environment/cdk-app (master) $ cdk deploy
マネージメントコンソールでS3バケットを確認してみます。バケット名にdev
が付きました。
これで、コンテキスト変数でパラメータを渡す方法が確認できました。S3バケットを削除しておきます。
(.venv) user_name:~/environment/cdk-app (master) $ cdk destroy
最後に、cdkコマンドとコンテキスト変数両方で同じパラメータ名に別のパラメータ値を渡すとどうなるか試してみます。
コンテキスト変数でENV
パラメータにdev
を指定した状態で、cdkコマンドでENV
パラメータにprod
を指定して実行します。
{
"app": "python3 app.py",
"watch": {
(中略)
},
"context": {
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
(中略)
"@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
"# comment": "# ↓↓ パラメータ追加 ↓↓",
"ENV": "dev",
"# comment": "# ↑↑ パラメータ追加 ↑↑"
}
}
(.venv) user_name:~/environment/cdk-app (master) $ cdk deploy -c ENV=prod
✨ Synthesis time: 15.92s
(中略)
CdkAppStack-prod: deploying... [1/1]
CdkAppStack-prod: creating CloudFormation changeset...
✅ CdkAppStack-prod
✨ Deployment time: 36.76s
Stack ARN:
(中略)
✨ Total time: 52.68s
デプロイするとCdkAppStack-prod
スタックが作成され、S3バケットにもprod
が付いてますね。cdkコマンドでの指定が優先されるようです。
まとめ
AWS CDKでスタックにパラメータを渡す方法を確認しました。用途によってcdkコマンドから渡す方法とコンテキスト変数で渡す方法と使い分ける必要がありそうですね。
最後まで読んでいただいてありがとうございます。
少しでも参考になれば幸いです。