AWS Secrets Manager ローテーションのトラブルシューティング - AWS Secrets Manager

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

AWS Secrets Manager ローテーションのトラブルシューティング

多くのサービスでは、Secrets Manager は、Lambda 関数を使用してシークレットをローテーションします。詳細については、「Lambda 関数によるローテーション」を参照してください。Lambda ローテーション関数は、シークレットの対象となるデータベースまたはサービス、および Secrets Manager とやり取りします。ローテーションが期待どおりに機能しない場合は、まず CloudWatch ログを確認する必要があります。

注記

一部のサービスは、ユーザーのためにシークレットを管理できます (自動ローテーションの管理など)。詳細については、「AWS Secrets Manager シークレットのマネージドローテーション」を参照してください。

Lambda 関数の CloudWatch ログを表示するには
  1. で Secrets Manager コンソールを開きますhttps://console.aws.amazon.com/secretsmanager/

  2. シークレットを選択し、詳細ページの [Rotation configuration] (ローテーション設定) で、Lambda ローテーション関数を選択します。Lambda コンソールが開きます。

  3. Monitor タブで、Logs を選択し、View logs in CloudWatchを選択します。

    CloudWatch コンソールが開き、関数のログが表示されます。

「環境変数に認証情報が見つかりました」の後にアクティビティがない

「環境変数に認証情報が見つかりました」の後にアクティビティがなく、タスクの所要時間が長い (例: デフォルトの Lambda タイムアウトは 30000 ms) 場合は、Secrets Manager エンドポイントへのアクセス時に Lambda 関数がタイムアウトしている可能性があります。

ローテーション用の Lambda 関数は、Secrets Manager のエンドポイントにアクセスできる必要があります。Lambda 関数がインターネットにアクセスできる場合は、パブリックなエンドポイントを使用できます。エンドポイントを見つけるには、「AWS Secrets Manager エンドポイント」を参照してください。

Lambda 関数VPCがインターネットアクセスのない で実行されている場合は、 内で Secrets Manager サービスのプライベートエンドポイントを設定することをお勧めしますVPC。その後、 VPCは、パブリックリージョンエンドポイント宛てのリクエストを傍受し、プライベートエンドポイントにリダイレクトできます。詳細については、「VPC エンドポイント (AWS PrivateLink)」を参照してください。

または、Lambda 関数が Secrets Manager パブリックエンドポイントにアクセスできるようにするには、NATゲートウェイまたはインターネットゲートウェイを に追加します。これによりVPC、 からのトラフィックVPCがパブリックエンドポイントに到達できるようになります。これにより、ゲートウェイの IP アドレスがパブリックインターネットから攻撃される可能性があるため、 VPCのリスクが高まります。

createSecret「」の後にアクティビティがない

以下は、 の後にローテーションが停止する原因となる問題ですcreateSecret。

VPC ネットワークは、送受信HTTPSトラフィックを許可ACLsしません。

詳細については、「Amazon VPCユーザーガイド」の「ネットワークを使用してサブネットへのトラフィックを制御するACLs」を参照してください。

Lambda 関数のタイムアウト設定が短すぎてタスクを実行できません。

詳細については、「AWS Lambda デベロッパーガイド」の「Lambda 関数オプションの設定」を参照してください。

Secrets Manager VPCエンドポイントは、割り当てられたセキュリティグループへの進入VPCCIDRs時に を許可しません。

詳細については、「Amazon VPCユーザーガイド」の「セキュリティグループを使用してリソースへのトラフィックを制御する」を参照してください。

Secrets Manager VPCエンドポイントポリシーは、Lambda がVPCエンドポイントを使用することを許可しません。

詳細については、「エンドポイントの使用 AWS Secrets Manager VPC 」を参照してください。

シークレットは交代ユーザーローテーションを使用し、スーパーユーザーシークレットは Amazon によって管理されRDS、Lambda 関数は RDS にアクセスできませんAPI。

スーパーユーザーシークレットが他の AWS サービスによって管理されている交代ユーザーローテーションでは、Lambda ローテーション関数がサービスエンドポイントを呼び出してデータベース接続情報を取得できる必要があります。データベースサービスのVPCエンドポイントを設定することをお勧めします。詳細については、以下を参照してください。

エラー:「 へのアクセスKMSは許可されていません」

が表示された場合ClientError: An error occurred (AccessDeniedException) when calling the GetSecretValue operation: Access to KMS is not allowed、ローテーション関数には、シークレットの暗号化に使用された KMSキーを使用してシークレットを復号するアクセス許可がありません。暗号化コンテキストを特定のシークレットに制限する条件が、アクセス許可ポリシーに含まれている可能性があります。必要なアクセス許可の詳細については、「カスタマーマネージドキーのポリシーステートメント」を参照してください。

エラー:「キーがシークレットにありませんJSON」

Lambda ローテーション関数では、シークレット値が特定のJSON構造にある必要があります。このエラーが表示される場合、 には、ローテーション関数がアクセスしようとしたキーが欠落しているJSON可能性があります。シークレットの各タイプのJSON構造については、「」を参照してくださいAWS Secrets Manager シークレットの JSON 構造

エラー:setSecret「: データベースにログインできません」

このエラーを引き起こす可能性のある問題は次のとおりです。

ローテーション関数はデータベースにアクセスできません。

タスクの所要時間が長い (例: 5000 ミリ秒以上) 場合、Lambda ローテーション関数はネットワーク経由でデータベースにアクセスできない可能性があります。

データベースまたはサービスが の Amazon EC2インスタンスで実行されている場合はVPC、同じ で実行するように Lambda 関数を設定することをお勧めしますVPC。こうすることで、ローテーション関数はサービスと直接通信できるようになります。詳細については、VPC「アクセスの設定」を参照してください。

Lambda 関数からデータベースまたはサービスへのアクセスを可能にするには、ローテーション用の Lambda 関数にアタッチされたセキュリティグループによって、そのデータベースまたはサービスに対するアウトバウンド接続が許可されている必要があります。同時に、データベースまたはサービスにアタッチされているセキュリティグループでは、ローテーション用 Lambda 関数からのインバウンド接続を許可する必要もあります。

シークレットの認証情報が正しくありません。

タスクの所要時間が短い場合、Lambda ローテーション関数がシークレット内の認証情報を使用しても認証できない可能性があります。 AWS CLI コマンド を使用して、シークレットの AWSCURRENTおよび AWSPREVIOUSバージョンの情報を使用して手動でログインし、認証情報を確認しますget-secret-value

データベースは scram-sha-256 を使用してパスワードを暗号化します。

データベースが Aurora PostgreSQL バージョン 13 以降で、 を使用してパスワードscram-sha-256を暗号化しているが、ローテーション関数が をサポートしていないlibpqバージョン 9 以前を使用している場合scram-sha-256、ローテーション関数はデータベースに接続できません。

scram-sha-256 暗号化を使用するデータベースユーザーを判別するには
  • ブログ「Postgre 13 の認証」の「 以外のSCRAMパスワードを持つユーザーのチェック」を参照してください。 SCRAM RDS SQL

ローテーション関数が使用する libpq のバージョンを判別するには
  1. Linux ベースのコンピュータの Lambda コンソールで、ローテーション関数に移動し、デプロイバンドルをダウンロードします。zip ファイルを作業ディレクトリに解凍します。

  2. コマンドラインの作業ディレクトリで、以下を実行します。

    readelf -a libpq.so.5 | grep RUNPATH

  3. 文字列 PostgreSQL-9.4.x、または 10 未満のメジャーバージョンが表示されている場合、ローテーション関数は scram-sha-256 をサポートしていません。

    • scram-sha-256 をサポートしていないローテーション関数の出力を次に示します。

      0x000000000000001d (RUNPATH) Library runpath: [/local/p4clients/pkgbuild-a1b2c/workspace/build/PostgreSQL/PostgreSQL-9.4.x_client_only.123456.0/AL2_x86_64/DEV.STD.PTHREAD/build/private/tmp/brazil-path/build.libfarm/lib:/local/p4clients/pkgbuild-a1b2c/workspace/src/PostgreSQL/build/private/install/lib]

    • scram-sha-256 をサポートしているローテーション関数の出力を次に示します。

      0x000000000000001d (RUNPATH) Library runpath: [/local/p4clients/pkgbuild-a1b2c/workspace/build/PostgreSQL/PostgreSQL-10.x_client_only.123456.0/AL2_x86_64/DEV.STD.PTHREAD/build/private/tmp/brazil-path/build.libfarm/lib:/local/p4clients/pkgbuild-a1b2c/workspace/src/PostgreSQL/build/private/install/lib]

注記

2021 年 12 月 30 日より前に自動シークレットローテーションを設定した場合、ローテーション関数は をサポートしていない以前のバージョンの libpqをバンドルしましたscram-sha-256scram-sha-256 をサポートするには、ローテーション関数を再作成する必要があります。

データベースには SSL/TLS アクセスが必要です。

データベースに SSL/TLS 接続が必要で、ローテーション関数が暗号化されていない接続を使用している場合、ローテーション関数はデータベースに接続できません。Amazon RDS (Oracle と Db2 を除く) および Amazon DocumentDB のローテーション関数は、使用可能な場合、Secure Socket Layer (SSL) または Transport Layer Security (TLS) を自動的に使用してデータベースに接続します。使用できない場合は、暗号化されていない接続が使用されます。

注記

2021 年 12 月 20 日より前に自動シークレットローテーションを設定した場合、ローテーション関数は SSL/TLS. To support connections that use SSL/TLSをサポートしていない以前のテンプレートに基づいている可能性がありますAmazon RDS、Amazon Aurora、Amazon DocumentDB、Amazon Redshift のシークレットで自動ローテーションを設定にする

ローテーション関数がいつ作成されたかを特定するには
  1. Secrets Manager コンソール でhttps://console.aws.amazon.com/secretsmanager/、シークレットを開きます。ローテーション設定セクションの Lambda ローテーション関数の下に、Lambda 関数 ARNが表示されます。たとえば、 ですarn:aws:lambda:aws-region:123456789012:function:SecretsManagerMyRotationFunction 。この例ではARN、 の末尾から関数名をコピーします SecretsManagerMyRotationFunction

  2. AWS Lambda コンソールの 関数 https://console.aws.amazon.com/lambda/で、検索ボックスに Lambda 関数名を貼り付け、Enter を選択してから、Lambda 関数を選択します。

  3. 関数の詳細ページで、[Configuration] (設定) タブの [Tags] (タグ) で、aws:cloudformation:stack-name キーの横にある値をコピーします。

  4. AWS CloudFormation コンソールhttps://console.aws.amazon.com/クラウドフォーメーションの スタックで、検索ボックスにキー値を貼り付け、Enter を選択します。

  5. スタックのリストがフィルタリングされ、Lambda ローテーション関数を作成したスタックだけが表示されます。[Created date] (作成日) 列に、スタックが作成された日付が表示されます。これが、Lambda ローテーション関数が作成された日付です。

エラー: 「モジュール 'lambda_function' をインポートできません」

古い (Python 3.7 から新しいバージョンの Python に自動的にアップグレードされた) Lambda 関数を実行している場合に、このエラーが表示されることがあります。このエラーを解決するには、Lambda 関数のバージョンを Python 3.7 に戻してから、既存のローテーション関数を Python 3.7 から 3.9 にアップグレードする を実行します。詳細については、「AWS re:Post」の「Secrets Manager Lambda 関数のローテーションが「pg モジュールが見つかりません」というエラーで失敗したのはなぜですか?」 を参照してください。

既存のローテーション関数を Python 3.7 から 3.9 にアップグレードする

2022 年 11 月よりも前に作成された一部のローテーション関数では、Python 3.7 が使用されていました。for AWS SDKPython は、2023 年 12 月に Python 3.7 のサポートを停止しました。詳細については、「 および ツールの Python サポートポリシーの更新 AWS SDKs」を参照してください。Python 3.9 を使用する新しいローテーション関数に切り替えるには、既存のローテーション関数にランタイムプロパティを追加するか、またはローテーション関数を再作成します。

Python 3.7 を使用する Lambda ローテーション関数を見つけるには
  1. にサインイン AWS Management Console し、 で AWS Lambda コンソールを開きますhttps://console.aws.amazon.com/lambda/

  2. [関数] のリストで、SecretsManager をフィルタリングします。

  3. フィルタリングされた関数のリストの [ランタイム] で、Python 3.7 を見つけます。

オプション 1: を使用してローテーション関数を再作成する AWS CloudFormation

Secrets Manager コンソールを使用してローテーションを有効にすると、Secrets Manager は AWS CloudFormation を使用して Lambda ローテーション関数を含む必要なリソースを作成します。コンソールを使用してローテーションを有効にした場合、または AWS CloudFormation スタックを使用してローテーション関数を作成した場合は、同じ AWS CloudFormation スタックを使用してローテーション関数を新しい名前で再作成できます。新しい関数は、より新しいバージョンの Python を使用します。

ローテーション関数を作成した AWS CloudFormation スタックを検索するには
  • Lambda 関数の詳細ページの [設定] タブで、[タグ] を選択します。aws:cloudformation:stack-id ARNの横にある を表示します。

    次の例に示すようにARN、スタック名は に埋め込まれます。

    • ARN: arn:aws:cloudformation:us-west-2:408736277230:stack/SecretsManagerRDSMySQLRotationSingleUser5c2-SecretRotationScheduleHostedRotationLambda-3CUDHZMDMBO8/79fc9050-2eef-11ed-80f0-021fb13c0537

    • スタック名: SecretsManagerRDSMySQLRotationSingleUser5c2-SecretRotationScheduleHostedRotationLambda

ローテーション関数を再作成するには (AWS CloudFormation)
  1. で AWS CloudFormation、名前でスタックを検索し、更新を選択します。

    ルートスタックの更新を推奨するダイアログボックスが表示された場合は、[ルートスタックに移動] を選択し、[更新] を選択します。

  2. [スタックの更新] ページで、[テンプレートの準備] から [Application Composer で編集] を選択し、次に [Application Composer でテンプレートを編集] から [Application Composer で編集] を選択します。

  3. Application Composer で、次の操作を行います。

    1. テンプレートコードの でSecretRotationScheduleHostedRotationLambda、 の値を"functionName": "SecretsManagerTestRotationRDS"新しい関数名に置き換えます。たとえば、 ではJSON、 "functionName": "SecretsManagerTestRotationRDSupdated"

    2. [テンプレートの更新] を選択します。

    3. [ AWS CloudFormationに進む] ダイアログボックスで、[確認して AWS CloudFormationに進む] を選択します。

  4. AWS CloudFormation スタックワークフローを続行し、送信を選択します。

オプション 2: を使用して既存のローテーション関数のランタイムを更新する AWS CloudFormation

Secrets Manager コンソールを使用してローテーションを有効にすると、Secrets Manager は AWS CloudFormation を使用して Lambda ローテーション関数を含む必要なリソースを作成します。コンソールを使用してローテーションを有効にした場合、または AWS CloudFormation スタックを使用してローテーション関数を作成した場合は、同じ AWS CloudFormation スタックを使用してローテーション関数のランタイムを更新できます。

ローテーション関数を作成した AWS CloudFormation スタックを検索するには
  • Lambda 関数の詳細ページの [設定] タブで、[タグ] を選択します。aws:cloudformation:stack-id ARNの横にある を表示します。

    次の例に示すようにARN、スタック名は に埋め込まれます。

    • ARN: arn:aws:cloudformation:us-west-2:408736277230:stack/SecretsManagerRDSMySQLRotationSingleUser5c2-SecretRotationScheduleHostedRotationLambda-3CUDHZMDMBO8/79fc9050-2eef-11ed-80f0-021fb13c0537

    • スタック名: SecretsManagerRDSMySQLRotationSingleUser5c2-SecretRotationScheduleHostedRotationLambda

ローテーション関数のランタイムを更新するには (AWS CloudFormation)
  1. で AWS CloudFormation、名前でスタックを検索し、更新を選択します。

    ルートスタックの更新を推奨するダイアログボックスが表示された場合は、[ルートスタックに移動] を選択し、[更新] を選択します。

  2. [スタックの更新] ページで、[テンプレートの準備] から [Application Composer で編集] を選択し、次に [Application Composer でテンプレートを編集] から [Application Composer で編集] を選択します。

  3. Application Composer で、次の操作を行います。

    1. テンプレート でJSON、 の SecretRotationScheduleHostedRotationLambda、 の Properties、 の Parametersで、 を追加します"runtime": "python3.9"

    2. [テンプレートの更新] を選択します。

    3. [ AWS CloudFormationに進む] ダイアログボックスで、[確認して AWS CloudFormationに進む] を選択します。

  4. AWS CloudFormation スタックワークフローを続行し、送信を選択します。

オプション 3: AWS CDK ユーザーの場合は、CDKライブラリをアップグレードする

バージョン v2.94.0 AWS CDK より前の を使用してシークレットのローテーションを設定した場合は、v2.94.0 以降にアップグレードすることで Lambda 関数を更新できます。詳細については、「AWS Cloud Development Kit (AWS CDK) v2 デベロッパーガイド」を参照してください。

AWS Lambda シークレットのローテーションがPutSecretValue失敗しました

Secrets Manager で引き受けたロールまたはクロスアカウントローテーションを使用していて、「シークレットVERSION_ID の保留中のシークレットバージョンSECRET_ARN が Lambda LAMBDA_ARN. によって作成されなかったAWSPENDING」というメッセージ RotationFailed AWS CloudTrail が表示された場合は、 RotationTokenパラメータを使用するように Lambda 関数を更新する必要があります。

Lambda ローテーション関数を更新して含める RotationToken

  1. Lambda 関数コードをダウンロードする

    • Lambda コンソールを開く

    • ナビゲーションペインで、関数を選択します。

    • 関数名の Lambda シークレットローテーション関数を選択する

    • ダウンロードで、関数コード .zip、file、 Both のいずれかを選択します。 AWS SAM

    • OK を選択して、ローカルマシンに関数を保存します。

  2. Lambda_handler を編集する

    クロスアカウントローテーションの create_secret ステップに rotation_token パラメータを含めます。

    def lambda_handler(event, context): """Secrets Manager Rotation Template This is a template for creating an AWS Secrets Manager rotation lambda Args: event (dict): Lambda dictionary of event parameters. These keys must include the following: - SecretId: The secret ARN or identifier - ClientRequestToken: The ClientRequestToken of the secret version - Step: The rotation step (one of createSecret, setSecret, testSecret, or finishSecret) - RotationToken: the rotation token to put as parameter for PutSecretValue call context (LambdaContext): The Lambda runtime information Raises: ResourceNotFoundException: If the secret with the specified arn and stage does not exist ValueError: If the secret is not properly configured for rotation KeyError: If the event parameters do not contain the expected keys """ arn = event['SecretId'] token = event['ClientRequestToken'] step = event['Step'] # Add the rotation token rotation_token = event['RotationToken'] # Setup the client service_client = boto3.client('secretsmanager', endpoint_url=os.environ['SECRETS_MANAGER_ENDPOINT']) # Make sure the version is staged correctly metadata = service_client.describe_secret(SecretId=arn) if not metadata['RotationEnabled']: logger.error("Secret %s is not enabled for rotation" % arn) raise ValueError("Secret %s is not enabled for rotation" % arn) versions = metadata['VersionIdsToStages'] if token not in versions: logger.error("Secret version %s has no stage for rotation of secret %s." % (token, arn)) raise ValueError("Secret version %s has no stage for rotation of secret %s." % (token, arn)) if "AWSCURRENT" in versions[token]: logger.info("Secret version %s already set as AWSCURRENT for secret %s." % (token, arn)) return elif "AWSPENDING" not in versions[token]: logger.error("Secret version %s not set as AWSPENDING for rotation of secret %s." % (token, arn)) raise ValueError("Secret version %s not set as AWSPENDING for rotation of secret %s." % (token, arn)) # Use rotation_token if step == "createSecret": create_secret(service_client, arn, token, rotation_token) elif step == "setSecret": set_secret(service_client, arn, token) elif step == "testSecret": test_secret(service_client, arn, token) elif step == "finishSecret": finish_secret(service_client, arn, token) else: raise ValueError("Invalid step parameter")
  3. create_secret コードの編集

    rotation_token パラメータを受け入れて使用するように create_secret関数を改訂します。

    # Add rotation_token to the function def create_secret(service_client, arn, token, rotation_token): """Create the secret This method first checks for the existence of a secret for the passed in token. If one does not exist, it will generate a new secret and put it with the passed in token. Args: service_client (client): The secrets manager service client arn (string): The secret ARN or other identifier token (string): The ClientRequestToken associated with the secret version rotation_token (string): the rotation token to put as parameter for PutSecretValue call Raises: ResourceNotFoundException: If the secret with the specified arn and stage does not exist """ # Make sure the current secret exists service_client.get_secret_value(SecretId=arn, VersionStage="AWSCURRENT") # Now try to get the secret version, if that fails, put a new secret try: service_client.get_secret_value(SecretId=arn, VersionId=token, VersionStage="AWSPENDING") logger.info("createSecret: Successfully retrieved secret for %s." % arn) except service_client.exceptions.ResourceNotFoundException: # Get exclude characters from environment variable exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else '/@"\'\\' # Generate a random password passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters) # Put the secret, using rotation_token service_client.put_secret_value(SecretId=arn, ClientRequestToken=token, SecretString=passwd['RandomPassword'], VersionStages=['AWSPENDING'], RotationToken=rotation_token) logger.info("createSecret: Successfully put secret for ARN %s and version %s." % (arn, token))
  4. 更新された Lambda 関数コードをアップロードする

    Lambda 関数コードを更新したら、アップロードしてシークレットをローテーションします