AWS CDKでプライベートサブネットに配置した踏み台サーバ(EC2)からRDS(PostgreSQL)接続できる環境をデプロイする方法
| 項目 | バージョン |
|---|---|
| CDK | 2.27.0 |
プライベートサブネットに配置した踏み台サーバからSSMでRDS(PostgreSQL)に接続できる環境をデプロイしてみました。
SSMを有効にするためにVPCエンドポイント作成、yumなど実行できるようにVPCエンドポイント作成しています。
RDSのインバウンドはポート5432、ソースはEC2のセキュリティグループとなるように設定しています。
RDSの情報はシークレットに格納しています。
import { Stack, StackProps, aws_secretsmanager } from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import { Construct } from 'constructs';
import * as rds from 'aws-cdk-lib/aws-rds';
export class Sample001Stack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const vpc = new ec2.Vpc(this, 'vpc-sample-cdk', {
cidr: '10.0.0.0/16',
natGateways: 0,
maxAzs: 2,
subnetConfiguration: [
{
name: 'public-subnet',
subnetType: ec2.SubnetType.PUBLIC,
cidrMask: 24,
},
{
name: 'isolated-subnet',
subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
cidrMask: 24,
}
]
});
// VPC Endpoint
const endpoints : Array<[string, string]> =
[['com.amazonaws.ap-northeast-1.ssm', 'ssm'],
['com.amazonaws.ap-northeast-1.ec2messages', 'ec2messages'],
['com.amazonaws.ap-northeast-1.ssmmessages', 'ssmmessages']]
for(const data of endpoints) {
new ec2.InterfaceVpcEndpoint(this, data[1], {
vpc,
service: new ec2.InterfaceVpcEndpointService(data[0], 443),
subnets: {
subnetType: ec2.SubnetType.PUBLIC // 明示的に指定
},
privateDnsEnabled: true // プライベートDNS有効化しておく
});
}
const subnetSelection: ec2.SubnetSelection = {
subnetType: ec2.SubnetType.PRIVATE_ISOLATED, onePerAz: true
};
new ec2.GatewayVpcEndpoint(this, 's3gateway', {
vpc,
service: ec2.GatewayVpcEndpointAwsService.S3,
subnets: [subnetSelection]
});
// シークレット
const newSecret = new aws_secretsmanager.Secret(
this,
'DBCredentialsSecret',
{
secretName: 'secret-test',
generateSecretString: {
excludePunctuation: true,
includeSpace: false,
generateStringKey: 'password',
secretStringTemplate: JSON.stringify({
username: 'hoge',
})
}
}
);
// EC2 SecurityGroup
const ec2InstanceSG = new ec2.SecurityGroup(this, 'ec2-instance-sg', {
vpc,
allowAllOutbound: true // アウトバウンドはデフォルトがtrue
});
ec2InstanceSG.addIngressRule( // インバウンド
ec2.Peer.anyIpv4(),
ec2.Port.tcp(5432)
);
// RDS SecurityGroup
const rdsSG = new ec2.SecurityGroup(this, 'rds-sg', {
vpc,
allowAllOutbound: true
});
rdsSG.addIngressRule( // インバウンド
ec2InstanceSG,
ec2.Port.tcp(5432)
);
// 踏み台サーバ
const host = new ec2.BastionHostLinux(this, 'BastionHost', {
vpc,
instanceName: "bastion",
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T4G, ec2.InstanceSize.NANO),
subnetSelection: {
subnetType: ec2.SubnetType.PRIVATE_ISOLATED, // プライベートサブネットにEC2配置
},
securityGroup: ec2InstanceSG
});
// あらかじめインストールしておく
host.instance.addUserData("yum -y update", "yum install -y postgresql jq");
// RDS(postgreSQL) private subnet
const postgres = new rds.DatabaseInstance(this, 'Instance', {
engine: rds.DatabaseInstanceEngine.postgres({
version: rds.PostgresEngineVersion.VER_12, // バージョン12指定
}),
vpc, // vpc変数指定
vpcSubnets: {
subnetType: ec2.SubnetType.PRIVATE_ISOLATED // プライベートサブネットに配置
},
databaseName: 'postgrexxx', // DB名
securityGroups: [rdsSG],
credentials: rds.Credentials.fromSecret(newSecret) // シークレットにRDS情報格納
});
}
}
これでデプロイします。
cdk deploy
VPCエンドポイントが作成されています。
RDSのセキュリティグループのインバウンドがEC2のセキュリティグループになっています。
シークレットが作成されています。
RDSの情報が格納されています。
SSMでコマンドプロンプトから接続してみます。
c:\>aws ssm start-session --target 踏み台サーバのid Starting session with SessionId: takahashi-h5-013e27cf085bde113 sh-4.2$ sudo su [root@ip-10-0-2-81 bin]# yum list installed | grep postgres postgresql.aarch64 9.2.24-6.amzn2 @amzn2-core postgresql-libs.aarch64 9.2.24-6.amzn2 @amzn2-core [root@ip-10-0-2-81 bin]#
あらかじめインストールしたpsqlがインストールされていることが確認できます。
このままpsqlコマンドを実行します。
[root@ip-10-0-2-81 bin]# psql -h sitqgavnxm2bbs.cjvwtdcasc7l.ap-northeast-1.rds.amazonaws.com --dbname=postgrexxx -U hoge --password
Password for user hoge:
psql (9.2.24, server 12.8)
WARNING: psql version 9.2, server version 12.0.
Some psql features might not work.
SSL connection (cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256)
Type "help" for help.
postgrexxx=> \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
------------+----------+----------+-------------+-------------+-----------------------
postgres | hoge | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
postgrexxx | hoge | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
rdsadmin | rdsadmin | UTF8 | en_US.UTF-8 | en_US.UTF-8 | rdsadmin=CTc/rdsadmin
template0 | rdsadmin | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/rdsadmin +
| | | | | rdsadmin=CTc/rdsadmin
template1 | hoge | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/hoge +
| | | | | hoge=CTc/hoge
(5 rows)
postgrexxx=>
接続が確認できました。
参考サイト

Privateサブネットに構築した踏み台経由でDBクライアントツールからRDSに接続してみた | DevelopersIO
もう踏み台をPublicサブネットに置かなくてもいい・・・?

KHI入社して退社。今はCONFRAGEで正社員です。関西で140-170/80~120万から受け付けております^^
得意技はJS(ES6),Java,AWSの大体のリソースです
コメントはやさしくお願いいたします^^
座右の銘は、「狭き門より入れ」「願わくは、我に七難八苦を与えたまえ」です^^

![<h2>AWS CDKでプライベートサブネットに配置した踏み台サーバ(EC2)からRDS(PostgreSQL)接続できる環境をデプロイする方法</h2> |項目|バージョン| |:--|:--| |CDK|2.27.0| プライベートサブネットに配置した踏み台サーバからSSMでRDS(PostgreSQL)に接続できる環境をデプロイしてみました。 SSMを有効にするためにVPCエンドポイント作成、yumなど実行できるようにVPCエンドポイント作成しています。 RDSのインバウンドはポート5432、ソースはEC2のセキュリティグループとなるように設定しています。 RDSの情報はシークレットに格納しています。 <pre>import { Stack, StackProps, aws_secretsmanager } from 'aws-cdk-lib'; import * as ec2 from 'aws-cdk-lib/aws-ec2'; import { Construct } from 'constructs'; import * as rds from 'aws-cdk-lib/aws-rds'; export class Sample001Stack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); const vpc = new ec2.Vpc(this, 'vpc-sample-cdk', { cidr: '10.0.0.0/16', natGateways: 0, maxAzs: 2, subnetConfiguration: [ { name: 'public-subnet', subnetType: ec2.SubnetType.PUBLIC, cidrMask: 24, }, { name: 'isolated-subnet', subnetType: ec2.SubnetType.PRIVATE_ISOLATED, cidrMask: 24, } ] }); // VPC Endpoint const endpoints : Array<[string, string]> = [['com.amazonaws.ap-northeast-1.ssm', 'ssm'], ['com.amazonaws.ap-northeast-1.ec2messages', 'ec2messages'], ['com.amazonaws.ap-northeast-1.ssmmessages', 'ssmmessages']] for(const data of endpoints) { new ec2.InterfaceVpcEndpoint(this, data[1], { vpc, service: new ec2.InterfaceVpcEndpointService(data[0], 443), subnets: { subnetType: ec2.SubnetType.PUBLIC // 明示的に指定 }, privateDnsEnabled: true // プライベートDNS有効化しておく }); } const subnetSelection: ec2.SubnetSelection = { subnetType: ec2.SubnetType.PRIVATE_ISOLATED, onePerAz: true }; new ec2.GatewayVpcEndpoint(this, 's3gateway', { vpc, service: ec2.GatewayVpcEndpointAwsService.S3, subnets: [subnetSelection] }); // シークレット const newSecret = new aws_secretsmanager.Secret( this, 'DBCredentialsSecret', { secretName: 'secret-test', generateSecretString: { excludePunctuation: true, includeSpace: false, generateStringKey: 'password', secretStringTemplate: JSON.stringify({ username: 'hoge', }) } } ); // create a security group for the EC2 instance const ec2InstanceSG = new ec2.SecurityGroup(this, 'ec2-instance-sg', { vpc, allowAllOutbound: true // アウトバウンドはデフォルトがtrue }); ec2InstanceSG.addIngressRule( // インバウンド ec2.Peer.anyIpv4(), ec2.Port.tcp(5432) ); // RDS SecurityGroup const rdsSG = new ec2.SecurityGroup(this, 'rds-sg', { vpc, allowAllOutbound: true }); rdsSG.addIngressRule( // インバウンド ec2InstanceSG, ec2.Port.tcp(5432) ); // 踏み台サーバ const host = new ec2.BastionHostLinux(this, 'BastionHost', { vpc, instanceName: "bastion", instanceType: ec2.InstanceType.of(ec2.InstanceClass.T4G, ec2.InstanceSize.NANO), subnetSelection: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED, // プライベートサブネットにEC2配置 }, securityGroup: ec2InstanceSG }); // あらかじめインストールしておく host.instance.addUserData("yum -y update", "yum install -y postgresql jq"); // RDS(postgreSQL) private subnet const postgres = new rds.DatabaseInstance(this, 'Instance', { engine: rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_12, // バージョン12指定 }), vpc, // vpc変数指定 vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED // プライベートサブネットに配置 }, databaseName: 'postgrexxx', // DB名 securityGroups: [rdsSG], credentials: rds.Credentials.fromSecret(newSecret) // シークレットにRDS情報格納 }); } }</pre> これでデプロイします。 <pre>cdk deploy</pre> VPCエンドポイントが作成されています。 <a href="https://confrage.jp/wp-content/uploads/2022/06/b-2.png"><img class="alignnone size-medium wp-image-18499" src="https://confrage.jp/wp-content/uploads/2022/06/b-2-300x68.png" alt="AWS CDKでプライベートサブネットに配置した踏み台サーバ(EC2)からRDS(PostgreSQL)接続できる環境をデプロイする方法" width="300" height="68" /></a> RDSのセキュリティグループのインバウンドがEC2のセキュリティグループになっています。 <h3>ローカルマシン(Windows)からポートフォワーディングして、A5M2でRDS接続する</h3> d](https://i0.wp.com/confrage.jp/wp-content/uploads/2022/06/a-22-300x140.png?resize=300%2C140&ssl=1)
![<h2>AWS CDKでプライベートサブネットに配置した踏み台サーバ(EC2)からRDS(PostgreSQL)接続できる環境をデプロイする方法</h2> |項目|バージョン| |:--|:--| |CDK|2.27.0| プライベートサブネットに配置した踏み台サーバからSSMでRDS(PostgreSQL)に接続できる環境をデプロイしてみました。 SSMを有効にするためにVPCエンドポイント作成、yumなど実行できるようにVPCエンドポイント作成しています。 RDSのインバウンドはポート5432、ソースはEC2のセキュリティグループとなるように設定しています。 RDSの情報はシークレットに格納しています。 <pre>import { Stack, StackProps, aws_secretsmanager } from 'aws-cdk-lib'; import * as ec2 from 'aws-cdk-lib/aws-ec2'; import { Construct } from 'constructs'; import * as rds from 'aws-cdk-lib/aws-rds'; export class Sample001Stack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); const vpc = new ec2.Vpc(this, 'vpc-sample-cdk', { cidr: '10.0.0.0/16', natGateways: 0, maxAzs: 2, subnetConfiguration: [ { name: 'public-subnet', subnetType: ec2.SubnetType.PUBLIC, cidrMask: 24, }, { name: 'isolated-subnet', subnetType: ec2.SubnetType.PRIVATE_ISOLATED, cidrMask: 24, } ] }); // VPC Endpoint const endpoints : Array<[string, string]> = [['com.amazonaws.ap-northeast-1.ssm', 'ssm'], ['com.amazonaws.ap-northeast-1.ec2messages', 'ec2messages'], ['com.amazonaws.ap-northeast-1.ssmmessages', 'ssmmessages']] for(const data of endpoints) { new ec2.InterfaceVpcEndpoint(this, data[1], { vpc, service: new ec2.InterfaceVpcEndpointService(data[0], 443), subnets: { subnetType: ec2.SubnetType.PUBLIC // 明示的に指定 }, privateDnsEnabled: true // プライベートDNS有効化しておく }); } const subnetSelection: ec2.SubnetSelection = { subnetType: ec2.SubnetType.PRIVATE_ISOLATED, onePerAz: true }; new ec2.GatewayVpcEndpoint(this, 's3gateway', { vpc, service: ec2.GatewayVpcEndpointAwsService.S3, subnets: [subnetSelection] }); // シークレット const newSecret = new aws_secretsmanager.Secret( this, 'DBCredentialsSecret', { secretName: 'secret-test', generateSecretString: { excludePunctuation: true, includeSpace: false, generateStringKey: 'password', secretStringTemplate: JSON.stringify({ username: 'hoge', }) } } ); // create a security group for the EC2 instance const ec2InstanceSG = new ec2.SecurityGroup(this, 'ec2-instance-sg', { vpc, allowAllOutbound: true // アウトバウンドはデフォルトがtrue }); ec2InstanceSG.addIngressRule( // インバウンド ec2.Peer.anyIpv4(), ec2.Port.tcp(5432) ); // RDS SecurityGroup const rdsSG = new ec2.SecurityGroup(this, 'rds-sg', { vpc, allowAllOutbound: true }); rdsSG.addIngressRule( // インバウンド ec2InstanceSG, ec2.Port.tcp(5432) ); // 踏み台サーバ const host = new ec2.BastionHostLinux(this, 'BastionHost', { vpc, instanceName: "bastion", instanceType: ec2.InstanceType.of(ec2.InstanceClass.T4G, ec2.InstanceSize.NANO), subnetSelection: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED, // プライベートサブネットにEC2配置 }, securityGroup: ec2InstanceSG }); // あらかじめインストールしておく host.instance.addUserData("yum -y update", "yum install -y postgresql jq"); // RDS(postgreSQL) private subnet const postgres = new rds.DatabaseInstance(this, 'Instance', { engine: rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_12, // バージョン12指定 }), vpc, // vpc変数指定 vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED // プライベートサブネットに配置 }, databaseName: 'postgrexxx', // DB名 securityGroups: [rdsSG], credentials: rds.Credentials.fromSecret(newSecret) // シークレットにRDS情報格納 }); } }</pre> これでデプロイします。 <pre>cdk deploy</pre> VPCエンドポイントが作成されています。 <a href="https://confrage.jp/wp-content/uploads/2022/06/b-2.png"><img class="alignnone size-medium wp-image-18499" src="https://confrage.jp/wp-content/uploads/2022/06/b-2-300x68.png" alt="AWS CDKでプライベートサブネットに配置した踏み台サーバ(EC2)からRDS(PostgreSQL)接続できる環境をデプロイする方法" width="300" height="68" /></a> RDSのセキュリティグループのインバウンドがEC2のセキュリティグループになっています。 <h3>ローカルマシン(Windows)からポートフォワーディングして、A5M2でRDS接続する</h3> d](https://i0.wp.com/confrage.jp/wp-content/uploads/2022/06/b-3-300x80.png?resize=300%2C80&ssl=1)




コメント