AWS CDKでRDSのパスワードを自動生成してコード内で利用する

AWS CDKでパスワードを取り扱う場合、パスワードをどこに保存するか悩ましいです。 パラメータストアのSecureStringや、Secrets Managerに保存しておいて参照するというのはよい方法だと思いますが、CDK内でパスワードを自動生成する方法を紹介します。
2021.01.13

AWS CDKでパスワードを取り扱う場合、パスワードをどこに保存するか悩ましいです。

たとえば、RDSのパスワードを作りたい場合、パスワードはどこに保存しましょう?

CDKのソースコードにハードコーディングするのはセキュリティの観点から好ましくありません。

パラメータストアのSecureStringや、Secrets Managerに保存しておいて参照するというのは、よい方法だと思います。

いやしかし、別途パラメータストアを作るのも面倒くさいのです。(個人の感想です)

と、いうわけで、CDK内でパスワードを自動生成する方法 を紹介します。

AWS CDKでRDSのパスワードを自動生成する

結論から言うと、 Credentials クラスの fromGeneratedSecret メソッドを使うことで、簡単にパスワードを生成できます。

具体的なTypeScriptのソースコードをあげると、次のように使用できます。

#!/usr/bin/env node
import "source-map-support/register";
import * as Core from "@aws-cdk/core";
import * as Ec2 from "@aws-cdk/aws-ec2";
import * as Rds from "@aws-cdk/aws-rds";

class TestStack extends Core.Stack {
  constructor(scope: Core.Construct, id: string, props?: Core.StackProps) {
    super(scope, id, props);

    const dbUser: string = 'admin';
    const dbName: string = 'testdb';

    const rdsCredentials: Rds.Credentials =  Rds.Credentials.fromGeneratedSecret(dbUser);

    const vpc: Ec2.Vpc = new Ec2.Vpc(this, "VPC", {
      enableDnsHostnames: true,
      enableDnsSupport: true,
      maxAzs: 2,
      subnetConfiguration: [{
        name: 'PublicSubnet',
        subnetType: Ec2.SubnetType.PUBLIC,
        cidrMask: 24,
        reserved: false,
      },
      ],
    });

    const mysql: Rds.DatabaseCluster = new Rds.DatabaseCluster(this, "Mysql", {
      engine: Rds.DatabaseClusterEngine.AURORA_MYSQL,
      credentials: rdsCredentials,
      defaultDatabaseName: dbName,
      instanceProps: {
        instanceType: Ec2.InstanceType.of(
            Ec2.InstanceClass.BURSTABLE3,
            Ec2.InstanceSize.SMALL,
        ),
        vpcSubnets: {
          subnetType: Ec2.SubnetType.PUBLIC
        },
        vpc: vpc,
      },
      instances: 1,
    });
  }
}

const app = new Core.App();
new TestStack(app, 'TestStack');

実際にこのCDKソースコードをデプロイして、Secrtes Managerを構築すると、ランダムなパスワード文字列が生成されていることがわかります。 パスワードだけではなく、ホスト名やポート番号といったRDSに対する接続情報も保存されます。

利用しているCloudFormationの機能

CloudFormationでは、Secrets Managerを構築する際、ランダムなパスワード文字列を生成できます。

また、 AWS::SecretsManager::SecretTargetAttachment を利用することで、RDSの接続情報をSecrets Managerにリンクできます。

AWS CDKではこのCloudFormationの機能を利用して、RDSのパスワードの自動生成を実現しています。

終わりに

AWS CDKでもSecrets Managerを利用してパスワードを自動生成できることがわかり、サクッと構築できるようになりました。 AWS CDKでRDSのパスワードを取り扱うことがあれば、ぜひお試しください。