AWS CDKでプライベートサブネットに配置した踏み台サーバ(EC2)からRDS(PostgreSQL)接続できる環境をデプロイする方法

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エンドポイントが作成されています。

AWS CDKでプライベートサブネットに配置した踏み台サーバ(EC2)からRDS(PostgreSQL)接続できる環境をデプロイする方法

RDSのセキュリティグループのインバウンドがEC2のセキュリティグループになっています。

<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

<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

シークレットが作成されています。

AWS CDKでプライベートサブネットに配置した踏み台サーバ(EC2)からRDS(PostgreSQL)接続できる環境をデプロイする方法

RDSの情報が格納されています。

AWS CDKでプライベートサブネットに配置した踏み台サーバ(EC2)からRDS(PostgreSQL)接続できる環境をデプロイする方法

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サブネットに置かなくてもいい・・・?

コメント

株式会社CONFRAGE ITソリューション事業部をもっと見る

今すぐ購読し、続きを読んで、すべてのアーカイブにアクセスしましょう。

続きを読む

タイトルとURLをコピーしました