この記事を読むとできること
以下構成に示すサービスをAWS CDK(TypeScript)で作成し、Linux(Amazon Linux 2023)とOracle DB(Oracle 19c)の疎通が確認できる
環境
- MacOS Sonoma 14.6.1(23G93)
- zsh 5.9
- aws-cli/2.9.12
- cdk 2.149.0
- node v20.11.1
構成
出典:https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/tutorial-connect-ec2-instance-to-rds-database.html
構築サービスと詳細
- EC2
- OS: Amazon Linux 2023 (以降AL2023)
- インスタンスタイプ:M5.xlarge
- パブリックサブネットに配置
- 任意のIPからのHTTP, HTTPSおよびSSH接続を受け付ける
- RDS
- DBMS: Oracle 19c
- インスタンスタイプ:M5.large
- プライベートサブネットに配置
- EC2からのみ接続を受け付ける(ポート1521)
スタック
oracledb-test-stack.ts
import { CfnOutput, RemovalPolicy, Stack, StackProps, Token } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as rds from 'aws-cdk-lib/aws-rds';
import { Secret } from 'aws-cdk-lib/aws-secretsmanager';
export class OracledbTestStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
//VPC作成
const vpc = new ec2.Vpc(this, 'OracleDBTestVPC', {
ipAddresses: ec2.IpAddresses.cidr('10.0.0.0/16'),
})
// EC2用キーペア作成
const cfnKeyPair = new ec2.CfnKeyPair(this, 'CfnKeyPair', {
keyName: 'oracledb-test-ssh-keypair',
})
cfnKeyPair.applyRemovalPolicy(RemovalPolicy.DESTROY)
// EC2用キーペア取得コマンドアウトプット
new CfnOutput(this, 'GetSSHKeyCommand', {
value: `aws ssm get-parameter --name /ec2/keypair/${cfnKeyPair.getAtt('KeyPairId')} --region ${this.region} --with-decryption --query Parameter.Value --output text`,
})
//EC2 インスタンスの宣言
const webServer1 = new ec2.Instance(this, "OracleDBTestServer1", {
vpc,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.SMALL),
machineImage: new ec2.AmazonLinuxImage({
generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2023,
}),
vpcSubnets: { subnetType: ec2.SubnetType.PUBLIC },
keyName: Token.asString(cfnKeyPair.ref),
});
// インターネット接続およびサーバ設定のためのSSH接続を, 全ての IP アドレスからのアクセスを許可
webServer1.connections.allowFromAnyIpv4(ec2.Port.tcp(80));
webServer1.connections.allowFromAnyIpv4(ec2.Port.tcp(443));
webServer1.connections.allowFromAnyIpv4(ec2.Port.tcp(22));
// EC2 インスタンスアクセス用の IP アドレスを出力
new CfnOutput(this, "OracleDBTestServer1PublicIPAddress", {
value: `http://${webServer1.instancePublicIp}`,
});
// RDS用シークレット生成
const databaseCredentialsSecret = new Secret(this, 'AppDbCredentialsSecret', {
secretName: id + '-rds-credentials',
generateSecretString: {
secretStringTemplate: JSON.stringify({
username: 'admin',
}),
excludePunctuation: true,
includeSpace: false,
passwordLength: 30,
generateStringKey: 'password',
},
});
// RDS のインスタンスを宣言
const dbServer = new rds.DatabaseInstance(this, "OraTestDB", {
vpc,
// DatabaseInstanceEngine クラスを利用してデータベースエンジンを設定
engine: rds.DatabaseInstanceEngine.oracleSe2({ version: rds.OracleEngineVersion.VER_19_0_0_0_2024_04_R1 }),
// RDS DB インスタンスのインスタンスタイプを設定
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.SMALL),
// RDS DB インスタンスのデータベース名を設定
databaseName: "oratest",
// RDS DB インスタンスにライセンスを指定
licenseModel: rds.LicenseModel.LICENSE_INCLUDED,
//シークレットをRDSに割り当て
credentials: rds.Credentials.fromSecret(databaseCredentialsSecret),
});
// WebServer からのアクセスを許可
dbServer.connections.allowDefaultPortFrom(webServer1);
}
}
CDK deploy後(デプロイ方法等詳細はここを参照)、LinuxにSSH接続し以下を行う
Linux設定
# timedatectl status
Local time: Fri 2024-08-16 01:42:53 UTC
Universal time: Fri 2024-08-16 01:42:53 UTC
RTC time: Fri 2024-08-16 01:42:54
Time zone: n/a (UTC, +0000)
NTP enabled: yes
NTP synchronized: yes
RTC in local TZ: no
DST active: n/a
# timedatectl set-timezone Asia/Tokyo
# localectl status
System Locale: LANG=en_US.UTF-8
VC Keymap: n/a
X11 Layout: n/a
# localectl set-locale LANG=ja_JP.utf8
# source /etc/locale.conf
#
DBクライアントツールインストール
ここをの3-9を参照
クライアントツール起動確認
$ sqlplus admin@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=xxxx.rds.amazonaws.com)(PORT=1521)))(CONNECT_DATA=(SID=TEST)))
SQL*Plus: Release 19.0.0.0.0 - Production on Fri Aug 16 13:43:04 2024
Version 19.20.0.0.0
Copyright (c) 1982, 2022, Oracle. All rights reserved.
Enter password:
Connected to:
Oracle Database 19c Standard Edition 2 Release 19.0.0.0.0 - Production
Version 19.23.0.0.0
SQL>
LinuxとOracle DBが疎通できることを確認できた!
注意点(つまったところ)
- EC2へのSSH接続のためのキーペア作成時、最初EC2への受け渡し方法がCDKでどうやるのかわからずマネコンからローカルにキーペア落としてSSH接続しようとしたが
Permission denied.
- EC2側に渡してないから当たり前ですね。。。気付くのに半日溶かした。
- RDSシークレット生成・RDSへの割り当てについて、この記事ではMySQLを使っておりパラメータが色々違ってこれだけでは足りなかった。シークレットをRDSに渡してなくて何時間か溶かした。
- DBインスタンスにライセンス割り当てについて。以下エラー出て
LicenseModel
を指定する必要があることに気づく。
Resource handler returned message: "The LicenseModel parameter is required for configurations with multiple options. (Service: Rds, Status Code: 400, Request ID: b293284e-8017-4546-985f-ee23b484356b)" (RequestToken: 53fbb6fd-62e6-c637-9d94-ce74eaa29ac9, HandlerErrorCode: InvalidRequest)
- RDSシークレット生成時のキーとバリューの値が間違ってた
- usernameの値はOracle DBの場合
admin
にしないといけないらしい。適当な値を入れていた
- usernameの値はOracle DBの場合
- エラー:
Resource handler returned message: "The parameter MasterUserPassword is not a valid password because it is longer than 30 characters.
とのことでpasswordLength
を30文字に指定したらいけた
参考
- https://catalog.workshops.aws/typescript-and-cdk-for-beginner/ja-JP
- https://dev.classmethod.jp/articles/build-ec2-key-pair-with-aws-cdk/
- https://qiita.com/m-chan/items/f56e9300351f68fdda08
- https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk.aws_rds/LicenseModel.html
- https://www.oracle.com/jp/database/technologies/instant-client.html
- https://qiita.com/billtench/items/ac58466b693a01ad6464
- https://qiita.com/moroishisan/items/e987921581896e6884db
- https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_ConnectToOracleInstance.html
最後に
CDKでOracle DB構築してる記事がほとんど見つからず大変だったので、、誰かのお役に立てたら嬉しいです!