AWS Systems Manager(SSM)パラメータストアからAWS Secrets Managerシークレットを参照できるようになりました

2018.07.28

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AWS Systems Manager パラメータストアを利用すると、パスワード、データベース文字列、ライセンスコードなどのデータをパラメータ値として保存することができます。

セキュアに管理したいデータは、KMS と連携して暗号化されたデータとして保存していました。

AWS KMS で EC2 Systems Managerパラメータストアを暗号化

この度、パラメータストアから直接 AWS Secrets Managerで管理されたシークレットを参照できるようになったため、試してみました。

AWS Systems Manager Parameter Store integrates with AWS Secrets Manager, and adds labeling for easy configuration updates

ポイント

  • SSM パラメータストアはあくまでプロキシー(パス・スルー)として機能
  • パラメータ登録は不要で、 /aws/reference/secretsmanager/secret_ID_in_Secrets_Manager の予約パスで Secrets Manager シークレットを参照
  • SSM の GetParameter/GetParameters API でのみ参照できる。DescribeParameters/GetParametersByPath API では参照できない
  • SSM パラメータストアと Secrets Manager の両方の参照権限が必要
  • パラメータストアのバージョニング・ヒストリー機能は使えない
  • Secrets Manager のバージョニング機能は使える

参照イメージ図

やってみた

以下の手順で動作確認します。

  1. AWS Secrets Manager シークレットの作成
  2. SSM パラメータストアから参照
  3. AWS Secrets Manager のバージョン機能を利用

1. AWS Secrets Manager シークレットの作成

まず、Secret Id prod/App/Mysql で新規シークレットを作成します。

$ aws secretsmanager  create-secret \
  --name prod/App/Mysql \
  --secret-string '{"key":"val"}'
{
    "ARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:prod/App/Mysql-XYZ",
    "Name": "prod/App/Mysql",
    "VersionId": "98a55589-b075-47fb-bae9-df4f289527b9"
}

$ aws secretsmanager get-secret-value --secret-id prod/App/Mysql
{
    "ARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:prod/App/Mysql-XYZ",
    "Name": "prod/App/Mysql",
    "VersionId": "98a55589-b075-47fb-bae9-df4f289527b9",
    "SecretString": "{\"key\":\"val\"}",
    "VersionStages": [
        "AWSCURRENT"
    ],
    "CreatedDate": 1532776189.618
}

2. AWS SSM パラメータストアから参照

Secrets Managerシークレットは SSM の describe-parameters からは参照できません。

$ aws ssm describe-parameters
{
    "Parameters": []
}

SSM の get-parameter で参照します。

/aws/reference/secretsmanager/secret_ID_in_Secrets_Manager の予約パスでアクセスします。

$ aws ssm get-parameter \
  --name /aws/reference/secretsmanager/prod/App/Mysql \
  --with-decryption
{
    "Parameter": {
        "Name": "/aws/reference/secretsmanager/prod/App/Mysql",
        "Type": "SecureString",
        "Value": "{\"key\":\"val\"}",
        "Version": 0,
        "SourceResult": "{\"ARN\":\"arn:aws:secretsmanager:eu-central-1:123456789012:secret:prod/App/Mysql-XYZ\",\"name\":\"prod/App/Mysql\",\"versionId\":\"98a55589-b075-47fb-bae9-df4f289527b9\",\"secretString\":\"{\\\"key\\\":\\\"val\\\"}\",\"versionStages\":[\"AWSCURRENT\"],\"createdDate\":\"Jul 28, 2018 11:09:49 AM\"}",
        "LastModifiedDate": 1532776189.618,
        "ARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:prod/App/Mysql-XYZ"
    }
}

--with-decryption オプションをつけ忘れると、ValidationException エラーが発生します。お気をつけください。

An error occurred (ValidationException) when calling the GetParameter operation: WithDecryption flag must be True for retrieving a Secret Manager secret.

3. AWS Secrets Manager のバージョン機能を利用

Secrets Manager シークレットを更新します。

$ aws secretsmanager update-secret \
  --secret-id prod/App/Mysql \
  --secret-string '{"foo":"bar"}'
{
    "ARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:prod/App/Mysql-XYZ",
    "Name": "prod/App/Mysql",
    "VersionId": "f66c87f8-384b-445b-bd93-5edac5d72705"
}
$ aws secretsmanager list-secret-version-ids --secret-id prod/App/Mysql
{
    "Versions": [
        {
            "VersionId": "98a55589-b075-47fb-bae9-df4f289527b9",
            "VersionStages": [
                "AWSPREVIOUS"
            ],
            "LastAccessedDate": 1532736000.0,
            "CreatedDate": 1532776189.618
        },
        {
            "VersionId": "f66c87f8-384b-445b-bd93-5edac5d72705",
            "VersionStages": [
                "AWSCURRENT"
            ],
            "CreatedDate": 1532776737.955
        }
    ],
    "ARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:prod/App/Mysql-XYZ",
    "Name": "prod/App/Mysql"
}
  • AWSPREVIOUS
  • AWSCURRENT

の2種類の VersionStages があることが確認できます。

この VersionStages を利用して、SSM パラメータストアから参照します。

Version Stage を指定しなければ、更新後の最新の値を取得します。

$ aws ssm get-parameter \
  --name /aws/reference/secretsmanager/prod/App/Mysql \
  --with-decryption | jq -r .Parameter.SourceResult | jq .
{
  "ARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:prod/App/Mysql-XYZ",
  "name": "prod/App/Mysql",
  "versionId": "f66c87f8-384b-445b-bd93-5edac5d72705",
  "secretString": "{\"foo\":\"bar\"}",
  "versionStages": [
    "AWSCURRENT"
  ],
  "createdDate": "Jul 28, 2018 11:18:57 AM"
}

Version Stage を利用するには /aws/reference/secretsmanager/secret_ID_in_Secrets_Manager:VersionStage の予約パスでアクセスします。

Version Stage AWSCURRENT で参照すると、先ほどと同じ最新の値を取得します。

$ aws ssm get-parameter \
  --name /aws/reference/secretsmanager/prod/App/Mysql:AWSCURRENT \
  --with-decryption | jq -r .Parameter.SourceResult | jq .
{
  "ARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:prod/App/Mysql-XYZ",
  "name": "prod/App/Mysql",
  "versionId": "f66c87f8-384b-445b-bd93-5edac5d72705",
  "secretString": "{\"foo\":\"bar\"}",
  "versionStages": [
    "AWSCURRENT"
  ],
  "createdDate": "Jul 28, 2018 11:18:57 AM"
}

Version Stage をAWSPREVIOUS にすると、名前通り、一つ前のバージョンの値を参照します。

$ aws ssm get-parameter \
  --name /aws/reference/secretsmanager/prod/App/Mysql:AWSPREVIOUS \
  --with-decryption | jq -r .Parameter.SourceResult | jq .
{
  "ARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:prod/App/Mysql-XYZ",
  "name": "prod/App/Mysql",
  "versionId": "98a55589-b075-47fb-bae9-df4f289527b9",
  "secretString": "{\"key\":\"val\"}",
  "versionStages": [
    "AWSPREVIOUS"
  ],
  "createdDate": "Jul 28, 2018 11:09:49 AM"
}

Version Stage の参照するバージョンは、シークレットが更新されるたびに変わります。

バージョン ID を直接指定すれば、シークレット更新の影響を受けません。

バージョン ID を利用するには /aws/reference/secretsmanager/secret_ID_in_Secrets_Manager:VersionID の予約パスでアクセスします。

$ aws ssm get-parameter \
  --name /aws/reference/secretsmanager/prod/App/Mysql:98a55589-b075-47fb-bae9-df4f289527b9 \
  --with-decryption | jq -r .Parameter.SourceResult | jq .
{
  "ARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:prod/App/Mysql-XYZ",
  "name": "prod/App/Mysql",
  "versionId": "98a55589-b075-47fb-bae9-df4f289527b9",
  "secretString": "{\"key\":\"val\"}",
  "createdDate": "Jul 28, 2018 11:09:49 AM"
}

まとめ

AWS SSM パラメータストアから AWS Secrets Managerシークレットを参照する方法を紹介しました。

現状の機能では、データの保存先によって、SSM パラメータストアに問い合わせる際のネームスペースが大きく異なります。 どちらに保存されているのか意識せずに、同じ命名規則でデータにアクセスできるようになると、嬉しいのではないかと思いました。

今後は、KMSとパラメータストアの暗号化連携は廃れ、AWS SSM パラメータストアはパラメータ管理のゲートウェイに特化し、セキュアなデータ管理は AWS Secrets Manager が主役になっていくのかもしれません。

そんなことを妄想した新機能でした。

参考