Secrets Managerを使用して、ランダムなパスワードを生成する
Secrets Managerを使用すると、ランダムなパスワードを生成することができます。
https://docs.aws.amazon.com/ja_jp/secretsmanager/latest/userguide/cfn-example_secret.html
本ページでは、上記のページを参考にして、ランダムパスワードを生成します。
また生成したパスワード情報に、AWS CLIおよびLambda関数からアクセスします。
構築する環境
Secrets Managerにシークレットを作成します。
今回はシークレット作成時に、自動的にパスワードを生成します。
生成したパスワードをAWS CLIおよびLambda関数から取得します。
Lambda関数のランタイム環境はPython3.8とします。
CloudFormationテンプレートファイル
上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。
https://github.com/awstut-an-r/awstut-fa/tree/main/126
テンプレートファイルのポイント解説
Secrets Manager
Resources:
Secret:
Type: AWS::SecretsManager::Secret
Properties:
Description: test secret
GenerateSecretString:
ExcludeCharacters: ""
ExcludeLowercase: false
ExcludeNumbers: false
ExcludePunctuation: false
ExcludeUppercase: false
GenerateStringKey: !Ref PasswordKey
IncludeSpace: false
PasswordLength: !Ref PasswordLength
RequireEachIncludedType: true
SecretStringTemplate: !Sub '{"${PasswordKey}": "hogehoge"}'
KmsKeyId: alias/aws/secretsmanager
Name: !Ref Prefix
Code language: YAML (yaml)
GenerateSecretStringプロパティで、生成するパスワードに関する設定を行います。
今回は以下の条件でパスワードを設定します。
- 大文字・小文字・数字・記号(スペース除く)を含む。
- パスワードの長さは64文字とする。
- 「{“password”: “[password]”}」の形式で出力する。
パスワードの形式ですが、GenerateStringKeyおよびSecretStringTemplateプロパティで設定します。
前者がJSONのキーを指定するものですから、後者の該当箇所に統一的に「password」を指定します。
なおJSONの値に関する箇所(「hogehoge」)については、後ほど生成されるパスワード文字列に置き換えられます。
Lambda関数
Resources:
Function:
Type: AWS::Lambda::Function
Properties:
Architectures:
- !Ref Architecture
Environment:
Variables:
SECRET_ARN: !Ref Secret
Code:
ZipFile: |
import boto3
import json
import os
secret_arn = os.environ['SECRET_ARN']
client = boto3.client('secretsmanager')
def lambda_handler(event, context):
response = client.get_secret_value(
SecretId=secret_arn
)
secret_dict = json.loads(response['SecretString'])
return secret_dict['password']
FunctionName: !Sub "${Prefix}-function"
Handler: !Ref Handler
Runtime: !Ref Runtime
Role: !GetAtt FunctionRole.Arn
Code language: YAML (yaml)
Lambda関数で実行するコードをインライン形式で記載します。
詳細につきましては、以下のページをご確認ください。
コードの内容ですが、boto3でSecrets Manager用のクライアントオブジェクトを作成後、get_secret_valueメソッドを実行して、シークレット文字列を取得します。
今回はJSON形式でパスワード情報を保存していますので、json.loadsで辞書型に変換した上で、パスワードにアクセスします。
以下が本関数用のIAMロールです。
Resources:
FunctionRole:
Type: AWS::IAM::Role
DeletionPolicy: Delete
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service:
- lambda.amazonaws.com
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: GetSecretValuePolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- secretsmanager:GetSecretValue
Resource:
- !Ref Secret
Code language: YAML (yaml)
Secrets Managerに保存されているシークレット情報を取得するための権限を付与します。
環境構築
CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。
CloudFormationスタックを作成し、スタック内のリソースを確認する
CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。
各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。
- シークレット名:fa-126
- Lambda関数:fa-126-function
AWSマネージメントコンソールから各種リソースを確認します。
Secrets Managerを確認します。
確かにシークレットが作成されています。
シークレットキー名が「password」、シークレットの値がランダムに生成された文字列です。
このようにSecrets Managerを使用すると、ランダムパスワードを生成することができます。
Lambda関数を確認します。
こちらも正常に作成されています。
動作確認
AWS CLIからSecrets Managerにアクセス
準備が整いましたので、AWS CLIからSecrets Managerに保存されているシークレット情報を取得します。
$ aws secretsmanager get-secret-value --secret-id fa-126
{
"ARN": "arn:aws:secretsmanager:ap-northeast-1:[account-id]:secret:fa-126-b9sPdb",
"Name": "fa-126",
"VersionId": "02433ea8-08cd-412e-8717-26bb08eb8f64",
"SecretString": "{\"password\":\"q8BP.(PO{X2F7D)b&w~@k{\\\"!dAQ8FYsV>iSZR7vaEjz>3r=/CtD5=A+3d_P{0NZ:\"}",
"VersionStages": [
"AWSCURRENT"
],
"CreatedDate": "2023-04-01T07:43:25.603000+00:00"
}
Code language: Bash (bash)
確かにAWS CLIからシークレット情報にアクセスすることができました。
Lambda関数からSecrets Managerにアクセス
Lambda関数を実行して、Secrets Managerに保存されているシークレット情報を取得します。
以下が実行結果です。
パスワード文字列が返ってきました。
このように、AWS CLIやLambda関数からSecrets Managerにアクセスし、シークレット情報を取得することができます。
まとめ
Secrets Managerを使用して、ランダムパスワードを生成しました。
また生成したパスワード情報に、AWS CLIおよびLambda関数からアクセスしました。