はじめに
先日、Lambda上でコンテナイメージを動かしRDSに接続するということをやりました。
このときは手作業でぽちぽちやりましたが、環境設定が面倒くさかったのでCDKで実装してみました。
VPCを作る
まずはVPCを作成します。こんな感じで。ちょっとでも料金節約のために、natGateways
の数は1に設定します。
// VPCの作成 const vpc = new Vpc(this, "MyVPC", { enableDnsHostnames: true, enableDnsSupport: true, maxAzs: 2, natGateways: 1, subnetConfiguration: [ { name: "PublicSubnet", subnetType: SubnetType.PUBLIC, cidrMask: 24, mapPublicIpOnLaunch: true, }, { name: "PrivateSubnet", subnetType: SubnetType.PRIVATE_WITH_EGRESS, cidrMask: 24, }, { name: "DBSubnet", subnetType: SubnetType.PRIVATE_ISOLATED, cidrMask: 24, } ] });
こんな感じでリソースが作られます。
作ってみて思いましたが、name
属性にSubnet
はいらなかったかなと思います。自動生成する名前にもSubnetがつくので冗長でした。
Lambdaを作る
コンテナイメージを作るLambdaを作成します。コンテナイメージはECRにあるので、こんな感じで実装します。
// ECRのリポジトリを指定する const repository = Repository.fromRepositoryName(this, "MyRepository", "my-ruby-app"); // Lambda用のセキュリティグループを作成する const lambdaSecurityGroup = new SecurityGroup(this, "LambdaSecurityGroup", { vpc: vpc, description: "Lambda Security Group", allowAllOutbound: true, }); // ECRにあるコンテナイメージを利用してLambda関数を作成する const lambda = new Function(this, "Lambda", { code: Code.fromEcrImage(repository, { tag: "latest", }), functionName: "my-ruby-app", runtime: Runtime.FROM_IMAGE, handler: Handler.FROM_IMAGE, timeout: cdk.Duration.seconds(30), vpc: vpc, vpcSubnets: { subnetType: SubnetType.PRIVATE_WITH_EGRESS, }, securityGroups: [lambdaSecurityGroup], });
既存のECRはRepository.fromRepositoryName
で取得できるので、それを使い、Function
のcode
属性にてCode.fromEcrImage
にて対象のイメージを指定します。
RDSを作る
RDSを作成します。こんな感じで実装します。
// RDS用のセキュリティグループの作成 const rdsSecurityGroup = new SecurityGroup(this, "RDSSecurityGroup", { vpc: vpc, description: "RDS Security Group", allowAllOutbound: true, }); const dbSubnetGroup = new SubnetGroup(this, "MyDBSubnetGroup", { vpc: vpc, description: "My DB Subnet Group", vpcSubnets: { subnetType: SubnetType.PRIVATE_ISOLATED, onePerAz: true, } }); // RDSインスタンスの作成と設定を行う。今回はPostgreSQLを使用しているため、 // DatabaseInstanceEngine.POSTGRESを指定する。 const rdsInstance = new DatabaseInstance(this, "MyRDSInstance", { engine: DatabaseInstanceEngine.POSTGRES, instanceType: InstanceType.of(InstanceClass.T3, InstanceSize.MICRO), vpc: vpc, databaseName: "mypostgresdb", multiAz: false, subnetGroup: dbSubnetGroup, securityGroups: [rdsSecurityGroup], });
上記のCDK内でRDSのパスワードなどは指定していませんが、これらはSecret Managerに自動的に登録されます。
前回でのプログラムでは環境変数経由でユーザー名やパスワードの取得をしていましたが、Secret Managerから読み取らせる必要があります。実装についてはまた後日。
RDSの作成は、そこそこ時間がかかるのでのんびり待ちます。
セキュリティグループの設定
セキュリティグループの指定は以下の実装で適切なものが実装されます。
rdsInstance.connections.allowDefaultPortFrom(lambda, "Lambda to RDS");
おまけ
これでCDKで前回の環境を実装することができました。今回はテスト用だったので、一度動作確認をしたらcdk destroy
で削除しようとしたのですが、実際の削除には30分ぐらい時間がかかりました。主な要因は、Lambdaが生成するネットワークインターフェースが20分ぐらい使っているという状況のまま消えなかったため。あまり気にせずにのんびり待ちます。