CloudFormationでパスワードを自動生成してテンプレート内で利用する
CloudFormationでパスワードを取り扱う場合、パスワードをどこに保存するか悩ましいです。
たとえば、CloudFormationでIAM Userを作りたい場合、IAM Userのパスワードはどこに保存しましょう?
CloudFormationテンプレート内にハードコーディングするのは、セキュリティの観点から好ましくありません。
パラメータストアのSecureStringに保存しておいて参照するというのは、よい方法だと思います。
いやしかし、別途パラメータストアを作るのが面倒くさいのです。(個人の感想です)
もっとサクッと作りたい!と、いうことで、CloudFormationでパスワードを自動生成する方法を紹介します。
CloudFormationでパスワードを自動生成する
結論から言うと、Secrets Managerの機能を使うことで、簡単にパスワードを生成することができます。
Secrets Managerでは、CloudFormationでシークレットを構築する際、ランダムな文字列を生成する機能が備わっています。
パスワードの生成ルールはGenerateSecretStringプロパティで細かく指定することができます。
具体的にCloudFormationテンプレートをあげると、次のように使用できます。
--- AWSTemplateFormatVersion: '2010-09-09' Resources: SampleSecret: Type: AWS::SecretsManager::Secret Properties: GenerateSecretString: GenerateStringKey: password PasswordLength: 32 SecretStringTemplate: '{}' Outputs: GetSecretValueByCLI: Value: !Sub |+ aws secretsmanager get-secret-value --secret-id ${SampleSecret} --region ${AWS::Region} --query SecretString
実際にCloudFormationでシークレットを構築すると、ランダムな文字列が生成されていることがわかります。
ついでに、AWS CLIでSecrets Managerの値を取得するコマンドを出力するよう仕込んでいるので、こっちも確認します。
実際にコマンドを実行してみます。
$ aws secretsmanager get-secret-value \ --secret-id arn:aws:secretsmanager:us-west-2:123456789012:secret:SampleSecret-nQQ16yTl7F79-yYVzIl \ --region us-west-2 \ --query SecretString "{\"password\":\"xxxxxxxxxxxxxxxxxxxxxxxxx\"}"
CLIでもランダムな文字列が生成されていることが確認できます。
Secrets Managerの値を取得してCloudFormationで利用する
CloudFormationでは、パラメータストアとSecrets Managerに格納された値を動的に参照する機能がサポートされています。
この機能を利用することで、CloudFormationテンプレート内でSecrets Managerの値を利用できます。
具体的にCloudFormationテンプレートをあげると、次のように利用できます。
--- AWSTemplateFormatVersion: '2010-09-09' Resources: SampleSecret: Type: AWS::SecretsManager::Secret Properties: GenerateSecretString: GenerateStringKey: password PasswordLength: 32 SecretStringTemplate: '{}' SampleUser: Type: AWS::IAM::User Properties: Path: "/" LoginProfile: Password: !Sub "{{resolve:secretsmanager:${SampleSecret}:SecretString:password::}}" Outputs: GetSecretValueByCLI: Value: !Sub |+ aws secretsmanager get-secret-value --secret-id ${SampleSecret} --region ${AWS::Region} --query SecretString IAMUserName: Value: !Ref SampleUser
実際にCloudFormationでIAM Userを構築すると、パスワードでコンソールログイン可能なユーザーができていることがわかります。
パスワードにSecrets Managerの値が使われていることを確かめる
IAM Userが構築できたので、本当にSecrets Managerの値がパスワードとして設定されているのか確かめてみます。
ユーザー名とパスワードを入力して、マネジメントコンソールにログインします。パスワードは、Secrets Managerの値からコピーしてきます。
問題なくログインできて、パスワードが期待通り設定できていることがわかりました。
終わりに
CloudFormationでパスワードの扱いに迷っていましたが、Secrets Managerで自動生成できることがわかり、サクッと作ることができるようになりました。 CloudFormationでパスワードを取り扱うことがあれば、ぜひお試しください。