Secrets ManagerとParameter Store
Secrets Managerでデータベース認証情報を自動的にローテーションし、秘密ではない設定をParameter Storeに保存して、両方をLambdaとECSに統合します。
「Secrets ManagerとParameter Store」はCoddyKit上の無料AWS Solutions Architectレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAWS Solutions Architect学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 AWS Solutions Architectコースには全4レッスンが含まれています。
コードにシークレットを保存する問題
データベースのパスワード、API キー、OAuth トークンなどのシークレットを、アプリケーションのソースコード、環境変数、またはバージョン管理システムに登録する設定ファイルに保存することは、一般的で危険なアンチパターンです。これらのリポジトリが誤って公開されたり、攻撃者にアクセスされたりすると、すべてのシークレットが直ちに漏洩します。AWS には、この問題を解消する 2 つのマネージドサービスがあります。自動ローテーションが必要な認証情報には AWS Secrets Manager、設定値やローテーションしないシークレットには AWS Systems Manager Parameter Storeを使用します。
# Anti-pattern: secrets in code (NEVER do this)
# db_password = 'supersecret123'
# api_key = 'sk-abc123def456'
# Best practice: retrieve at runtime
import boto3
client = boto3.client('secretsmanager', region_name='us-east-1')
response = client.get_secret_value(SecretId='prod/myapp/db-password')
password = response['SecretString'] # fresh value, always currentAWS Secrets Manager の概要
AWS Secrets Managerは、シークレットの保存、取得、自動ローテーションを行うマネージドサービスです。すべてのシークレットを KMS で暗号化します(デフォルトでは AWS 管理キーを使用しますが、CMK も使用できます)。シークレットには、キーと値で構成される JSON 文字列として、任意の構造化データを保存できます。Secrets Manager の料金は、シークレット 1 件につき月額 0.40 ドル、API 呼び出し 10,000 回につき 0.05 ドルです。Parameter Store との主な違いは、自動ローテーションが組み込まれていることです。RDS、Redshift、DocumentDB、カスタムシークレットについて、Lambda ローテーション関数を使用して自動ローテーションできます。ローテーション中にアプリケーションを変更する必要はありません。
# Create a secret in Secrets Manager
aws secretsmanager create-secret \
--name 'prod/myapp/database' \
--description 'Production MySQL credentials' \
--secret-string '{"username":"admin","password":"changeme123","host":"mydb.rds.amazonaws.com","port":3306,"dbname":"orders"}'
# Retrieve the secret (by application)
aws secretsmanager get-secret-value \
--secret-id 'prod/myapp/database' \
--query 'SecretString' \
--output text | python3 -c 'import sys,json; s=json.load(sys.stdin); print(s["password"])'Secrets Managerによる自動ローテーション
自動ローテーションは、Secrets Managerの最も強力な機能です。RDSデータベースの場合、Secrets Managerは次の手順でパスワードをネイティブにローテーションします。1) 新しいパスワードを生成します。2) RDSのデータベースユーザーのパスワードを更新します。3) 新しいパスワードでシークレットを更新します。4) 新しい認証情報が機能することを検証します。これらはすべてアプリケーションの稼働中に行われるため、ダウンタイムも手動操作も発生しません。アプリケーションは常にget-secret-valueを呼び出して現在のパスワードを取得するため、ローテーション後の認証情報を自動的に使用します。
# Enable automatic rotation for RDS secret
aws secretsmanager rotate-secret \
--secret-id 'prod/myapp/database' \
--rotation-rules AutomaticallyAfterDays=30 \
--rotation-lambda-arn arn:aws:lambda:us-east-1:123:function:SecretsManagerRDSMySQLRotationSingleUser
# AWS provides pre-built rotation Lambda functions for:
# - RDS MySQL/PostgreSQL/MariaDB/Oracle/SQL Server
# - DocumentDB
# - Redshift
# - Custom: write your own Lambda for other services
# Application code: always call GetSecretValue, never cache long-termシークレットのローカルキャッシュ
データベースクエリのたびにSecrets Managerを呼び出すと、コストが高くなり、処理も遅くなります。ベストプラクティスは、シークレットを短時間メモリにローカルキャッシュすることです。AWSはJavaおよびPython向けに公式のSecrets Managerキャッシングクライアントを提供しており、設定可能なTTLでシークレットをキャッシュできます。キャッシュの有効期限が切れると、クライアントはSecrets Managerからシークレットを再取得します。アプリケーションが認証エラー(パスワードがローテーションされたことを示します)を受け取った場合は、直ちにキャッシュを更新して再試行します。このパターンにより、Secrets Manager APIに過度な負荷をかけずに、パフォーマンスと最新性を両立できます。
# Python: Secrets Manager caching client
# pip install aws-secretsmanager-caching
from botocore.session import get_session
from aws_secretsmanager_caching import SecretCache, SecretCacheConfig
client = get_session().create_client('secretsmanager')
cache = SecretCache(
config=SecretCacheConfig(secret_refresh_interval=3600), # cache 1 hour
client=client
)
# Returns cached value unless refresh interval expired
secret = cache.get_secret_string('prod/myapp/database')AWS Systems Manager Parameter Store
AWS Systems Manager (SSM) Parameter Storeは、設定データやシークレットを保存する、無料(標準パラメータの場合)の階層型キーバリューストアです。String、StringList、SecureStringのパラメータタイプをサポートしています。SecureStringでは、KMSを使用して値を暗号化します。Secrets Managerとは異なり、Parameter Storeは自動ローテーションをサポートしていません。変更頻度の低い設定値向けに設計されています。標準パラメータは無料で、最大4 KBまで保存できます。アドバンストパラメータは、より大きな値(最大8 KB)、パラメータポリシー(有効期限やローテーションのリマインダー)をサポートし、料金は1パラメータあたり月額0.05ドルです。
# Create Parameter Store parameters
aws ssm put-parameter \
--name '/prod/myapp/db-host' \
--value 'mydb.cluster-abc.us-east-1.rds.amazonaws.com' \
--type String
aws ssm put-parameter \
--name '/prod/myapp/db-password' \
--value 'mysecretpassword' \
--type SecureString \
--key-id alias/my-kms-key
# Retrieve parameter
aws ssm get-parameter \
--name '/prod/myapp/db-password' \
--with-decryption \
--query 'Parameter.Value' --output textParameter Storeの階層構造とIAM
環境やアプリケーションのアーキテクチャを反映した階層型パス構造を使用して、Parameter Storeの値を整理します。これにより、パスのプレフィックスに基づいてパラメータへのアクセスを許可する、きめ細かなIAMポリシーを設定できます。たとえば、Lambda関数に/prod/payment-service/配下のパラメータだけへのアクセスを許可できます。この場合、他のサービスのパラメータにはアクセスできません。設定に最小権限の原則を適用することで、侵害されたサービスが別のサービスのシークレットを読み取ることを防止できます。
# Parameter hierarchy
/prod/payment-service/db-password
/prod/payment-service/stripe-api-key
/prod/order-service/db-password
/prod/order-service/redis-url
/staging/payment-service/db-password
# IAM policy: payment-service Lambda can ONLY read its params
{
'Effect': 'Allow',
'Action': ['ssm:GetParameter', 'ssm:GetParameters', 'ssm:GetParametersByPath'],
'Resource': 'arn:aws:ssm:us-east-1:123:parameter/prod/payment-service/*'
}
# Get all parameters for an app at once
aws ssm get-parameters-by-path \
--path '/prod/payment-service/' \
--with-decryption --recursiveSecrets ManagerとParameter Store:使い分け
要件に応じて2つのサービスを使い分けます。次の場合はSecrets Managerを使用します。自動的なシークレットのローテーションが必要な場合、データベース認証情報を保存する場合、シークレットを複数のAWSアカウント間で共有する必要がある場合、またはコンプライアンス上、文書化されたローテーションポリシーが必要な場合です。次の場合はParameter Storeを使用します。設定値(シークレットではない値)が必要な場合、単純なキーバリューストレージに無料のソリューションを使用したい場合、パスベースのアクセス制御を備えた階層型設定が必要な場合、またはパラメータのバージョン履歴を保存する必要がある場合です。多くのアーキテクチャでは、設定にParameter Store、認証情報にSecrets Managerを使用して、両方を組み合わせます。
# Usage comparison:
# Secrets Manager:
# Cost: $0.40/secret/month
# Rotation: Automatic (RDS, custom Lambda)
# Cross-account: Yes
# Best for: Database passwords, API keys, OAuth tokens
# Parameter Store:
# Cost: Free (standard) / $0.05/month (advanced)
# Rotation: Manual only
# Cross-account: No (use Secrets Manager)
# Best for: Config values, feature flags, non-rotating secretsLambdaとECSとの統合
Lambda関数とECSタスクでは、呼び出しのたびではなく起動時にシークレットを取得する必要があります。Lambdaでは、初期化コード(ハンドラー関数の外側)でシークレットを取得し、グローバル変数にキャッシュします。Lambdaの実行環境は呼び出し間で保持されるため、シークレットの取得は各環境の存続期間中に1回だけ行われます。ECSでは、タスク定義のsecretsフィールドを使用して、Secrets Managerの値またはParameter StoreのSecureStringを環境変数として注入します。ECSがタスクの起動時に値を取得して注入するため、アプリケーションコードを変更する必要はありません。
# ECS task definition: inject secret as environment variable
{
'containerDefinitions': [{
'name': 'api',
'image': 'my-api:latest',
'secrets': [
{
'name': 'DB_PASSWORD',
'valueFrom': 'arn:aws:secretsmanager:us-east-1:123:secret:prod/myapp/database:password::'
},
{
'name': 'API_KEY',
'valueFrom': '/prod/myapp/api-key'
}
]
}]
}
# Application reads DB_PASSWORD from env var
# ECS injects the current secret value at task startEC2 AMI IDのParameter Storeでの管理
Parameter Storeの実用的ですが見落とされがちな用途の1つは、AMI IDやその他のデプロイ参照情報を保存することです。CloudFormationテンプレートにAMI IDをハードコードすると、新しいAMIがリリースされたときに古い値になるため、代わりにParameter Storeの値を参照します。CI/CDパイプラインは、新しいゴールデンAMIが作成されるたびに、Parameter StoreのAMI IDを更新します。CloudFormationはデプロイ時に、Parameter Storeから最新のAMI IDを読み取ります。AWSは、最新のAmazon Linux AMI IDをパブリックなParameter Storeのパスにも公開しており、直接参照できます。
# Get AWS public AMI ID from Parameter Store
aws ssm get-parameter \
--name '/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64' \
--query 'Parameter.Value' --output text
# CloudFormation: reference public AMI parameter
Parameters:
LatestAmiId:
Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
Default: '/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64'
Resources:
MyEC2:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref LatestAmiIdシークレットの監査とコンプライアンス
シークレットを適切に管理するには、誰がいつシークレットにアクセスしたかを把握する必要があります。AWS CloudTrailは、Secrets ManagerとParameter StoreへのすべてのAPI呼び出し(GetSecretValue、PutParameter、GetParameter)を記録します。これにより、コンプライアンスに必要な完全な監査証跡を取得できます。CloudWatch AlarmsをCloudTrailのメトリクスに設定し、通常とは異なるパターンでシークレットにアクセスされたときにアラートを出します。たとえば、本番環境のシークレットに通常とは異なるIAMプリンシパルや、既知の範囲外のIPアドレスからアクセスされた場合は、調査用のアラートを発生させます。
# CloudTrail metric filter: alert on unexpected secret access
aws logs put-metric-filter \
--log-group-name CloudTrail/management-events \
--filter-name 'SecretAccessOutsideHours' \
--filter-pattern '{ $.eventSource = "secretsmanager.amazonaws.com" && $.eventName = "GetSecretValue" && $.userAgent != "lambda.amazonaws.com" }' \
--metric-transformations \
metricName=UnexpectedSecretAccess,metricNamespace=Security,metricValue=1
# Then create CloudWatch alarm on this metric
# Alert fires when non-Lambda principal accesses secretsクロスアカウントでのシークレット共有
マルチアカウントアーキテクチャでは、あるアカウントのアプリケーションが別のアカウントで管理されているシークレットを必要とすることがあります(たとえば、中央のSecurityアカウントですべてのRDSパスワードを管理する場合です)。Secrets Managerのリソースポリシーを使用すると、クロスアカウントアクセスを許可できます。シークレットにリソースベースのポリシーを設定し、利用側アカウントのロールにGetSecretValueの呼び出しを許可します。利用側アカウントのロールには、シークレットのARNに対する呼び出しを許可するIAMポリシーも必要です。また、KMSキーポリシーで、シークレットの暗号化に使用するCMKへの利用側アカウントのアクセスも許可する必要があります。
# Secret resource policy: allow cross-account access
aws secretsmanager put-resource-policy \
--secret-id 'prod/shared/rds-password' \
--resource-policy '{
"Statement": [{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::999999999999:role/AppRole"
},
"Action": "secretsmanager:GetSecretValue",
"Resource": "*"
}]
}'
# KMS key policy must also allow account 999999999999
# IAM policy in 999999999999 must allow GetSecretValue on ARNクイックチェック
このレッスンで学んだAWS Solutions Architect(SAA-C03)の概念について、理解度を確認しましょう。
レッスンのまとめ
このレッスンでは、次のことを学びました。Secrets Managerは、データベース認証情報やAPIキーの自動ローテーションを提供し、ローテーションが必要なシークレットには推奨される選択肢です。Parameter Storeは、パスベースのIAMアクセス制御を備えた、無料の階層型設定ストレージを提供します。ECSとLambdaは、アプリケーションコードを変更せずにシークレットを環境変数として注入できます。CloudTrailは、すべてのシークレットアクセスの監査証跡を提供します。次は、WAF、Shield、Network Firewallについて学びます。
よくある質問
「Secrets ManagerとParameter Store」レッスンは無料ですか?
はい。「Secrets ManagerとParameter Store」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、AWS Solutions Architectコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 AWS Solutions Architectコースには全4レッスンが含まれています。
「Secrets ManagerとParameter Store」で何を学びますか?
Secrets Managerでデータベース認証情報を自動的にローテーションし、秘密ではない設定をParameter Storeに保存して、両方をLambdaとECSに統合します。 ブラウザで直接実行するハンズオンコードでAWS Solutions Architectを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
AWS Solutions Architectを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのAWS Solutions Architectは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「Secrets ManagerとParameter Store」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このAWS Solutions Architectレッスンでコードを書いて実行できますか?
はい。すべてのAWS Solutions Architectレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- KMS、ACM、暗号化パターン
- GuardDuty、Inspector、Macie
- Secrets ManagerとParameter Store
- WAF、Shield、Network Firewall